aboutsummaryrefslogtreecommitdiffstats
path: root/src/rcl_cmd_args.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rcl_cmd_args.erl')
-rw-r--r--src/rcl_cmd_args.erl125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/rcl_cmd_args.erl b/src/rcl_cmd_args.erl
new file mode 100644
index 0000000..454e762
--- /dev/null
+++ b/src/rcl_cmd_args.erl
@@ -0,0 +1,125 @@
+%% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
+%%% Copyright 2012 Erlware, LLC. All Rights Reserved.
+%%%
+%%% This file is provided to you under the Apache License,
+%%% Version 2.0 (the "License"); you may not use this file
+%%% except in compliance with the License. You may obtain
+%%% a copy of the License at
+%%%
+%%% http://www.apache.org/licenses/LICENSE-2.0
+%%%
+%%% Unless required by applicable law or agreed to in writing,
+%%% software distributed under the License is distributed on an
+%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%%% KIND, either express or implied. See the License for the
+%%% specific language governing permissions and limitations
+%%% under the License.
+%%%---------------------------------------------------------------------------
+%%% @author Eric Merritt <[email protected]>
+%%% @copyright (C) 2012 Erlware, LLC.
+%%%
+%%% @doc Trivial utility file to help handle common tasks
+-module(rcl_cmd_args).
+
+-export([args2state/1]).
+
+%%============================================================================
+%% types
+%%============================================================================
+
+
+%%============================================================================
+%% API
+%%============================================================================
+-spec args2state({error, Reason::term()} | {[getopt:option()], [string()]}) ->
+ {error, Reason::term()} |
+ {ok, {rcl_state:t(), [string()]}}.
+args2state(Error={error, _}) ->
+ Error;
+args2state({ok, {Opts, Targets}}) ->
+ RelName = proplists:get_value(relname, Opts, undefined),
+ RelVsn = proplists:get_value(relvsn, Opts, undefined),
+ case create_log(Opts,
+ [{relname, RelName},
+ {relvsn, RelVsn}]) of
+ Error = {error, _} ->
+ Error;
+ {ok, CommandLineConfig} ->
+ {ok, {rcl_state:new(CommandLineConfig), Targets}}
+ end.
+
+%%%===================================================================
+%%% Internal Functions
+%%%===================================================================
+
+-spec create_log([getopt:option()], rcl_state:cmd_args()) ->
+ {ok, rcl_state:cmd_args()} | {error, Reason::term()}.
+create_log(Opts, Acc) ->
+ LogLevel = proplists:get_value(log_level, Opts, 0),
+ if
+ LogLevel >= 0, LogLevel =< 2 ->
+ create_goals(Opts, [{log, rcl_log:new(LogLevel)} | Acc]);
+ true ->
+ {error, {invalid_log_level, LogLevel}}
+ end.
+
+-spec create_goals([getopt:option()], rcl_state:cmd_args()) ->
+ {ok, rcl_state:cmd_args()} | {error, Reason::term()}.
+create_goals(Opts, Acc) ->
+ case convert_goals(proplists:get_all_values(goals, Opts), []) of
+ Error={error, {failed_to_parse, _Spec}} ->
+ Error;
+ {ok, Specs} ->
+ create_output_dir(Opts, [{goals, Specs} | Acc])
+ end.
+
+-spec convert_goals([string()], [depsolver:constraint()]) ->
+ {error,{failed_to_parse, string()}} |
+ {ok,[depsolver:constraint()]}.
+convert_goals([], Specs) ->
+ %% Reverse the specs because order matters to depsolver
+ {ok, lists:reverse(Specs)};
+convert_goals([RawSpec | Rest], Acc) ->
+ case rcl_goal:parse(RawSpec) of
+ {ok, Spec} ->
+ convert_goals(Rest, [Spec | Acc]);
+ {fail, _} ->
+ {error, {failed_to_parse, RawSpec}}
+ end.
+-spec create_output_dir([getopt:option()], rcl_state:cmd_args()) ->
+ {ok, rcl_state:cmd_args()} | {error, Reason::term()}.
+create_output_dir(Opts, Acc) ->
+ OutputDir = proplists:get_value(output_dir, Opts, "./relcool_output"),
+ case filelib:is_dir(OutputDir) of
+ false ->
+ case rcl_util:mkdir_p(OutputDir) of
+ ok ->
+ create_lib_dirs(Opts, [{output_dir, OutputDir} | Acc]);
+ {error, _} ->
+ {error, {unable_to_create_output_dir, OutputDir}}
+ end;
+ true ->
+ create_lib_dirs(Opts, [{output_dir, OutputDir} | Acc])
+ end.
+
+-spec create_lib_dirs([getopt:option()], rcl_state:cmd_args()) ->
+ {ok, rcl_state:cmd_args()} | {error, Reason::term()}.
+create_lib_dirs(Opts, Acc) ->
+ Dirs = proplists:get_all_values(lib_dir, Opts),
+ case check_lib_dirs(Dirs) of
+ Error = {error, _} ->
+ Error;
+ ok ->
+ {ok, [{lib_dirs, Dirs} | Acc]}
+ end.
+
+-spec check_lib_dirs([string()]) -> ok | {error, {Reason::atom(), Dir::string()}}.
+check_lib_dirs([]) ->
+ ok;
+check_lib_dirs([Dir | Rest]) ->
+ case filelib:is_dir(Dir) of
+ false ->
+ {error, {not_directory, Dir}};
+ true ->
+ check_lib_dirs(Rest)
+ end.