How do I install meck with my Erlang project?

865 views Asked by At

I created my first Erlang project. It's a simple secret code game. I'm trying to avoid OTP at all costs because it seems REALLY confusing and my mentor thought it wasn't necessary to use it this go- around.

I have three folders: ebin src test

I use a makefile to compile all code and run tests.

Life is good until tonight...

To mock my input (and outputs?) for the game, it was recommended that I use Meck but I am having a really hard time integrating it into my project.

I tried manually installing. I did a git clone of Meck. I can "cd" into the eBin folder in the Meck directory and compile, run all the system tests, and perform a basic command "meck:new(dog)". Awesome!

Now I need to get Meck working with my project...I read this line in the Github Meck readme: "If you want to install your own built version of meck add the ebin directory to your Erlang code path or move the meck folder into your release folder and make sure that folder is in your ERL_LIBS environment variable."

But I can't figure out how to add the ebin directory to my Erland code path, I don't have a release folder (this is a rebar thing I think?) and I don't know how to add a ERL_LIBS environment variable. So I'm stuck.

Here's what I've tried: To add the ebin directory to my code path, I did this in my makefile (I have the meck directory sitting on my Desktop right now):

    erlc -pa ~/Desktop/meck/ebin/

And I added the ERL_LIBS to my .bash_profile like so:

    export ERL_LIBS='~/Desktop/meck/ebin/'

I also tried installing Agner and get errors when I install:

    ERROR: compile failed while processing /private/tmp/agner.0r04Vm: {'EXIT',
        {undef,
            [{rebar,get_jobs,
                 [{config,"/private/tmp/agner.0r04Vm",
                      [{require_otp_vsn,"R14|R15"},
                       {lib_dirs,["deps"]},
                       {escript_incl_apps,
                           [getopt,gproc,rebar,plists,gen_fsm2,jsx]},
                       {erl_opts,[{i,"deps"}]},
                       {plugins,[agner_rebar_plugin]},
                       local]}],
                 []},
             {rebar_base_compiler,run,4,
                 [{file,"src/rebar_base_compiler.erl"},{line,49}]},
             {rebar_erlc_compiler,doterl_compile,3,
                 [{file,"src/rebar_erlc_compiler.erl"},{line,157}]},
             {rebar_core,run_modules,4,[{file,"src/rebar_core.erl"},{line,420}]},
             {rebar_core,execute,4,[{file,"src/rebar_core.erl"},{line,354}]},
             {rebar_core,process_dir0,6,[{file,"src/rebar_core.erl"},{line,217}]},
             {rebar_core,process_dir,4,[{file,"src/rebar_core.erl"},{line,128}]},
             {rebar_core,process_commands,2,
                 [{file,"src/rebar_core.erl"},{line,83}]}]}}
    make: *** [compile] Error 1

Can anyone help? I feel like there were several option for me to try and none of them are working.

Update:

Here's what my make file looks like after reading @d11wtq's solution:

    .SUFFIXES: .erl .beam .yrl        

    .erl.beam:
        erlc -W $<        

    .yrl.erl:
        erlc -W $<        

    ERL = erl -boot start_clean        

    MODS = console_io feedback mastermind secret_code meck        

    all:    compile path run_test        

    compile:
        erlc -o ebin/ src/*.erl
        erlc -o ebin/ test/*.erl        

    path:
        erlc -pa ebin/
        -env ERL_LIBS deps/        

    run_test:
        erl -noshell -pa ebin \
        -eval 'eunit:test("ebin").' \
        -eval 'mastermind:start_game().' \
        -s init stop        

    clean:
        rm -rf ebin/*.beam
        rm -rf erl_crash.dump

Final Update:

Based on the tips, here is my final makefile that now works.

    all:    compile run_test run_game

    compile:
        erlc -o ebin/ src/*.erl
        erlc -o ebin/ test/*.erl

    run_test:
        erl -pa ebin \
        -env ERL_LIBS deps/ \
        -eval 'eunit:test("ebin").' \
        -s init stop

    run_game:
        erl -pa ebin \
        -env ERL_LIBS deps/ \
        -eval "mastermind:start_game()." \
        -s init stop

    clean:
        rm -rf ebin/*.beam
        rm -rf erl_crash.dump
2

There are 2 answers

3
d11wtq On BEST ANSWER

Just put meck (and all its subdirectories) in a subdirectory of your project; say, deps/.

So now you'll have:

src/
ebin/
deps/
  meck/
    src/
    ebin/

Because libs in Erlang are packaged up the same way as applications, there is the environment variable ERL_LIBS that will tell the VM where to find libraries your app uses. Meck is one of those libs, and it is at the path "deps/".

erl -pa ebin/ -env ERL_LIBS deps/

Now meck should be visible to the Erlang VM.

1
legoscia On

Quoting meck's README:

Meck is best used via rebar. Add the following dependency t your rebar.config in your project root:

{deps, [
    {meck, ".*", {git, "https://github.com/eproxus/meck.git"}}
]}.

And then run rebar get-deps and rebar compile.