<commit_before>%% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
%%%---------------------------------------------------------------------------
%%% @author <NAME>
%%% @doc
%%% Populate the application metadata.
%%% @end
%%% @copyright (C) 2011 Erlware, LLC.
%%%---------------------------------------------------------------------------
-module(sin_app_meta).


-include_lib("sinan/include/sinan.hrl").

%% API
-export([build_meta/3,
         populate_modules/1,
         write_app_file/1,
         format_exception/1]).

%% SLASH_RE was create by doing re:compile("\\/").
-define(SLASH_RE,
        {re_pattern,0,0,
         <<69,82,67,80,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,0,0,
           0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93,0,5,27,47,83,0,5,27,92,
           84,0,10,0>>}).

%%====================================================================
%% API
%%====================================================================
write_app_file(#app{name=AppName,vsn=Vsn,path=Path,
                    description=Desc,registered=Reg,
                    applications=Appls,included_applications=IA,
                    mod=Mod,modules=AppModules,
                    id=Id,maxP=MaxP,maxT=MaxT,env=Env,
                    start_phases=StartPhases}) ->
    MetaDataPath = filename:join([Path, "ebin",
                                  erlang:atom_to_list(AppName) ++
                                      ".app"]),
    MetaData = {application, AppName,
                [{description, Desc},
                 {id, Id},
                 {vsn, Vsn},
                 {modules, AppModules},
                 {maxP, MaxP},
                 {maxT, MaxT},
                 {registered, Reg},
                 {included_applications, IA},
                 {applications, Appls},
                 {env, Env},
                 {mod, Mod},
                 {start_phases, StartPhases}]},
    file:write_file(MetaDataPath,
                    io_lib:format("~p.\n",
                                  [MetaData])).

populate_modules(App=#app{path=Path}) ->
    EbinDir = filename:join(Path, "ebin"),
    Modules =
        filelib:fold_files(EbinDir,
                           ".+\.beam",
                           true,
                           fun(File, Acc) ->
                                   PathName = filename:rootname(File, ".beam"),
                                   Name = string:substr(PathName,
                                                        erlang:length(EbinDir) + 2),
                                   ModuleName =
                                       erlang:list_to_atom(erlang:binary_to_list(
                                                             erlang:iolist_to_binary(
                                                               re:replace(Name,
                                                                          ?SLASH_RE,
                                                                          ".",
                                                                          [global])))),
                                   [ModuleName | Acc]
                           end,
                           []),
    App#app{modules=Modules}.

build_meta(Config, State0, AppDir) ->
    AppFile  = get_app_file(State0, AppDir),
    case file:consult(AppFile) of
        {ok, [Detail={application, _, _Details}]} ->
            build_out_app_description(Config, State0, AppDir, AppFile, Detail);
        {error, {_, Module, Desc}} ->
            Error = Module:format_error(Desc),
            ?SIN_RAISE(State0, {invalid_app_file, AppFile, Error});
        {error, Error} ->
            ?SIN_RAISE(State0,
                       {no_app_file_available, AppFile, Error})
    end.

%% @doc Format an exception thrown by this module
-spec format_exception(sin_exceptions:exception()) ->
                              string().
format_exception(?SIN_EXEP_UNPARSE(_, {unable_to_read_config,
                                       AppFilePath, Error})) ->
    io_lib:format("unable parse *.app file ~s:~s.",
                  [AppFilePath, file:format_error(Error)]);
format_exception(?SIN_EXEP_UNPARSE(_, {invalid_app_file, bad_name,
                                       AppFile, AppName, WrongAppName})) ->
    io_lib:format("~s file has wrong app name. Should be ~p,"
                  " but is ~p.", [AppFile, AppName, WrongAppName]);
format_exception(?SIN_EXEP_UNPARSE(_, {invalid_app_file, AppFile,
                                       _AppName, Error})) ->
    io_lib:format("Unable to parse *.app file ~s due to ~p.",
                  [AppFile, Error]);
format_exception(?SIN_EXEP_UNPARSE(_, {no_app_file_available,
                                       AppFile, _AppName, Error})) ->
    io_lib:format("Unable to access file ~s due to  ~p.", [AppFile, Error]);
format_exception(Exception) ->
    sin_exceptions:format_exception(Exception).

%%====================================================================
%% Internal functions
%%====================================================================<commit_msg>fix a nasty bug in app generation<commit_after>%% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
%%%---------------------------------------------------------------------------
%%% @author <NAME>
%%% @doc
%%% Populate the application metadata.
%%% @end
%%% @copyright (C) 2011 Erlware, LLC.
%%%---------------------------------------------------------------------------
-module(sin_app_meta).


-include_lib("sinan/include/sinan.hrl").

%% API
-export([build_meta/3,
         populate_modules/1,
         write_app_file/1,
         format_exception/1]).

%% SLASH_RE was create by doing re:compile("\\/").
-define(SLASH_RE,
        {re_pattern,0,0,
         <<69,82,67,80,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,0,0,
           0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93,0,5,27,47,83,0,5,27,92,
           84,0,10,0>>}).

%%====================================================================
%% API
%%====================================================================
write_app_file(#app{name=AppName,vsn=Vsn,path=Path,
                    description=Desc,registered=Reg,
                    applications=Appls,included_applications=IA,
                    mod=Mod,modules=AppModules,
                    id=Id,maxP=MaxP,maxT=MaxT,env=Env,
                    start_phases=StartPhases}) ->
    MetaDataPath = filename:join([Path, "ebin",
                                  erlang:atom_to_list(AppName) ++
                                      ".app"]),
    MetaData = {application, AppName,
                lists:flatten(
                  [{description, Desc},
                   is_not_default(Id, [], {id, Id}),
                   {vsn, Vsn},
                   {modules, AppModules},
                   is_not_default(MaxP, infinity, {maxP, MaxP}),
                   is_not_default(MaxT, infinity, {maxT, MaxT}),
                   {registered, Reg},
                   is_not_default(IA, [], {included_applications, IA}),
                   {applications, Appls},
                   is_not_default(Env, [], {env, Env}),
                   is_not_default(Mod, undefined, {mod, Mod}),
                   is_not_default(StartPhases, undefined, {start_phases, StartPhases})
                  ])},
                file:write_file(MetaDataPath,
                    io_lib:format("~p.\n",
                                  [MetaData])).

populate_modules(App=#app{path=Path}) ->
    EbinDir = filename:join(Path, "ebin"),
    Modules =
        filelib:fold_files(EbinDir,
                           ".+\.beam",
                           true,
                           fun(File, Acc) ->
                                   PathName = filename:rootname(File, ".beam"),
                                   Name = string:substr(PathName,
                                                        erlang:length(EbinDir) + 2),
                                   ModuleName =
                                       erlang:list_to_atom(erlang:binary_to_list(
                                                             erlang:iolist_to_binary(
                                                               re:replace(Name,
                                                                          ?SLASH_RE,
                                                                          ".",
                                                                          [global])))),
                                   [ModuleName | Acc]
                           end,
                           []),
    App#app{modules=Modules}.

build_meta(Config, State0, AppDir) ->
    AppFile  = get_app_file(State0, AppDir),
    case file:consult(AppFile) of
        {ok, [Detail={application, _, _Details}]} ->
            build_out_app_description(Config, State0, AppDir, AppFile, Detail);
        {error, {_, Module, Desc}} ->
            Error = Module:format_error(Desc),
            ?SIN_RAISE(State0, {invalid_app_file, AppFile, Error});
        {error, Error} ->
            ?SIN_RAISE(State0,
                       {no_app_file_available, AppFile, Error})
    end.

%% @doc Format an exception thrown by this module
-spec format_exception(sin_exceptions:exception()) ->
                              string().
format_exception(?SIN_EXEP_UNPARSE(_, {unable_to_read_config,
                                       AppFilePath, Error})) ->
    io_lib:format("unable parse *.app file ~s:~s.",
                  [AppFilePath, file:format_error(Error)]);
format_exception(?SIN_EXEP_UNPARSE(_, {invalid_app_file, bad_name,
                                       AppFile, AppName, WrongAppName})) ->
    io_lib:format("~s file has wrong app name. Should be ~p,"
                  " but is ~p.", [AppFile, AppName, WrongAppName]);
format_exception(?SIN_EXEP_UNPARSE(_, {invalid_app_file, AppFile,
                                       _AppName, Error})) ->
    io_lib:format("Unable to parse *.app file ~s due to ~p.",
                  [AppFile, Error]);
format_exception(?SIN_EXEP_UNPARSE(_, {no_app_file_available,
                                       AppFile, _AppName, Error})) ->
    io_lib:format("Unable to access file ~s due to  ~p.", [AppFile, Error]);
format_exception(Exception) ->
    sin_exceptions:format_exception(Exception).

%%====================================================================
%% Internal functions
%%====================================================================
is_not_default(Value, Value, _) ->
    [];
is_not_default(_Value, _DefaultValue, Result) ->
    Result.


{'fraction_non_alphanumeric': 0.19790486976217442, 'fraction_numerical': 0.01812004530011325, 'mean_word_length': 1.4587006960556845, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 54, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2601684', 'n_tokens_mistral': 2961, 'n_tokens_neox': 2792, 'n_words': 460}