zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

cli.ex (7061B)


      1 defmodule ExDoc.CLI do
      2   @moduledoc false
      3 
      4   @doc """
      5   Handles the command line parsing for the escript.
      6   """
      7   def main(args, generator \\ &ExDoc.generate_docs/3) do
      8     {:ok, _} = Application.ensure_all_started(:ex_doc)
      9 
     10     {opts, args, _invalid} =
     11       OptionParser.parse(args,
     12         aliases: [
     13           c: :config,
     14           f: :formatter,
     15           l: :logo,
     16           m: :main,
     17           n: :canonical,
     18           o: :output,
     19           p: :homepage_url,
     20           q: :quiet,
     21           u: :source_url,
     22           v: :version
     23         ],
     24         switches: [
     25           formatter: :keep,
     26           language: :string,
     27           package: :string,
     28           paths: :keep,
     29           proglang: :string,
     30           quiet: :boolean,
     31           source_ref: :string,
     32           version: :boolean
     33         ]
     34       )
     35 
     36     if List.keymember?(opts, :version, 0) do
     37       print_version()
     38     else
     39       generate(args, opts, generator)
     40     end
     41   end
     42 
     43   defp print_version do
     44     IO.puts("ExDoc v#{ExDoc.version()}")
     45   end
     46 
     47   defp generate(args, opts, generator) do
     48     [project, version, source_beam] = parse_args(args)
     49 
     50     Code.prepend_path(source_beam)
     51 
     52     for path <- Keyword.get_values(opts, :paths),
     53         path <- Path.wildcard(path) do
     54       Code.prepend_path(path)
     55     end
     56 
     57     opts =
     58       opts
     59       |> Keyword.put(:source_beam, source_beam)
     60       |> Keyword.put(:apps, [app(source_beam)])
     61       |> merge_config()
     62 
     63     quiet? = Keyword.get(opts, :quiet, false)
     64 
     65     for formatter <- get_formatters(opts) do
     66       index = generator.(project, version, Keyword.put(opts, :formatter, formatter))
     67 
     68       quiet? ||
     69         IO.puts(IO.ANSI.format([:green, "View #{inspect(formatter)} docs at #{inspect(index)}"]))
     70 
     71       index
     72     end
     73   end
     74 
     75   defp get_formatters(opts) do
     76     case Keyword.get_values(opts, :formatter) do
     77       [] -> opts[:formatters] || ["html", "epub"]
     78       values -> values
     79     end
     80   end
     81 
     82   defp app(source_beam) do
     83     case Path.wildcard(Path.join([source_beam, "*.app"])) do
     84       [path] ->
     85         path |> Path.basename(".app") |> String.to_atom()
     86 
     87       _ ->
     88         raise "cannot find .app file in #{inspect(source_beam)}"
     89     end
     90   end
     91 
     92   defp merge_config(opts) do
     93     case Keyword.fetch(opts, :config) do
     94       {:ok, config} ->
     95         opts
     96         |> Keyword.delete(:config)
     97         |> Keyword.merge(read_config(config))
     98 
     99       _ ->
    100         opts
    101     end
    102   end
    103 
    104   defp read_config(path) do
    105     case Path.extname(path) do
    106       ".exs" ->
    107         read_config_exs(path)
    108 
    109       ".config" ->
    110         read_config_erl(path)
    111 
    112       other ->
    113         raise "expected config to have .exs or .config extension, got: #{inspect(other)}"
    114     end
    115   end
    116 
    117   defp read_config_exs(path) do
    118     config = File.read!(path)
    119     {result, _} = Code.eval_string(config)
    120 
    121     unless is_list(result) do
    122       raise "expected a keyword list from config file: #{inspect(path)}"
    123     end
    124 
    125     result
    126   end
    127 
    128   defp read_config_erl(path) do
    129     case :file.consult(path) do
    130       {:ok, config} ->
    131         config
    132 
    133       {:error, reason} ->
    134         raise "error parsing #{path}: #{inspect(reason)}"
    135     end
    136   end
    137 
    138   defp parse_args([_project, _version, _source_beam] = args), do: args
    139 
    140   defp parse_args([_, _, _ | _]) do
    141     IO.puts("Too many arguments.\n")
    142     print_usage()
    143     exit({:shutdown, 1})
    144   end
    145 
    146   defp parse_args(_) do
    147     IO.puts("Too few arguments.\n")
    148     print_usage()
    149     exit({:shutdown, 1})
    150   end
    151 
    152   defp print_usage do
    153     IO.puts(~S"""
    154     Usage:
    155       ex_doc PROJECT VERSION BEAMS [OPTIONS]
    156 
    157     Examples:
    158       ex_doc "Ecto" "0.8.0" "_build/dev/lib/ecto/ebin" -u "https://github.com/elixir-ecto/ecto"
    159       ex_doc "Project" "1.0.0" "_build/dev/lib/project/ebin" -c "docs.exs"
    160 
    161     Options:
    162       PROJECT             Project name
    163       VERSION             Version number
    164       BEAMS               Path to compiled beam files
    165       -n, --canonical     Indicate the preferred URL with rel="canonical" link element
    166       -c, --config        Give configuration through a file instead of a command line.
    167                           See "Custom config" section below for more information.
    168       -f, --formatter     Docs formatter to use (html or epub), default: html and epub
    169       -p, --homepage-url  URL to link to for the site name
    170           --language      Identify the primary language of the documents, its value must be
    171                           a valid [BCP 47](https://tools.ietf.org/html/bcp47) language tag, default: "en"
    172       -l, --logo          Path to the image logo of the project (only PNG or JPEG accepted)
    173                           The image size will be 64x64 and copied to the assets directory
    174       -m, --main          The entry-point page in docs, default: "api-reference"
    175       -o, --output        Path to output docs, default: "doc"
    176           --package       Hex package name
    177           --paths         Prepends the given path to Erlang code path. The path might contain a glob
    178                           pattern but in that case, remember to quote it: --paths "_build/dev/lib/*/ebin".
    179                           This option can be given multiple times
    180           --proglang      The project's programming language, default: "elixir"
    181       -q, --quiet         Only output warnings and errors
    182           --source-ref    Branch/commit/tag used for source link inference, default: "master"
    183       -u, --source-url    URL to the source code
    184       -v, --version       Print ExDoc version
    185 
    186     ## Custom config
    187 
    188     A custom config can be given with the `--config` option.
    189 
    190     The file must either have ".exs" or ".config" extension.
    191 
    192     The file with the ".exs" extension must be an Elixir script that returns a keyword list with
    193     the same options declares in `Mix.Tasks.Docs`. Here is an example:
    194 
    195         [
    196           extras: Path.wildcard("lib/elixir/pages/*.md"),
    197           groups_for_functions: [
    198             Guards: & &1[:guard] == true
    199           ],
    200           skip_undefined_reference_warnings_on: ["compatibility-and-deprecations"],
    201           groups_for_modules: [
    202             ...
    203           ]
    204         ]
    205 
    206     The file with the ".config" extension must contain Erlang terms separated by ".".
    207     See `:file.consult/1` for more information. Here is an example:
    208 
    209         {extras, [<<"README.md">>, <<"CHANGELOG.md">>]}.
    210         {main, <<"readme">>}.
    211         {proglang, erlang}.
    212 
    213     ## Source linking
    214 
    215     ExDoc by default provides links to the source code implementation as
    216     long as `--source-url` or `--source-url-pattern` is provided. If you
    217     provide `--source-url`, ExDoc will inflect the url pattern automatically
    218     for GitHub, GitLab, and Bitbucket URLs. For example:
    219 
    220         --source-url "https://github.com/elixir-ecto/ecto"
    221 
    222     Will be inflected as:
    223 
    224         https://github.com/elixir-ecto/ecto/blob/master/%{path}#L%{line}
    225 
    226     To specify a particular branch or commit, use the `--source-ref` option:
    227 
    228         --source-url "https://github.com/elixir-ecto/ecto" --source-ref "v1.0"
    229 
    230     will result in the following URL pattern:
    231 
    232         https://github.com/elixir-ecto/ecto/blob/v1.0/%{path}#L%{line}
    233 
    234     """)
    235   end
    236 end