File: parser.ex

package info (click to toggle)
erlang-hex 2.0.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,204 kB
  • sloc: erlang: 2,950; sh: 203; makefile: 10
file content (60 lines) | stat: -rw-r--r-- 1,546 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
defmodule Hex.Netrc.Parser do
  @moduledoc false

  def parse(path \\ netrc_path()) when is_binary(path) do
    case File.read(path) do
      {:ok, contents} ->
        parse_contents(contents)

      error ->
        error
    end
  end

  defp parse_contents(contents) when is_binary(contents) do
    parse_result =
      contents
      |> String.trim()
      |> String.split("\n", trim: true)
      |> Enum.map(&String.split/1)
      |> Enum.reduce({%{}, nil}, &parse_line/2)

    case parse_result do
      {machines, %{username: _, password: _} = current} ->
        {host, machine} = Map.pop(current, :host)
        {:ok, Map.put(machines, host, machine)}

      _ ->
        {:error, :parse}
    end
  end

  defp parse_line(_, :parse_error), do: :parse_error

  defp parse_line(["machine", host], {machines, nil}) do
    {machines, %{host: host}}
  end

  defp parse_line(["machine", next_host], {machines, %{username: _, password: _} = current}) do
    {host, machine} = Map.pop(current, :host)
    {Map.put(machines, host, machine), %{host: next_host}}
  end

  defp parse_line(["login", username], {machines, %{} = current}) do
    {machines, Map.put(current, :username, username)}
  end

  defp parse_line(["password", password], {machines, %{} = current}) do
    {machines, Map.put(current, :password, password)}
  end

  defp parse_line(_line, _parse_state), do: :parse_error

  def netrc_path() do
    System.get_env("NETRC") || default_path()
  end

  defp default_path() do
    Path.join(System.user_home!(), ".netrc")
  end
end