In our Java applications we typically use the maven conventions (docs, src/java, test, etc.). For Perl we follow similar conventions only using a top level 'lib' which is easy to add to Perl's #INC.
I'm about to embark on creating a service written in Erlang, what's a good source layout for Erlang applications?
The Erlang recommended standard directory structure can be found here.
In addition you may need a few more directories depending on your project, common ones are (credit to Vance Shipley):
lib: OS driver libraries
bin: OS executables
c_src: C language source files (e.g. for drivers)
java_src: Java language source files
examples: Example code
mibs: SNMP MIBs
Other projects such as Mochiweb have their own structures, Mochiweb even have a script to create it all for you. Other projects such as Erlware overlay on the standard structure.
Another critical directory is the priv directory. Here you can store files that can easily be found from your applications.
code:priv_dir(Name) -> string() | {error, bad_name}
where Name is the name of your application.
Erlware is changing that - in a couple of days the Erlware structures will be exactly that of Erlang OTP. Actually the structure of app packages is already exactly that of OTP and as specified above. What will change is that Erlware installed directory structure will fit exactly over an existing Erlang/OTP install (of course one is not needed to install Erlware though) Erlware can now be used to add packages to an existing install very easily.
Cheers,
Martin
Related
Suppose I have a CLI application with subcommands and arguments (like application foo --bar baz). How can I package it for distribution without requiring user to install Erlang?
I know there's mix escript Mix task, but it builds a binary that requires Erlang to be installed, also Mix reference states that escripts should be used only for development purposes.
mix release, however, produces redundant shell scripts that I don't want to see in dist.
So, is there a way to make a standalone distributable of an Elixir CLI application?
P. S. This is actually my first experience with Elixir (and the whole Erlang ecosystem)
Elixir applications can be packaged as Erlang releases, see also here. These can include Erlang VM. Elixir since 1.9 supports building releases without extra tooling, using included mix task mix release - please check the documentation for greasy details: https://hexdocs.pm/mix/Mix.Tasks.Release.html
You might benefit from a quick look at this blog post for inspiration and conceptual overview, noticing that for simple CLI app it is much simpler: https://www.cogini.com/blog/best-practices-for-deploying-elixir-apps/
Bakeware generates a single executable file.
They have added a CLI app example here.
I am building a Spring project with Bower to manage client libraries. I am interested to know what is the best practices way to expose those libraries (or any sort of client libraries managed by a package manager) to the web client.
I can see that I can use a .bowerrc file to choose where to install the files. I could have them install into a static resources folder, one where each of the files installed would be accessible to http requests. It struck me as a potential code smell, however, to expose all the files, instead of the ones that I specifically need.
I could copy individual files into such a directory, or adopt an automated solution to do the same. If this is not considered necessary, however, I would prefer not to expend the effort.
Which of these, or any other solution (if any) is considered the clear best practices way to do this and why? (Please provide a reference to support your answer.) To be clear, I am not interested in individual opinion, but rather if there is a known, clearly preferred, solution.
After looking at what a lot of projects and tutorial suggest, it seems that the clear way to do this is the following:
Use a framework like Grunt or Gulp to separate "built" code from source code. Built code, in this case refers to code that is copied, minified, and/or concatenated into a separate folder. The Grunt or Gulp configuration file should include all application code, as well as select source files from bower components. The running application should reference only these "built" files. The directory of "built" client-side code should be served statically by Spring.
We are getting familiar with Erlang/OTP and Riak (Core, KV, Pipe, and so on) trying to build an open-source distributed application in turn. Our project is going to have a bunch of dependencies : tools like erlang_js, protobuffs, etc., but also services that we need to have running, such as Riak KV.
In Python/Ruby/Node.js, if modules are placed in a standard subdirectory relative to your project's, you can reference them, and later package them in releases. You can fire up a shell in the project's directory, play with your modules, do tests and so on, all just easily if good practices are followed.
What are the best practices for organizing a development environment in Erlang/OTP, with all dependencies reachable (and easily updatable to newest version), shell access to running nodes, testing, making releases, and so forth?
Check out rebar3: used for packaging, templating and managing releases of Erlang/OTP applications. You will find there an entire tutorial on how to use it.
Check out this tutorial on OTP first, before you can switch to this one which shows you releases and how they are handled in Erlang. Use this entire book as reference as you develop your project and because the author is still progressively adding more advanced stuff that you may need.
You may also want to keep reading about Erlang Applications and then do check out these quick links below:
Erlang Packaging, Process OneOTP Packaging Video by Chicago Boss GuysErlang Dependency ManagementRichard Jones Advice and examples on Packaging Erlang Projects with DependenciesMaven Tool and how it is used in packaging Erlang Projects
Most importantly, take rebar very seriously. It is very important in managing Erlang applications which have dependencies. You can keep posting your questions here on Stack Overflow for any assistance as you progress.
Before I forget, do check out a lot of stuff from the Riak Community.
Also, its important to check out the system documentation on creating target systems and also how to use Reltool to handle releases. The good thing with erlang is that it has several options of how to do something, as long as its easy to maintain your application in that way. With target systems, you will learn how to embed the Erlang VM, how to run Erlang applications on Solaris, VxWorks, and creating Erlang applications as Services on Windows NT using erlsrv.
Normally, we make sure that as an operating system is booting a Server, our application starts with it. Solaris so far has more customizations than any other OS as regards embedding Erlang/OTP VM. You can always communicate with (an) embedded Erlang VM(s) using Escript where by the escript creates a an erlang node which is allowed to connect to the embedded VM (so they have to share same cookie) and the embedded VM must have allowed the temporarily created Node to connect by executing net_kernel:allow(List_of_nodes)
Make sure to call this method to make your embedded VM allow connections only from an known strictly specified number of Nodes.
What is the idiomatic way of packaging erlang modules/app? For example, in Java there two options: jar or war depending on deployment target.
In Erlang, modules are grouped into applications. Applications are grouped into releases. How does this works? Like this.
Luckily, Rebar exists to do most of it. Rebar is probably the most commonly used tool to manage applications and releases.
I want to use some libs in my application, like https://github.com/Panmind/erlang-ruby-marshal. That repo holds an src dir, but has no .app file (because it's not an application), so I can't use get-deps.
I tried another approach, adding a libs dir in sub_dirs and added the repo as a git submodule, but rebar won't compile any of its files. I guess that rebar only compiles otp applications, but not just .erl files that aren't tied to an application.
How do you manage those kind of dependencies? I would like to avoid copying the files to my app dir, because I don't think they belong there, and I kind of like the git submodule approach, that allows me to keep track of the lib version I am using.
Recent rebar supports raw option for dependencies. When this option is specific, rebar does not require the dependency to have a standard Erlang/OTP layout which assumes the presence of either "src/dependency_name.app.src" or "ebin/dependency_name.app" files (see more details here).
For example:
{deps, [
{erlang_ruby_marshal, "",
{git, "https://github.com/Panmind/erlang-ruby-marshal", {branch, master}},
[raw]}
]}.
Note that rebar will now be able to fetch it, but it still won't compile it. As other commenters pointed out, there's no reason why this dependency should not have an .app file. I would fork the repository and add the .app file to it.
This article goes through the bigger process of creating applications and releases with rebar.
More specifically, I think this option in rebar.config might be what you're looking for. The only way I've found so far is to have one entry for each application:
{sub_dirs, ["libs/app1",
"libs/app2",
...]}.
This requires a bit more manual work. Unfortunately rebar is very structured around the concept of one app only, and would need some better support for caring for a repository with a bunch of equally worth applications instead of a single application.
If you are using Linux, you can add the required modules as hard links, into the src directory of your application.
This is far from optimal but I have yet to find a better way to do this.
Ask the Agner guys to add it to their package management system. In the process they will create a fork and convert to make the project rebar compatible. Also, the original maintainer will quite possibly integrate the changes.