-module(gleamdoc). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/gleamdoc.gleam"). -export([main/0]). -export_type([format/0, scope/0, action/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(" Command-line entrypoint for Gleamdoc.\n"). -type format() :: text | json. -type scope() :: {scope, gleam@option:option(binary()), boolean()}. -type action() :: {lookup, binary(), format(), scope()} | {search, binary(), format(), scope(), integer(), gleamdoc@interface:symbol_kind(), gleamdoc@interface:target()} | {packages, format(), boolean()} | {index, format(), scope()}. -file("src/gleamdoc.gleam", 391). -spec print(format(), binary(), gleam@json:json(), gleamdoc@output:style()) -> nil. print(Format, Text, Json_value, Style) -> case Format of text -> case gleamdoc_ffi:stdout_supports_color() of true -> _pipe = Text, _pipe@1 = gleamdoc@output:text(_pipe, Style), gleam_stdlib:println(_pipe@1); false -> gleam_stdlib:println(Text) end; json -> _pipe@2 = Json_value, _pipe@3 = gleam@json:to_string(_pipe@2), gleam_stdlib:println(_pipe@3) end. -file("src/gleamdoc.gleam", 407). -spec fail(format(), binary()) -> nil. fail(Format, Message) -> case Format of text -> case gleamdoc_ffi:stderr_supports_color() of true -> _pipe = Message, _pipe@1 = gleamdoc@output:error(_pipe), gleam_stdlib:println_error(_pipe@1); false -> gleam_stdlib:println_error(Message) end; json -> _pipe@2 = gleam@json:object( [{<<"schema_version"/utf8>>, gleam@json:int(1)}, {<<"error"/utf8>>, gleam@json:string(Message)}, {<<"results"/utf8>>, gleam@json:preprocessed_array([])}] ), _pipe@3 = gleam@json:to_string(_pipe@2), gleam_stdlib:println(_pipe@3) end, gleamdoc_ffi:exit_status(1). -file("src/gleamdoc.gleam", 371). -spec select_packages(list(gleam@package_interface:package()), scope()) -> list(gleam@package_interface:package()). select_packages(Packages, Scope) -> {scope, Package, Dependencies} = Scope, Packages@1 = case Dependencies of true -> Packages; false -> gleam@list:take(Packages, 1) end, case Package of none -> Packages@1; {some, Wanted} -> _pipe = Packages@1, gleam@list:filter( _pipe, fun(Package@1) -> {package, Name, _, _, _} = Package@1, Name =:= Wanted end ) end. -file("src/gleamdoc.gleam", 356). -spec scope_error(list(gleam@package_interface:package()), scope()) -> gleam@option:option(binary()). scope_error(Packages, Scope) -> {scope, Package, _} = Scope, case Package of none -> none; {some, Wanted} -> case select_packages(Packages, Scope) of [] -> {some, <<<<"Package `"/utf8, Wanted/binary>>/binary, "` is not indexed in this scope."/utf8>>}; _ -> none end end. -file("src/gleamdoc.gleam", 280). -spec execute_with_packages(action(), list(gleam@package_interface:package())) -> nil. execute_with_packages(Action, All_packages) -> case Action of {lookup, Query, Format, Scope} -> case scope_error(All_packages, Scope) of {some, Message} -> fail(Format, Message); none -> Packages = select_packages(All_packages, Scope), case gleamdoc@interface:lookup_packages(Packages, Query) of [] -> fail( Format, <<<<"No public symbol found for `"/utf8, Query/binary>>/binary, "`."/utf8>> ); Entries -> print( Format, gleamdoc@interface:render_all(Entries), gleamdoc@interface:entries_json(Entries), documentation ) end end; {search, Query@1, Format@1, Scope@1, Limit, Kind, Target} -> case scope_error(All_packages, Scope@1) of {some, Message@1} -> fail(Format@1, Message@1); none -> Packages@1 = select_packages(All_packages, Scope@1), case gleamdoc@interface:search_packages_filtered( Packages@1, Query@1, Limit, Kind, Target ) of [] -> fail( Format@1, <<<<"No public symbols matched `"/utf8, Query@1/binary>>/binary, "`."/utf8>> ); Entries@1 -> print( Format@1, gleamdoc@interface:render_search_results( Entries@1 ), gleamdoc@interface:entries_json(Entries@1), search_results ) end end; {packages, Format@2, Dependencies} -> Packages@2 = case Dependencies of true -> All_packages; false -> gleam@list:take(All_packages, 1) end, print( Format@2, gleamdoc@interface:render_packages(Packages@2), gleamdoc@interface:packages_json(Packages@2), packages ); {index, Format@3, _} -> Packages@3 = All_packages, print( Format@3, <<<<<<"Indexed "/utf8, (erlang:integer_to_binary(erlang:length(Packages@3)))/binary>>/binary, " package interfaces.\n\n"/utf8>>/binary, (gleamdoc@interface:render_packages(Packages@3))/binary>>, gleamdoc@interface:packages_json(Packages@3), index_result ) end. -file("src/gleamdoc.gleam", 271). -spec action_format(action()) -> format(). action_format(Action) -> case Action of {lookup, _, Format, _} -> Format; {search, _, Format@1, _, _, _, _} -> Format@1; {packages, Format@2, _} -> Format@2; {index, Format@3, _} -> Format@3 end. -file("src/gleamdoc.gleam", 491). -spec decode_path(list(binary())) -> binary(). decode_path(Path) -> <<<<"["/utf8, (gleam@string:join(Path, <<"."/utf8>>))/binary>>/binary, "]"/utf8>>. -file("src/gleamdoc.gleam", 477). -spec decode_errors_message(list(gleam@dynamic@decode:decode_error())) -> binary(). decode_errors_message(Errors) -> _pipe = Errors, _pipe@1 = gleam@list:map( _pipe, fun(Error) -> {decode_error, Expected, Found, Path} = Error, <<<<<<<<<<"expected "/utf8, Expected/binary>>/binary, " but got "/utf8>>/binary, Found/binary>>/binary, " at "/utf8>>/binary, (decode_path(Path))/binary>> end ), gleam@string:join(_pipe@1, <<"; "/utf8>>). -file("src/gleamdoc.gleam", 468). -spec json_error_message(gleam@json:decode_error()) -> binary(). json_error_message(Error) -> case Error of {unable_to_decode, Errors} -> decode_errors_message(Errors); unexpected_end_of_input -> <<"unexpected end of JSON input"/utf8>>; {unexpected_byte, Byte} -> <<"unexpected byte: "/utf8, Byte/binary>>; {unexpected_sequence, Seq} -> <<"unexpected sequence: "/utf8, Seq/binary>> end. -file("src/gleamdoc.gleam", 452). -spec load_package_file(binary()) -> {ok, gleam@package_interface:package()} | {error, binary()}. load_package_file(Path) -> gleam@result:'try'( begin _pipe = simplifile:read(Path), gleam@result:map_error( _pipe, fun(_) -> <<<<"Could not read "/utf8, Path/binary>>/binary, "."/utf8>> end ) end, fun(Source) -> _pipe@1 = gleam@json:parse( Source, gleam@package_interface:decoder() ), gleam@result:map_error( _pipe@1, fun(Error) -> <<<<<<"Invalid package interface JSON at "/utf8, Path/binary>>/binary, ": "/utf8>>/binary, (json_error_message(Error))/binary>> end ) end ). -file("src/gleamdoc.gleam", 439). -spec load_package_files( list(binary()), list(gleam@package_interface:package()) ) -> {ok, list(gleam@package_interface:package())} | {error, binary()}. load_package_files(Paths, Packages) -> case Paths of [] -> {ok, lists:reverse(Packages)}; [Path | Rest] -> gleam@result:'try'( load_package_file(Path), fun(Package) -> load_package_files(Rest, [Package | Packages]) end ) end. -file("src/gleamdoc.gleam", 426). -spec load_packages(scope(), boolean()) -> {ok, list(gleam@package_interface:package())} | {error, binary()}. load_packages(Scope, Refresh) -> {scope, Package, Dependencies} = Scope, gleam@result:'try'( gleamdoc@index:package_interface_paths( Dependencies, gleam@option:unwrap(Package, <<""/utf8>>), Refresh ), fun(Paths) -> load_package_files(Paths, []) end ). -file("src/gleamdoc.gleam", 263). -spec lookup_load_scope(scope(), binary()) -> scope(). lookup_load_scope(Scope, Query) -> {scope, Package, Dependencies} = Scope, case {Package, gleam@string:split_once(Query, <<":"/utf8>>)} of {none, {ok, {Package@1, _}}} -> {scope, {some, Package@1}, Dependencies}; {_, _} -> Scope end. -file("src/gleamdoc.gleam", 251). -spec load_options(action()) -> {scope(), boolean()}. load_options(Action) -> case Action of {lookup, Query, _, Scope} -> {lookup_load_scope(Scope, Query), false}; {search, _, _, Scope@1, _, _, _} -> {Scope@1, false}; {packages, _, Dependencies} -> {{scope, none, Dependencies}, false}; {index, _, Scope@2} -> {Scope@2, true} end. -file("src/gleamdoc.gleam", 243). -spec execute(action()) -> nil. execute(Action) -> {Scope, Refresh} = load_options(Action), case load_packages(Scope, Refresh) of {error, Message} -> fail(action_format(Action), <<"error: "/utf8, Message/binary>>); {ok, All_packages} -> execute_with_packages(Action, All_packages) end. -file("src/gleamdoc.gleam", 236). -spec optional_package(binary()) -> gleam@option:option(binary()). optional_package(Package) -> case gleam@string:trim(Package) of <<""/utf8>> -> none; Package@1 -> {some, Package@1} end. -file("src/gleamdoc.gleam", 229). -spec output_format(boolean()) -> format(). output_format(Json) -> case Json of true -> json; false -> text end. -file("src/gleamdoc.gleam", 159). -spec no_deps_flag() -> glint:flag(boolean()). no_deps_flag() -> _pipe = glint:bool_flag(<<"no-deps"/utf8>>), _pipe@1 = glint:flag_default(_pipe, false), glint:flag_help(_pipe@1, <<"Only inspect the current project."/utf8>>). -file("src/gleamdoc.gleam", 153). -spec package_flag() -> glint:flag(binary()). package_flag() -> _pipe = glint:string_flag(<<"package"/utf8>>), _pipe@1 = glint:flag_default(_pipe, <<""/utf8>>), glint:flag_help( _pipe@1, <<"Restrict lookup or search to one package."/utf8>> ). -file("src/gleamdoc.gleam", 147). -spec json_flag() -> glint:flag(boolean()). json_flag() -> _pipe = glint:bool_flag(<<"json"/utf8>>), _pipe@1 = glint:flag_default(_pipe, false), glint:flag_help(_pipe@1, <<"Emit machine-readable JSON."/utf8>>). -file("src/gleamdoc.gleam", 128). -spec index_command() -> glint:command(action()). index_command() -> glint:command_help( <<"Generate package-interface caches used by lookup and search commands."/utf8>>, fun() -> glint:flag( json_flag(), fun(Json) -> glint:flag( package_flag(), fun(Package) -> glint:flag( no_deps_flag(), fun(No_deps) -> glint:unnamed_args( {eq_args, 0}, fun() -> glint:command( fun(_, _, Flags) -> Json@2 = case Json(Flags) of {ok, Json@1} -> Json@1; _assert_fail -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"index_command"/utf8>>, line => 137, value => _assert_fail, start => 3856, 'end' => 3889, pattern_start => 3867, pattern_end => 3875} ) end, Package@2 = case Package( Flags ) of {ok, Package@1} -> Package@1; _assert_fail@1 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"index_command"/utf8>>, line => 138, value => _assert_fail@1, start => 3892, 'end' => 3931, pattern_start => 3903, pattern_end => 3914} ) end, No_deps@2 = case No_deps( Flags ) of {ok, No_deps@1} -> No_deps@1; _assert_fail@2 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"index_command"/utf8>>, line => 139, value => _assert_fail@2, start => 3934, 'end' => 3973, pattern_start => 3945, pattern_end => 3956} ) end, {index, output_format(Json@2), {scope, optional_package( Package@2 ), not No_deps@2}} end ) end ) end ) end ) end ) end ). -file("src/gleamdoc.gleam", 116). -spec packages_command() -> glint:command(action()). packages_command() -> glint:command_help( <<"List indexed packages and module counts."/utf8>>, fun() -> glint:flag( json_flag(), fun(Json) -> glint:flag( no_deps_flag(), fun(No_deps) -> glint:unnamed_args( {eq_args, 0}, fun() -> glint:command( fun(_, _, Flags) -> Json@2 = case Json(Flags) of {ok, Json@1} -> Json@1; _assert_fail -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"packages_command"/utf8>>, line => 122, value => _assert_fail, start => 3354, 'end' => 3387, pattern_start => 3365, pattern_end => 3373} ) end, No_deps@2 = case No_deps(Flags) of {ok, No_deps@1} -> No_deps@1; _assert_fail@1 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"packages_command"/utf8>>, line => 123, value => _assert_fail@1, start => 3390, 'end' => 3429, pattern_start => 3401, pattern_end => 3412} ) end, {packages, output_format(Json@2), not No_deps@2} end ) end ) end ) end ) end ). -file("src/gleamdoc.gleam", 220). -spec parse_target(binary()) -> gleamdoc@interface:target(). parse_target(Target) -> case Target of <<""/utf8>> -> all_targets; <<"erlang"/utf8>> -> erlang; <<"javascript"/utf8>> -> javascript; _ -> all_targets end. -file("src/gleamdoc.gleam", 207). -spec parse_kind(binary()) -> gleamdoc@interface:symbol_kind(). parse_kind(Kind) -> case Kind of <<""/utf8>> -> all; <<"module"/utf8>> -> module; <<"fn"/utf8>> -> fn; <<"const"/utf8>> -> const; <<"type"/utf8>> -> type; <<"variant"/utf8>> -> variant; <<"alias"/utf8>> -> alias; _ -> all end. -file("src/gleamdoc.gleam", 195). -spec target_flag() -> glint:flag(binary()). target_flag() -> _pipe = glint:string_flag(<<"target"/utf8>>), _pipe@1 = glint:flag_default(_pipe, <<""/utf8>>), _pipe@2 = glint:flag_constraint( _pipe@1, fun(Target) -> case gleam@list:contains( [<<""/utf8>>, <<"erlang"/utf8>>, <<"javascript"/utf8>>], Target ) of true -> {ok, Target}; false -> snag:error(<<"--target must be erlang or javascript"/utf8>>) end end ), glint:flag_help( _pipe@2, <<"Restrict search to functions and constants for a target."/utf8>> ). -file("src/gleamdoc.gleam", 177). -spec kind_flag() -> glint:flag(binary()). kind_flag() -> _pipe = glint:string_flag(<<"kind"/utf8>>), _pipe@1 = glint:flag_default(_pipe, <<""/utf8>>), _pipe@2 = glint:flag_constraint( _pipe@1, fun(Kind) -> case gleam@list:contains( [<<""/utf8>>, <<"module"/utf8>>, <<"fn"/utf8>>, <<"const"/utf8>>, <<"type"/utf8>>, <<"variant"/utf8>>, <<"alias"/utf8>>], Kind ) of true -> {ok, Kind}; false -> snag:error( <<"--kind must be module, fn, const, type, variant, or alias"/utf8>> ) end end ), glint:flag_help(_pipe@2, <<"Restrict search to one symbol kind."/utf8>>). -file("src/gleamdoc.gleam", 165). -spec limit_flag() -> glint:flag(integer()). limit_flag() -> _pipe = glint:int_flag(<<"limit"/utf8>>), _pipe@1 = glint:flag_default(_pipe, 50), _pipe@2 = glint:flag_constraint(_pipe@1, fun(Limit) -> case Limit > 0 of true -> {ok, Limit}; false -> snag:error(<<"--limit must be greater than zero"/utf8>>) end end), glint:flag_help(_pipe@2, <<"Maximum number of search results."/utf8>>). -file("src/gleamdoc.gleam", 87). -spec search_command() -> glint:command(action()). search_command() -> glint:command_help( <<"Search symbol names, modules, packages, signatures, and documentation."/utf8>>, fun() -> glint:flag( json_flag(), fun(Json) -> glint:flag( limit_flag(), fun(Limit) -> glint:flag( kind_flag(), fun(Kind) -> glint:flag( target_flag(), fun(Target) -> glint:flag( package_flag(), fun(Package) -> glint:flag( no_deps_flag(), fun(No_deps) -> glint:unnamed_args( {min_args, 1}, fun() -> glint:command( fun( _, Terms, Flags ) -> Json@2 = case Json( Flags ) of {ok, Json@1} -> Json@1; _assert_fail -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"search_command"/utf8>>, line => 99, value => _assert_fail, start => 2627, 'end' => 2660, pattern_start => 2638, pattern_end => 2646} ) end, Limit@2 = case Limit( Flags ) of {ok, Limit@1} -> Limit@1; _assert_fail@1 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"search_command"/utf8>>, line => 100, value => _assert_fail@1, start => 2663, 'end' => 2698, pattern_start => 2674, pattern_end => 2683} ) end, Kind@2 = case Kind( Flags ) of {ok, Kind@1} -> Kind@1; _assert_fail@2 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"search_command"/utf8>>, line => 101, value => _assert_fail@2, start => 2701, 'end' => 2734, pattern_start => 2712, pattern_end => 2720} ) end, Target@2 = case Target( Flags ) of {ok, Target@1} -> Target@1; _assert_fail@3 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"search_command"/utf8>>, line => 102, value => _assert_fail@3, start => 2737, 'end' => 2774, pattern_start => 2748, pattern_end => 2758} ) end, Package@2 = case Package( Flags ) of {ok, Package@1} -> Package@1; _assert_fail@4 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"search_command"/utf8>>, line => 103, value => _assert_fail@4, start => 2777, 'end' => 2816, pattern_start => 2788, pattern_end => 2799} ) end, No_deps@2 = case No_deps( Flags ) of {ok, No_deps@1} -> No_deps@1; _assert_fail@5 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"search_command"/utf8>>, line => 104, value => _assert_fail@5, start => 2819, 'end' => 2858, pattern_start => 2830, pattern_end => 2841} ) end, {search, gleam@string:join( Terms, <<" "/utf8>> ), output_format( Json@2 ), {scope, optional_package( Package@2 ), not No_deps@2}, Limit@2, parse_kind( Kind@2 ), parse_target( Target@2 )} end ) end ) end ) end ) end ) end ) end ) end ) end ). -file("src/gleamdoc.gleam", 66). -spec lookup_command() -> glint:command(action()). lookup_command() -> glint:command_help( <<"Look up an exact public module, function, constant, type, variant, or alias."/utf8>>, fun() -> glint:named_arg( <<"query"/utf8>>, fun(Query) -> glint:flag( json_flag(), fun(Json) -> glint:flag( package_flag(), fun(Package) -> glint:flag( no_deps_flag(), fun(No_deps) -> glint:unnamed_args( {eq_args, 0}, fun() -> glint:command( fun(Named, _, Flags) -> Json@2 = case Json( Flags ) of {ok, Json@1} -> Json@1; _assert_fail -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"lookup_command"/utf8>>, line => 76, value => _assert_fail, start => 1884, 'end' => 1917, pattern_start => 1895, pattern_end => 1903} ) end, Package@2 = case Package( Flags ) of {ok, Package@1} -> Package@1; _assert_fail@1 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"lookup_command"/utf8>>, line => 77, value => _assert_fail@1, start => 1920, 'end' => 1959, pattern_start => 1931, pattern_end => 1942} ) end, No_deps@2 = case No_deps( Flags ) of {ok, No_deps@1} -> No_deps@1; _assert_fail@2 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"gleamdoc"/utf8>>, function => <<"lookup_command"/utf8>>, line => 78, value => _assert_fail@2, start => 1962, 'end' => 2001, pattern_start => 1973, pattern_end => 1984} ) end, {lookup, Query(Named), output_format( Json@2 ), {scope, optional_package( Package@2 ), not No_deps@2}} end ) end ) end ) end ) end ) end ) end ). -file("src/gleamdoc.gleam", 54). -spec cli() -> glint:glint(action()). cli() -> _pipe = glint:new(), _pipe@1 = glint:with_name(_pipe, <<"gleamdoc"/utf8>>), _pipe@2 = glint:global_help( _pipe@1, <<"Sparse, terminal-first documentation lookup for Gleam packages."/utf8>> ), _pipe@3 = glint:add(_pipe@2, [], lookup_command()), _pipe@4 = glint:add(_pipe@3, [<<"search"/utf8>>], search_command()), _pipe@5 = glint:add(_pipe@4, [<<"packages"/utf8>>], packages_command()), glint:add(_pipe@5, [<<"index"/utf8>>], index_command()). -file("src/gleamdoc.gleam", 46). ?DOC(" Runs the Gleamdoc command-line application.\n"). -spec main() -> nil. main() -> case erlang:element(4, argv:load()) of [<<"--version"/utf8>>] -> gleam_stdlib:println(<<"gleamdoc "/utf8, "0.3.0"/utf8>>); [<<"-v"/utf8>>] -> gleam_stdlib:println(<<"gleamdoc "/utf8, "0.3.0"/utf8>>); Arguments -> glint:run_and_handle(cli(), Arguments, fun execute/1) end.