From 9aab4d7a16fba5dfcf4d60b58a05cc765eca3335 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 8 Sep 2012 11:15:49 -0500 Subject: full argument parsing and management capability --- src/rcl_cmd_args.erl | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/rcl_cmd_args.erl (limited to 'src/rcl_cmd_args.erl') 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 +%%% @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. -- cgit v1.2.3