Mochiweb: Include and compile other libraries - makefile

My app uses Mochiweb.
I have noticed that Mochiweb files reside in the myapp/deps/mochiweb directory and rebar compiles them when I run make in the myapp directory.
I wanted to add ibrowse to write a few tests which make http requests to my app. So I cloned ibrowse from github to myapp/deps/ibrowse directory.
But it seems that Erlang does not know where to get the .beam files for ibrowse and therefore all my tests that use the ibrowse module fail:
myapp
ebin %%compiled tests reside here, tests which use ibrowse fail (badarg)
deps
mochiweb
ibrowse
ebin %%compiled ibrowse module resides here
src
tests
How can I make my Mochiweb-based app use other Erlang/OTP external libraries?
Should I edit rebar.config or Makefile for that? Or maybe I should edit an _app.src file?
Edit: Maybe I should edit the list of directories in the myapp_sup.erl file? (myapp_deps:local_path(["priv", "www"])
P.S. How does my app know where all the mochiweb.beam files reside? (for example, the generic myapp_web.erl uses a call to mochiweb_http module, but there is no mochiweb_http.beam in the myapp/ebin directory).

Dependencies in rebar are added via the rebar.config file:
%% What dependencies we have, dependencies can be of 3 forms, an application
%% name as an atom, eg. mochiweb, a name and a version (from the .app file), or
%% an application name, a version and the SCM details on how to fetch it (SCM
%% type, location and revision). Rebar currently supports git, hg, bzr and svn.
{deps, [application_name,
{application_name, "1.0.*"},
{application_name, "1.0.*",
{git, "git://github.com/basho/rebar.git", {branch, "master"}}}]}.
Then, you probably want to look at Erlang releases and release handling with rebar. Think to a release as a way of grouping applications.
http://www.erlang.org/doc/design_principles/release_handling.html
http://learnyousomeerlang.com/release-is-the-word
https://github.com/basho/rebar/wiki/Release-handling

Adding the following code to myapp_web.erl solved my problem:
ibrowse:start()
By default Mochiweb is started in the same function:
mochiweb_http:start()...
I am not sure if it the proper way to do this, but it works.

Related

How to use an alternate go.mod file for local development?

Currently I am working on an API which uses Serverless Framework with Go.
I'm using the Serverless-offline plugin for local testing.
This API depends on a few other repositories (which I also maintain), which I import using the go.mod file.
However I am having a hard time refining my developer workflow.
Currently, if I want to make changes in a repository which this API depends upon, I have to alter the projects go.mod to include replace directives for the purpose of testing, but then I'm having to manually change it back for deployment to production.
Basically I'm looking for a way to include replace directives, which only get applied during local development. How has everyone else dealt with this problem?
Bonus question: Is there any way to run Serverless offline in docker? I'm finding that serverless-offline running on the bare metal is causing inconsistencies between different developers environments.
You can run go commands with an alternate go.mod file with the -modfile option:
From Build commands:
The -modfile=file.mod flag instructs the go command to read (and
possibly write) an alternate file instead of go.mod in the module root
directory. The file’s name must end with .mod. A file named go.mod
must still be present in order to determine the module root directory,
but it is not accessed. When -modfile is specified, an alternate
go.sum file is also used: its path is derived from the -modfile flag
by trimming the .mod extension and appending .sum.
Create a local.go.mod file with the necessary replace directive for development and build, for example, with:
go build -modfile=local.go.mod ./...

how to make `mvn package` aware that it has already built the target

In a makefile, I can easily do something like
${target}: ${sources}
mvn package
Where I have ${target} the generated jar file, and ${sources} all the java files and the pom.xml. With this makefile, the target will not be be rebuilt unless one of the sources is changed since the last build of the target. The result is
$> make target/demo-0.8.0-SNAPSHOT-jar-with-dependencies.jar
make: 'target/demo-0.8.0-SNAPSHOT-jar-with-dependencies.jar' is up to date.
But just mvn package will always run the maven-assembly-plugin even though none of the source files has changed.
Question:
Is there a way to make mvn package be aware of the source files, similar to how make knows this so it'll just say "no need, it's already built."
Whether or not something makes sense is maybe up to the use case and the developer.
In a system where integration is far more complicated than passing unit tests the only way to gain confidence is by deploying into a test Kubernetes environment.
Anyway thanks for answering my question that the maven packaging plugin is unable to handle this dependency tracking.

Buildr - Exclude source files when compiling

Is there a way to exclude certain packages or source files when compiling in buildr? There isn't an exclude on the compile task as it looks in the src directory. We are building for multiple environments and for one of the environments we need to exclude a few source files otherwise it won't compile.
Any ideas?
thanks
compile.sources only contains the source directories and there is no way to tell buildr to exclude subdirectories directly from that. However, before compilation, buildr lists all the files in these directories to pass them on to the compiler (you can see this with buildr --trace compile). You could monkey-patch Buildr::Compiler::Base::files_from_sources to exclude some stuff, but that seems way too intrusive.
I would turn the problem upside down: instead of putting all the code in a single source directory, put environment-specific stuff in its own directory like so:
src/main/java
src/other-env/java
Most if not all IDEs support multiple source directories, so that should not be a problem.
Then define buildr projects for each of the environments by adding the appropriate source directory to the compilation path using compile.from (same for resources). If src/main/java compiles on its own, you could also separate that into its own project and have the others depend on it, thus avoiding having to recompile it over and over.
To make the build script simpler, think about making the various environments proper sub-projects.

How to use leiningen to develop using local jars?

I realize that this question is pretty much the exact question found here. However, seeing as that question is 1.5 years old (or so), I would like to revisit it. How does one add local dependencies using leiningen? Surely this capability must exist by now?
Create a private Maven Repository, and then, add the following to your project.clj
:repositories {"local" ~(str (.toURI (java.io.File. "your_local_repository")))}
If the jars are based on your own projects, you can use lein install to put them into your local .m2, or use the checkout-dependencies feature.
You can also use the extra-classpaths feature, etc.
I found that the easiest (albeit somewhat hacky) solution is to do the following:
For an existing project that you're using as a dependency:
In your local project that has the dependency you want to modify, ensure you run lein deps
Clone the repo of this dependency so you can modify it locally (obv. make sure you're using the same tag as the version you specify in your project.clj file)
Run lein uberjar in this dependency dir (where the relevant project.clj file lives)
Copy the generated standalone jar in target/ to the exact path/file of your local maven files... (something like: ~/.m2/repository/project/.../file.jar); Ensure that you backup the original jar file so you can restore it later on if that is desirable
For development of your own project:
Within the project or plugin you're developing, simply run lein install
Find out where your local maven repo is (see above for an example path)
Enter dependency information in your test project like you would for any other leiningen project
Again, this is a quick hack and perhaps not the way you'd go about doing serious local development, but I found it easy enough for what I wanted. Check out lein help tutorial for much more info

Maven, how to trigger install of parent from child module? (command prompt)

This is more of aesthetic question since I want to make my life easier. I have maven project structure like this:
foo-project (parent)
foo-business (child-module)
foo-dao (child-module)
foo-app (child-module)
I run my maven commands from command prompt, I want to trigger install of all project from maven module, meaning if I am in module dir I want to trigger install from there and not to navigate to parent pom dir.
Thank you
If you really want to make your life easier, separate your parent project (i.e. the one where you put common settings for your other projects) from your aggregator project (i.e. the one that has your other projects as modules). At that point the sole purpose of your aggregator project will be to let you build all your projects together, so run your builds from there.
With Maven, doing as Maven likes is always going to make your life easier than any other option.
Consider using Buildozer - an utility that I wrote some time ago in order to cleverly perform builds of given module, but building all "outdated" dependencies first.
It can be downloaded here: http://buildbox.sourceforge.net/buildozer/
It requires that you first register your modules (= create mapping between dir and GAV for each module), like this:
zer reg /home/pkozelka/my-common-modules /home/pkozelka/my-projects
or
cd /home/pkozelka/other-modules
zer reg .
then you go into any module and perform the build:
zcd my-server # this is 'chdir by artifactId', with bashcompletion on Linux
zer . # compiles all (transitive) dependency modules and then this one

Resources