Skip to content

Instantly share code, notes, and snippets.

@frizbee
Last active July 3, 2024 14:35
Show Gist options
  • Save frizbee/9ceaaaca36498bc332ec35d10dd7b902 to your computer and use it in GitHub Desktop.
Save frizbee/9ceaaaca36498bc332ec35d10dd7b902 to your computer and use it in GitHub Desktop.
Script that will create the folder and file structure for your Erlang application and populate it with the example files

Create simple Erlang project structure

Folder structure

my_server/
├── _build/
├── config/
│   └── sys.config
├── deps/
├── ebin/
├── include/
├── priv/
├── src/
│   ├── my_server_app.erl
│   ├── my_server_sup.erl
│   └── my_server.erl
├── test/
│   └── my_server_SUITE.erl
├── rebar.config
└── README.md

Description of Each Folder and File

  • _build/: Contains build artifacts. This directory is managed by rebar3 and you typically don’t need to modify it.
  • config/: Contains configuration files for your application.
    • sys.config: The main configuration file for your application.
  • deps/: Contains dependencies for your application. This directory is also managed by rebar3.
  • ebin/: Contains compiled BEAM files. This directory is managed by rebar3.
  • include/: Contains header files (e.g., .hrl files) used in your application.
  • priv/: Contains private files used by your application, such as static assets or database files.
  • src/: Contains the source code for your application.
    • my_server_app.erl: The application module.
    • my_server_sup.erl: The supervisor module.
    • my_server.erl: The server module.
  • test/: Contains test files for your application.
    • my_server_SUITE.erl: An example EUnit test suite for your application.
  • rebar.config: The configuration file for rebar3, defining dependencies and build instructions.
  • README.md: A markdown file providing an overview of your application.

Script

# create_erlang_project.sh
#!/bin/bash

# Define project name
PROJECT_NAME="my_server"

# Create project directories
mkdir -p $PROJECT_NAME/{_build,config,deps,ebin,include,priv,src,test}

# Create config/sys.config
cat <<EOL > $PROJECT_NAME/config/sys.config
[
    {my_server, []}
].
EOL

# Create src/my_server_app.erl
cat <<EOL > $PROJECT_NAME/src/my_server_app.erl
-module(my_server_app).
-behaviour(application).

%% Application callbacks
-export([start/2, stop/1]).

start(_StartType, _StartArgs) ->
    my_server_sup:start_link().

stop(_State) ->
    ok.
EOL

# Create src/my_server_sup.erl
cat <<EOL > $PROJECT_NAME/src/my_server_sup.erl
-module(my_server_sup).
-behaviour(supervisor).

-export([start_link/0, init/1]).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init([]) ->
    %% Define child processes to be supervised
    Children = [
        {my_server, {my_server, start_link, []}, permanent, 5000, worker, [my_server]}
    ],
    {ok, {{one_for_one, 1, 5}, Children}}.
EOL

# Create src/my_server.erl
cat <<EOL > $PROJECT_NAME/src/my_server.erl
-module(my_server).
-behaviour(gen_server).

%% API
-export([start_link/0, stop/0, call/1, cast/1]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

%% API functions
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

stop() ->
    gen_server:cast(?MODULE, stop).

call(Request) ->
    gen_server:call(?MODULE, Request).

cast(Request) ->
    gen_server:cast(?MODULE, Request).

%% gen_server callbacks
init([]) ->
    {ok, #{}}.

handle_call(Request, _From, State) ->
    %% Handle synchronous calls
    Reply = process_request(Request),
    {reply, Reply, State}.

handle_cast(stop, State) ->
    {stop, normal, State};
handle_cast(_Msg, State) ->
    %% Handle asynchronous messages
    {noreply, State}.

handle_info(_Info, State) ->
    %% Handle all other messages
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

%% Helper function to process requests
process_request(Request) ->
    %% Implement your request processing logic here
    {ok, Request}.
EOL

# Create test/my_server_SUITE.erl
cat <<EOL > $PROJECT_NAME/test/my_server_SUITE.erl
-module(my_server_SUITE).
-include_lib("eunit/include/eunit.hrl").

%% Tests
simple_test() ->
    ?assertEqual({ok, test}, my_server:process_request(test)).
EOL

# Create rebar.config
cat <<EOL > $PROJECT_NAME/rebar.config
{erl_opts, [debug_info]}.

{deps, []}.

{relx, [
    {release, {my_server, "0.1.0"},
     [
      my_server
     ]},
    {dev_mode, true},
    {include_erts, false}
]}.
EOL

# Create README.md
cat <<EOL > $PROJECT_NAME/README.md
# My Server

This is a basic Erlang server application.

## Getting Started

To compile the project:

\`\`\`bash
rebar3 compile
\`\`\`

To start the Erlang shell with the application:

\`\`\`bash
erl -pa _build/default/lib/*/ebin
\`\`\`

To start the application:

\`\`\`erlang
application:start(my_server).
\`\`\`
EOL

# Output message
echo "Erlang project structure for '$PROJECT_NAME' created successfully."

To use this script:

  1. Copy the script into a file, for example, create_erlang_project.sh.

  2. Make the script executable:

    chmod +x create_erlang_project.sh
  3. Run the script:

    ./create_erlang_project.sh

This script will create the specified directory structure and populate it with the provided example files.

Example structure and files generated with AI ✨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment