Initial commit
This commit is contained in:
parent
6c7cd5aee2
commit
b48a9f5c58
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -1,12 +1,29 @@
|
|||
# ---> Elixir
|
||||
/_build
|
||||
/cover
|
||||
/deps
|
||||
/doc
|
||||
/.fetch
|
||||
erl_crash.dump
|
||||
*.ez
|
||||
*.beam
|
||||
/config/*.secret.exs
|
||||
.elixir_ls/
|
||||
# The directory Mix will write compiled artifacts to.
|
||||
/_build/
|
||||
/.elixir_ls/
|
||||
|
||||
# If you run "mix test --cover", coverage assets end up here.
|
||||
/cover/
|
||||
|
||||
# The directory Mix downloads your dependencies sources to.
|
||||
/deps/
|
||||
|
||||
# Where third-party dependencies like ExDoc output generated docs.
|
||||
/doc/
|
||||
|
||||
# Ignore .fetch files in case you like to edit your project deps locally.
|
||||
/.fetch
|
||||
|
||||
# If the VM crashes, it generates a dump, let's ignore it too.
|
||||
erl_crash.dump
|
||||
|
||||
# Also ignore archive artifacts (built via "mix archive.build").
|
||||
*.ez
|
||||
|
||||
# Ignore package tarball (built via "mix hex.build").
|
||||
ex_datagovua-*.tar
|
||||
|
||||
# Temporary files, for example, from tests.
|
||||
/tmp/
|
||||
|
||||
.DS_Store
|
|
@ -0,0 +1,3 @@
|
|||
alias ExDataGovUA.Package
|
||||
alias ExDataGovUA.Package.Meta
|
||||
alias ExDataGovUA.Package.Meta.Fetcher
|
22
README.md
22
README.md
|
@ -1,3 +1,21 @@
|
|||
# ex_data.gov.ua
|
||||
# ExDatagovua
|
||||
|
||||
**TODO: Add description**
|
||||
|
||||
## Installation
|
||||
|
||||
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
|
||||
by adding `ex_datagovua` to your list of dependencies in `mix.exs`:
|
||||
|
||||
```elixir
|
||||
def deps do
|
||||
[
|
||||
{:ex_datagovua, "~> 0.1.0"}
|
||||
]
|
||||
end
|
||||
```
|
||||
|
||||
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
|
||||
be found at [https://hexdocs.pm/ex_datagovua](https://hexdocs.pm/ex_datagovua).
|
||||
|
||||
data.gov.ua universal fetcher
|
|
@ -0,0 +1,20 @@
|
|||
use Mix.Config
|
||||
|
||||
config :ex_datagovua,
|
||||
default_fetcher: ExDataGovUA.Fetchers.FinchFetcher,
|
||||
default_decoder: ExDataGovUA.Decoders.JasonDecoder,
|
||||
file_formats: [
|
||||
"json"
|
||||
],
|
||||
container_formats: [
|
||||
"gz"
|
||||
],
|
||||
packages: %{
|
||||
"cf37fc56-2eb5-4b6c-81d2-d790e3264111": %{
|
||||
# schedule: "0 0 1 * *",
|
||||
# file: :all
|
||||
# mode: :rewrite
|
||||
}
|
||||
}
|
||||
|
||||
import_config "#{Mix.env()}.exs"
|
|
@ -0,0 +1 @@
|
|||
import Config
|
|
@ -0,0 +1 @@
|
|||
import Config
|
|
@ -0,0 +1 @@
|
|||
import Config
|
|
@ -0,0 +1,18 @@
|
|||
defmodule ExDataGovUA.Application do
|
||||
# See https://hexdocs.pm/elixir/Application.html
|
||||
# for more information on OTP Applications
|
||||
@moduledoc false
|
||||
|
||||
use Application
|
||||
|
||||
def start(_type, _args) do
|
||||
children = [
|
||||
# {Finch, name: ExDataGovUA.Finch}
|
||||
]
|
||||
|
||||
# See https://hexdocs.pm/elixir/Supervisor.html
|
||||
# for other strategies and supported options
|
||||
opts = [strategy: :one_for_one, name: ExDataGovUA.Supervisor]
|
||||
Supervisor.start_link(children, opts)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
defmodule ExDataGovUA.Archivers.Base do
|
||||
@type stream :: Stream.t()
|
||||
|
||||
@callback deflate(stream) :: stream
|
||||
|
||||
@callback inflate(stream) :: stream
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
defmodule ExDataGovUA.Archivers.Gz do
|
||||
@behaviour ExDataGovUA.Archivers.Base
|
||||
|
||||
@type input :: Stream.t()
|
||||
@type output :: Stream.t()
|
||||
|
||||
@spec deflate(input) :: output
|
||||
@doc """
|
||||
Pack data to archive
|
||||
"""
|
||||
def deflate(stream), do: stream |> StreamGzip.gzip
|
||||
|
||||
|
||||
@spec inflate(input) :: output
|
||||
@doc """
|
||||
Extract data from archive
|
||||
"""
|
||||
def inflate(stream), do: stream |> StreamGzip.gunzip
|
||||
end
|
|
@ -0,0 +1,93 @@
|
|||
defmodule ExDataGovUA.Commons.HttpStream do
|
||||
def get(url,emit_end\\false) do
|
||||
|
||||
Stream.resource(
|
||||
fn -> start_fun(url) end,
|
||||
|
||||
# next_fun (multi caluses)
|
||||
fn
|
||||
%HTTPoison.AsyncResponse{}=resp ->
|
||||
handle_async_resp(resp,emit_end)
|
||||
|
||||
#last accumulator when emitting :end
|
||||
{:end, resp}->
|
||||
{:halt, resp}
|
||||
end,
|
||||
|
||||
fn %HTTPoison.AsyncResponse{id: id} ->
|
||||
IO.puts("END_FUN")
|
||||
:hackney.stop_async(id)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
defp start_fun(url) do
|
||||
HTTPoison.get!(url,%{}, [stream_to: self(), async: :once])
|
||||
end
|
||||
|
||||
|
||||
defp handle_async_resp(%HTTPoison.AsyncResponse{id: id}=resp,emit_end) do
|
||||
receive do
|
||||
%HTTPoison.AsyncStatus{id: ^id, code: code}->
|
||||
IO.inspect(code, label: "STATUS: ")
|
||||
HTTPoison.stream_next(resp)
|
||||
{[], resp}
|
||||
%HTTPoison.AsyncHeaders{id: ^id, headers: headers}->
|
||||
IO.inspect(headers, label: "HEADERS: ")
|
||||
HTTPoison.stream_next(resp)
|
||||
{[], resp}
|
||||
%HTTPoison.AsyncChunk{id: ^id, chunk: chunk}->
|
||||
HTTPoison.stream_next(resp)
|
||||
# :erlang.garbage_collect()
|
||||
{[chunk], resp}
|
||||
%HTTPoison.AsyncEnd{id: ^id}->
|
||||
if emit_end do
|
||||
{[:end], {:end, resp}}
|
||||
else
|
||||
{:halt, resp}
|
||||
end
|
||||
after
|
||||
5_000 -> raise "receive timeout"
|
||||
end
|
||||
end
|
||||
|
||||
def lines(enum), do: lines(enum, :string_split)
|
||||
|
||||
def lines(enum, :next_lines) do
|
||||
enum
|
||||
|> Stream.transform("",&next_lines/2)
|
||||
end
|
||||
|
||||
def lines(enum, :string_split) do
|
||||
enum
|
||||
|> Stream.transform("",fn
|
||||
:end, acc ->
|
||||
{[acc],""}
|
||||
chunk, acc ->
|
||||
[last_line | lines] =
|
||||
String.split(acc <> chunk,"\n")
|
||||
|> Enum.reverse()
|
||||
{Enum.reverse(lines),last_line}
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
defp next_lines(:end,prev), do: {[prev], ""}
|
||||
defp next_lines(chunk,current_line) do
|
||||
# :erlang.garbage_collect()
|
||||
next_lines(chunk,current_line,[])
|
||||
end
|
||||
|
||||
defp next_lines(<<"\n"::utf8, rest::binary>>,current_line,lines) do
|
||||
next_lines(rest,"",[<<current_line::binary,"\n"::utf8>> | lines])
|
||||
end
|
||||
|
||||
defp next_lines(<<c::utf8, rest::binary>>,current_line,lines) do
|
||||
next_lines(rest,<<current_line::binary, c::utf8>>,lines)
|
||||
end
|
||||
|
||||
defp next_lines(<<>>,current_line,lines) do
|
||||
{Enum.reverse(lines), current_line}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
defmodule ExDataGovUA.Decoders.Base do
|
||||
@type data :: map()
|
||||
@type status :: Atom.t()
|
||||
@type async_response :: Stream.t()
|
||||
@type sync_response :: {status, data}
|
||||
@type body :: String.t() | Stream.t()
|
||||
|
||||
@callback decode(body) :: async_response | sync_response
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
defmodule ExDataGovUA.Decoders.JasonDecoder do
|
||||
@behaviour ExDataGovUA.Decoders.Base
|
||||
|
||||
@impl true
|
||||
def decode(data) do
|
||||
Jason.decode(data, [keys: :atoms])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
defmodule ExDataGovUA.Decoders.JaxonDecoder do
|
||||
@behaviour ExDataGovUA.Decoders.Base
|
||||
|
||||
@impl true
|
||||
def decode(stream) do
|
||||
stream
|
||||
|> Jaxon.Stream.from_enumerable()
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
defmodule ExDataGovUA.Fetchers.Base do
|
||||
@type data :: map()
|
||||
@type status :: Atom.t()
|
||||
@type url :: String.t()
|
||||
@type method :: Atom.t()
|
||||
|
||||
@callback fetch(method, url) :: {status, data}
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
defmodule ExDataGovUA.Fetchers.FinchFetcher do
|
||||
@behaviour ExDataGovUA.Fetchers.Base
|
||||
|
||||
@impl true
|
||||
def fetch(method, url) do
|
||||
start()
|
||||
with request <- Finch.build(method, url),
|
||||
{:ok, %Finch.Response{body: body}} <- Finch.request(request, MyFinchFetcher) do
|
||||
{:ok, body}
|
||||
end
|
||||
end
|
||||
|
||||
defp start() do
|
||||
case Finch.start_link(name: MyFinchFetcher) do
|
||||
{:ok, pid} -> pid
|
||||
{:error, {:already_started, pid}} -> pid
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
defmodule ExDataGovUA.Package.Base do
|
||||
defstruct [:id, :meta]
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
defmodule ExDataGovUA.Package.Meta.Base do
|
||||
defstruct [
|
||||
:profile,
|
||||
:name,
|
||||
:contributors,
|
||||
:created,
|
||||
:title,
|
||||
:keywords,
|
||||
:version,
|
||||
:licenses,
|
||||
:homepage,
|
||||
:id,
|
||||
:resources,
|
||||
:description
|
||||
]
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
profile: String.t(),
|
||||
name: String.t(),
|
||||
contributors: List.t(),
|
||||
created: String.t(),
|
||||
title: String.t(),
|
||||
keywords: List.t(),
|
||||
version: String.t(),
|
||||
licenses: List.t(),
|
||||
homepage: String.t(),
|
||||
id: String.t(),
|
||||
resources: List.t(),
|
||||
description: String.t()
|
||||
}
|
||||
|
||||
use ExConstructor
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
defmodule ExDataGovUA.Package.Meta.Parser do
|
||||
@default_fetcher Application.get_env(:ex_datagovua, :default_fetcher)
|
||||
@default_decoder Application.get_env(:ex_datagovua, :default_decoder)
|
||||
|
||||
@type result :: %ExDataGovUA.Package.Meta.Base{}
|
||||
@type id :: String.t()
|
||||
@type url :: String.t()
|
||||
@type fetcher :: Atom.t()
|
||||
@type decoder :: Atom.t()
|
||||
|
||||
@doc """
|
||||
Return meta information URL by data package ID
|
||||
"""
|
||||
@spec url(id) :: url
|
||||
def url(id) do
|
||||
"https://data.gov.ua/api/3/action/package_show?id=#{id}"
|
||||
end
|
||||
|
||||
@doc """
|
||||
Return meta information (ExDataGovUA.Package.Meta.Base) by data package ID
|
||||
"""
|
||||
@spec parse(id, fetcher, decoder) :: %ExDataGovUA.Package.Meta.Base{}
|
||||
def parse(id, fetcher \\ @default_fetcher, decoder \\ @default_decoder) do
|
||||
with {:ok, body} <- fetcher.fetch(:get, url(id)),
|
||||
{:ok, map} <- decoder.decode(body),
|
||||
result <- ExDataGovUA.Package.Meta.Base.new(map.result) do
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
defmodule ExDataGovUA.Resource.Base do
|
||||
def download(url, _filename) do
|
||||
url
|
||||
|> ExDataGovUA.Streamers.HttpStreamer.get()
|
||||
|> ExDataGovUA.Archivers.Gz.inflate()
|
||||
|> ExDataGovUA.Decoders.JaxonDecoder.decode()
|
||||
|> Enum.to_list()
|
||||
# |> Stream.run()
|
||||
# |> ExDataGovUA.Streamers.FileStreamer.export(filename)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
defmodule ExDataGovUA.Streamers.FileStreamer do
|
||||
@chunk_size 2048
|
||||
@spec export(Stream.t(), String.t()) :: Atom.t()
|
||||
def export(stream, filename) do
|
||||
stream
|
||||
|> Stream.into(File.stream!(filename, [], @chunk_size))
|
||||
end
|
||||
|
||||
@spec import(String.t()) :: File.Stream.t()
|
||||
def import(filename) do
|
||||
filename
|
||||
|> File.stream!([], @chunk_size)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
defmodule ExDataGovUA.Streamers.HttpStreamer do
|
||||
alias ExDataGovUA.Commons.HttpStream
|
||||
|
||||
def get(url) do
|
||||
url
|
||||
|> HttpStream.get()
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
defmodule ExDataGovUA do
|
||||
@moduledoc """
|
||||
Documentation for `ExDatagovua`.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Hello world.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> ExDatagovua.hello()
|
||||
:world
|
||||
|
||||
"""
|
||||
def hello do
|
||||
:world
|
||||
end
|
||||
end
|
|
@ -0,0 +1,42 @@
|
|||
defmodule ExDataGovUA.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :ex_datagovua,
|
||||
version: "0.1.0",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications.
|
||||
def application do
|
||||
[
|
||||
extra_applications: applications(Mix.env()),
|
||||
mod: {ExDataGovUA.Application, []}
|
||||
]
|
||||
end
|
||||
|
||||
defp applications(:dev), do: applications(:all) ++ ~w(remix)a
|
||||
defp applications(_all), do: ~w(logger)a
|
||||
|
||||
# Run "mix help deps" to learn about dependencies.
|
||||
defp deps do
|
||||
[
|
||||
{:jason, "~> 1.2.2"},
|
||||
{:jaxon, "~> 2.0.8"},
|
||||
{:finch, "~> 0.8.0"},
|
||||
{:httpoison, "~> 1.8.0"},
|
||||
{:stream_gzip, "~> 0.4.1"},
|
||||
{:exconstructor, "~> 1.2.2"},
|
||||
{:ex_doc, "~> 0.24.2", only: :dev, runtime: false},
|
||||
{:observer_cli, "~> 1.6.2", only: :dev, runtime: false},
|
||||
{:credo, "~> 1.5.6", only: :dev, runtime: false},
|
||||
{:dialyxir, "~> 1.1.0", only: :dev, runtime: false},
|
||||
# Remix for autorestart
|
||||
{:remix, "~> 0.0.2", only: :dev}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,36 @@
|
|||
%{
|
||||
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
|
||||
"castore": {:hex, :castore, "0.1.11", "c0665858e0e1c3e8c27178e73dffea699a5b28eb72239a3b2642d208e8594914", [:mix], [], "hexpm", "91b009ba61973b532b84f7c09ce441cba7aa15cb8b006cf06c6f4bba18220081"},
|
||||
"certifi": {:hex, :certifi, "2.6.1", "dbab8e5e155a0763eea978c913ca280a6b544bfa115633fa20249c3d396d9493", [:rebar3], [], "hexpm", "524c97b4991b3849dd5c17a631223896272c6b0af446778ba4675a1dff53bb7e"},
|
||||
"credo": {:hex, :credo, "1.5.6", "e04cc0fdc236fefbb578e0c04bd01a471081616e741d386909e527ac146016c6", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "4b52a3e558bd64e30de62a648518a5ea2b6e3e5d2b164ef5296244753fc7eb17"},
|
||||
"dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.13", "0c98163e7d04a15feb62000e1a891489feb29f3d10cb57d4f845c405852bbef8", [:mix], [], "hexpm", "d602c26af3a0af43d2f2645613f65841657ad6efc9f0e361c3b6c06b578214ba"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"},
|
||||
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.24.2", "e4c26603830c1a2286dae45f4412a4d1980e1e89dc779fcd0181ed1d5a05c8d9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e134e1d9e821b8d9e4244687fb2ace58d479b67b282de5158333b0d57c6fb7da"},
|
||||
"exconstructor": {:hex, :exconstructor, "1.2.3", "1f40baf7669aef0ac66325eb02cb119e708d24b490ace05a27bc1b42e30113b2", [:mix], [], "hexpm", "c7f549596308e6ba66aa66a108ddd1048d5654c4f0aa49d55d15df3989554f34"},
|
||||
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
|
||||
"finch": {:hex, :finch, "0.8.0", "9fe1b7b1613f4f0f43ac4be94462a0f3eb13264e5e9a624005da5670e452a1d1", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.3.5", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "07650fd74da3fb51984b9f62bf4db3ef720f3c06d914d716cceeb13a2bc2542d"},
|
||||
"hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"},
|
||||
"httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"},
|
||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
|
||||
"jaxon": {:hex, :jaxon, "2.0.8", "00951a79d354260e28d7e36f956c3de94818124768a4b22e0fc55559d1b3bfe7", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "74532853b1126609615ea98f0ceb5009e70465ca98027afbbd8ed314d887e82d"},
|
||||
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
|
||||
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},
|
||||
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
|
||||
"mint": {:hex, :mint, "1.3.0", "396b3301102f7b775e103da5a20494b25753aed818d6d6f0ad222a3a018c3600", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "a9aac960562e43ca69a77e5176576abfa78b8398cec5543dd4fb4ab0131d5c1e"},
|
||||
"nimble_options": {:hex, :nimble_options, "0.3.5", "a4f6820cdcb4ee444afd78635f323e58e8a5ddf2fbbe9b9d283a99f972034bae", [:mix], [], "hexpm", "f5507cc90033a8d12769522009c80aa9164af6bab245dbd4ad421d008455f1e1"},
|
||||
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
|
||||
"nimble_pool": {:hex, :nimble_pool, "0.2.4", "1db8e9f8a53d967d595e0b32a17030cdb6c0dc4a451b8ac787bf601d3f7704c3", [:mix], [], "hexpm", "367e8071e137b787764e6a9992ccb57b276dc2282535f767a07d881951ebeac6"},
|
||||
"observer_cli": {:hex, :observer_cli, "1.6.2", "016588e9a966247401bcbf02976d468f1e6f06891dde44f873c9259c6496cca1", [:mix, :rebar3], [{:recon, "~>2.5.1", [hex: :recon, repo: "hexpm", optional: false]}], "hexpm", "c23db9e4cca0e849adc42b0a099affb9e6267c5f23a871fc6f144348b249341f"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
|
||||
"recon": {:hex, :recon, "2.5.2", "cba53fa8db83ad968c9a652e09c3ed7ddcc4da434f27c3eaa9ca47ffb2b1ff03", [:mix, :rebar3], [], "hexpm", "2c7523c8dee91dff41f6b3d63cba2bd49eb6d2fe5bf1eec0df7f87eb5e230e1c"},
|
||||
"remix": {:hex, :remix, "0.0.2", "f06115659d8ede8d725fae1708920ef73353a1b39efe6a232d2a38b1f2902109", [:mix], [], "hexpm", "5f5555646ed4fca83fab8620735150aa0bc408c5a17a70d28cfa7086bc6f497c"},
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
||||
"stream_gzip": {:hex, :stream_gzip, "0.4.1", "d5f611b3fa8f5c9d928db4c8446edb7e22bebdf38d9914b4017a6fff44887b26", [:mix], [], "hexpm", "343dee3cc30dc78562bb524e8ea802a13d6377fc6ef1c05ac4c9d9fb1f58044b"},
|
||||
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
defmodule ExDataGovUATest do
|
||||
use ExUnit.Case
|
||||
doctest ExDataGovUA
|
||||
|
||||
test "greets the world" do
|
||||
assert ExDataGovUA.hello() == :world
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
ExUnit.start()
|
Loading…
Reference in New Issue