mirror of
https://github.com/bonfire-networks/bonfire-app.git
synced 2024-05-02 01:08:45 +00:00
move mix tasks
This commit is contained in:
parent
5ff4b36886
commit
a0c263f7cb
110
lib/mix/mess.exs
110
lib/mix/mess.exs
|
@ -1,110 +0,0 @@
|
|||
# Copyright (c) 2020 James Laver, mess Contributors
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
if not Code.ensure_loaded?(Mess) do
|
||||
defmodule Mess do
|
||||
@sources [path: "deps.path", git: "deps.git", hex: "deps.hex"]
|
||||
|
||||
@newline ~r/(?:\r\n|[\r\n])/
|
||||
@parser ~r/^(?<indent>\s*)((?<package>[a-z_][a-z0-9_]+)\s*=\s*"(?<value>[^"]+)")?(?<post>.*)/
|
||||
@git_branch ~r/(?<repo>[^#]+)(#(?<branch>.+))?/
|
||||
|
||||
def umbrella_path(opts \\ []),
|
||||
do: opts[:umbrella_path] || if(Mix.env() != :prod, do: "extensions/", else: nil)
|
||||
|
||||
def deps(sources \\ @sources, extra_deps, opts \\ []),
|
||||
do: Enum.flat_map(sources, fn {k, v} -> read(v, k) end) |> deps_packages(extra_deps, opts)
|
||||
|
||||
defp deps_packages(packages, extra_deps, opts),
|
||||
do: Enum.flat_map(packages, &dep_spec(&1, opts)) |> deps_uniq(extra_deps, opts)
|
||||
|
||||
defp deps_uniq(packages, extra_deps, opts),
|
||||
do: Enum.uniq_by(packages ++ extra_deps, &elem(&1, 0)) |> maybe_filter_umbrella(opts)
|
||||
|
||||
defp maybe_filter_umbrella(deps, opts) do
|
||||
if opts[:umbrella_root?] do
|
||||
Enum.reject(deps, fn dep ->
|
||||
dep_opts = elem(dep, 1)
|
||||
is_list(dep_opts) and dep_opts[:from_umbrella]
|
||||
end)
|
||||
|
||||
# |> IO.inspect(label: "umbrella_root")
|
||||
else
|
||||
if umbrella_path(opts) do
|
||||
umbrella_deps = read_umbrella("../../config/deps.path", opts)
|
||||
|
||||
deps
|
||||
|> Enum.map(fn dep ->
|
||||
name = elem(dep, 0)
|
||||
|
||||
case umbrella_deps[name] do
|
||||
nil ->
|
||||
dep
|
||||
|
||||
dep_opts ->
|
||||
if dep_opts[:from_umbrella] do
|
||||
{name, in_umbrella: true, override: true}
|
||||
else
|
||||
{name, dep_opts |> Keyword.put(:path, "../../#{dep_opts[:path]}")}
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
# |> IO.inspect(label: "in_umbrella")
|
||||
else
|
||||
deps
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp read_umbrella(path, opts) when is_binary(path) do
|
||||
if File.exists?(path) do
|
||||
read(path, :path)
|
||||
|> Enum.flat_map(&dep_spec(&1, opts))
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
defp read(path, kind) when is_binary(path), do: have_read(File.read(path), kind)
|
||||
|
||||
defp have_read({:error, :enoent}, _kind), do: []
|
||||
|
||||
defp have_read({:ok, file}, kind),
|
||||
do: Enum.map(String.split(file, @newline), &read_line(&1, kind))
|
||||
|
||||
defp read_line(line, kind),
|
||||
do: Map.put(Regex.named_captures(@parser, line), :kind, kind)
|
||||
|
||||
defp dep_spec(%{"package" => ""}, _opts), do: []
|
||||
|
||||
defp dep_spec(%{"package" => p, "value" => v, :kind => :hex}, _opts),
|
||||
do: pkg(p, v, override: true)
|
||||
|
||||
defp dep_spec(%{"package" => p, "value" => v, :kind => :path}, opts) do
|
||||
umbrella_path = umbrella_path(opts)
|
||||
|
||||
if umbrella_path && String.starts_with?(v, umbrella_path) do
|
||||
pkg(p, from_umbrella: true, override: true, path: v)
|
||||
else
|
||||
pkg(p, path: v, override: true)
|
||||
end
|
||||
end
|
||||
|
||||
defp dep_spec(%{"package" => p, "value" => v, :kind => :git}, _opts), do: git(v, p)
|
||||
|
||||
defp git(line, p) when is_binary(line),
|
||||
do: git(Regex.named_captures(@git_branch, line), p)
|
||||
|
||||
defp git(%{"branch" => "", "repo" => r}, p),
|
||||
do: pkg(p, git: r, override: true)
|
||||
|
||||
defp git(%{"branch" => b, "repo" => r}, p),
|
||||
do: pkg(p, git: r, branch: b, override: true)
|
||||
|
||||
defp pkg(name, opts), do: [{String.to_atom(name), opts}]
|
||||
defp pkg(name, version, opts), do: [{String.to_atom(name), version, opts}]
|
||||
end
|
||||
end
|
299
lib/mix/mixer.ex
299
lib/mix/mixer.ex
|
@ -1,299 +0,0 @@
|
|||
if not Code.ensure_loaded?(Bonfire.Mixer) do
|
||||
defmodule Bonfire.Mixer do
|
||||
def deps(config, deps_subtype)
|
||||
|
||||
def deps(config, :bonfire) do
|
||||
prefixes = multirepo_prefixes(config)
|
||||
Enum.filter(config[:deps] || config, &in_multirepo?(&1, prefixes))
|
||||
end
|
||||
|
||||
def deps(config, :update = deps_subtype) do
|
||||
prefixes = multirepo_prefixes(config)
|
||||
|
||||
Enum.filter(
|
||||
config[:deps] || config,
|
||||
&(include_dep?(deps_subtype, &1, config[:deps_prefixes][deps_subtype]) ||
|
||||
in_multirepo?(&1, prefixes))
|
||||
)
|
||||
|
||||
# |> IO.inspect(limit: :infinity)
|
||||
end
|
||||
|
||||
def deps(config, deps_subtype) when is_atom(deps_subtype),
|
||||
do:
|
||||
Enum.filter(
|
||||
config[:deps] || config,
|
||||
&include_dep?(deps_subtype, &1, config[:deps_prefixes][deps_subtype])
|
||||
)
|
||||
|
||||
def deps_for(type, deps \\ deps()) do
|
||||
deps(deps, type)
|
||||
|> Enum.map(&dep_name/1)
|
||||
end
|
||||
|
||||
def deps do
|
||||
if function_exported?(Mix.Project, :config, 0),
|
||||
do: Mix.Project.config()[:deps],
|
||||
else: Bonfire.Application.deps()
|
||||
end
|
||||
|
||||
def mix_config do
|
||||
if function_exported?(Mix.Project, :config, 0),
|
||||
do: Mix.Project.config(),
|
||||
else: Bonfire.Application.config()
|
||||
end
|
||||
|
||||
def multirepo_prefixes(config \\ mix_config()),
|
||||
do:
|
||||
List.wrap(config[:deps_prefixes] || mix_config()[:deps_prefixes])
|
||||
|> Enum.flat_map(fn {_, list} -> list || [] end)
|
||||
|> Enum.uniq()
|
||||
|
||||
def in_multirepo?(dep, deps_prefixes \\ multirepo_prefixes()),
|
||||
do: include_dep?(:bonfire, dep, deps_prefixes)
|
||||
|
||||
def deps_recompile(deps \\ deps_for(:bonfire)),
|
||||
do: Mix.Task.run("bonfire.dep.compile", ["--force"] ++ List.wrap(deps))
|
||||
|
||||
# def flavour_path(path) when is_binary(path), do: path
|
||||
def flavour_path(config),
|
||||
do: System.get_env("FLAVOUR_PATH", "flavours/" <> flavour(config))
|
||||
|
||||
def flavour(config \\ mix_config())
|
||||
|
||||
def flavour(default_flavour) when is_binary(default_flavour),
|
||||
do: System.get_env("FLAVOUR") || default_flavour
|
||||
|
||||
def flavour(config), do: System.get_env("FLAVOUR") || config[:default_flavour]
|
||||
|
||||
def config_path(config_or_flavour, filename),
|
||||
do: Path.expand(Path.join([flavour_path(config_or_flavour), "config", filename]))
|
||||
|
||||
def forks_path(), do: System.get_env("FORKS_PATH", "extensions/")
|
||||
|
||||
def mess_sources(config_or_flavour) do
|
||||
do_mess_sources(System.get_env("WITH_FORKS", "1"))
|
||||
|> Enum.map(fn {k, v} -> {k, config_path(config_or_flavour, v)} end)
|
||||
end
|
||||
|
||||
defp do_mess_sources("0"), do: [git: "deps.git", hex: "deps.hex"]
|
||||
|
||||
defp do_mess_sources(_),
|
||||
do: [path: "deps.path", git: "deps.git", hex: "deps.hex"]
|
||||
|
||||
def deps_to_clean(deps, type) do
|
||||
deps(deps, type)
|
||||
|> deps_names()
|
||||
end
|
||||
|
||||
def deps_to_update(config) do
|
||||
deps(config, :update)
|
||||
|> deps_names()
|
||||
|> IO.inspect(
|
||||
label:
|
||||
"Running Bonfire #{version(config)} with configuration from #{flavour_path(config)} in #{Mix.env()} environment. You can run `just mix bonfire.deps.update` to update these extensions and dependencies"
|
||||
)
|
||||
end
|
||||
|
||||
# Specifies which paths to include in docs
|
||||
|
||||
def beam_paths(deps, type \\ :all) do
|
||||
build = Mix.Project.build_path()
|
||||
|
||||
([:bonfire] ++ deps(deps, type))
|
||||
|> Enum.map(&beam_path(&1, build))
|
||||
end
|
||||
|
||||
defp beam_path(app, build),
|
||||
do: Path.join([build, "lib", dep_name(app), "ebin"])
|
||||
|
||||
def readme_paths(config),
|
||||
do:
|
||||
List.wrap(config[:guides]) ++
|
||||
Enum.map(Path.wildcard("flavours/*/README.md"), &flavour_readme/1) ++
|
||||
Enum.map(Path.wildcard("docs/DEPENDENCIES/*.md"), &flavour_deps_doc/1) ++
|
||||
Enum.flat_map(deps(config, :docs), &readme_path/1)
|
||||
|
||||
defp readme_path(dep) when not is_nil(dep),
|
||||
do: dep_paths(dep, "README.md") |> List.first() |> readme_path(dep)
|
||||
|
||||
defp readme_path(path, dep) when not is_nil(path),
|
||||
do: [{path |> String.to_atom(), [filename: "extension-" <> dep_name(dep)]}]
|
||||
|
||||
defp readme_path(_, _), do: []
|
||||
|
||||
def flavour_readme(path),
|
||||
do: {path |> String.to_atom(), [filename: path |> String.split("/") |> Enum.at(1)]}
|
||||
|
||||
def flavour_deps_doc(path),
|
||||
do:
|
||||
{path |> String.to_atom(),
|
||||
[
|
||||
title:
|
||||
path
|
||||
|> String.split("/")
|
||||
|> Enum.at(2)
|
||||
|> String.slice(0..-4)
|
||||
|> String.capitalize(),
|
||||
filename:
|
||||
path
|
||||
|> String.split("/")
|
||||
|> Enum.at(2)
|
||||
|> String.slice(0..-4)
|
||||
|> then(&"deps-#{&1}")
|
||||
]}
|
||||
|
||||
# [plug: "https://myserver/plug/"]
|
||||
def doc_deps(config), do: deps(config, :docs) |> Enum.map(&doc_dep/1)
|
||||
defp doc_dep(dep), do: {elem(dep, 0), "./"}
|
||||
|
||||
def source_url_pattern("deps/" <> _ = path, line),
|
||||
do: bonfire_ext_pattern(path, line)
|
||||
|
||||
def source_url_pattern("extensions/" <> _ = path, line),
|
||||
do: bonfire_ext_pattern(path, line)
|
||||
|
||||
def source_url_pattern("forks/" <> _ = path, line),
|
||||
do: bonfire_ext_pattern(path, line)
|
||||
|
||||
def source_url_pattern(path, line), do: bonfire_app_pattern(path, line)
|
||||
|
||||
def bonfire_ext_pattern(path, line),
|
||||
do:
|
||||
bonfire_ext_pattern(
|
||||
path |> String.split("/") |> Enum.at(1),
|
||||
path |> String.split("/") |> Enum.slice(2..1000) |> Enum.join("/"),
|
||||
line
|
||||
)
|
||||
|
||||
def bonfire_ext_pattern(dep, path, line),
|
||||
do:
|
||||
bonfire_app_pattern(
|
||||
"https://github.com/bonfire-networks/#{dep}/blob/main/%{path}#L%{line}",
|
||||
path,
|
||||
line
|
||||
)
|
||||
|
||||
def bonfire_app_pattern(path, line),
|
||||
do:
|
||||
bonfire_app_pattern(
|
||||
"https://github.com/bonfire-networks/bonfire-app/blob/main/%{path}#L%{line}",
|
||||
path,
|
||||
line
|
||||
)
|
||||
|
||||
def bonfire_app_pattern(pattern, path, line),
|
||||
do:
|
||||
pattern
|
||||
|> String.replace("%{path}", "#{path}")
|
||||
|> String.replace("%{line}", "#{line}")
|
||||
|
||||
# Specifies which paths to include when running tests
|
||||
def test_paths(config),
|
||||
do: ["test" | Enum.flat_map(deps(config, :test), &dep_paths(&1, "test"))]
|
||||
|
||||
# Specifies which paths to compile per environment
|
||||
def elixirc_paths(config, :test),
|
||||
do: [
|
||||
"lib",
|
||||
"test/support"
|
||||
| Enum.flat_map(deps(config, :test), &dep_paths(&1, "test/support"))
|
||||
]
|
||||
|
||||
def elixirc_paths(_, env), do: ["lib"] ++ catalogues(env)
|
||||
|
||||
def include_dep?(type, dep, config_or_prefixes)
|
||||
|
||||
def include_dep?(:update, dep, _config_or_prefixes) when is_tuple(dep),
|
||||
do: unpinned_git_dep?(dep)
|
||||
|
||||
# defp include_dep?(:docs = type, dep, deps_prefixes), do: String.starts_with?(dep_name(dep), deps_prefixes || @config[:deps_prefixes][type]) || git_dep?(dep)
|
||||
def include_dep?(type, dep, config_or_prefixes) do
|
||||
# IO.inspect(config_or_prefixes)
|
||||
String.starts_with?(
|
||||
dep_name(dep),
|
||||
config_or_prefixes[:deps_prefixes][type] || config_or_prefixes[type] || config_or_prefixes
|
||||
)
|
||||
end
|
||||
|
||||
# defp git_dep?(dep) do
|
||||
# spec = elem(dep, 1)
|
||||
# is_list(spec) && spec[:git]
|
||||
# end
|
||||
|
||||
def unpinned_git_dep?(dep) do
|
||||
spec = elem(dep, 1)
|
||||
is_list(spec) && spec[:git] && !spec[:commit]
|
||||
end
|
||||
|
||||
def dep_name(dep) when is_tuple(dep), do: elem(dep, 0) |> dep_name()
|
||||
def dep_name(dep) when is_atom(dep), do: Atom.to_string(dep)
|
||||
def dep_name(dep) when is_binary(dep), do: dep
|
||||
|
||||
def deps_names(deps) do
|
||||
deps
|
||||
|> Enum.map(&dep_name/1)
|
||||
|> Enum.join(" ")
|
||||
end
|
||||
|
||||
def dep_path(dep) when is_binary(dep) do
|
||||
path_if_exists(forks_path() <> dep) ||
|
||||
path_if_exists(
|
||||
(Mix.Project.deps_path() <> "/" <> dep)
|
||||
|> Path.expand(File.cwd!())
|
||||
) ||
|
||||
"."
|
||||
end
|
||||
|
||||
def dep_path(dep) do
|
||||
spec = elem(dep, 1)
|
||||
|
||||
path =
|
||||
if is_list(spec) && spec[:path],
|
||||
do: spec[:path],
|
||||
else:
|
||||
(Mix.Project.deps_path() <> "/" <> dep_name(dep))
|
||||
|> Path.relative_to_cwd()
|
||||
|
||||
path_if_exists(path)
|
||||
end
|
||||
|
||||
defp path_if_exists(path), do: if(File.exists?(path), do: path)
|
||||
|
||||
def dep_paths(dep, extra) when is_list(extra),
|
||||
do: Enum.flat_map(extra, &dep_paths(dep, &1))
|
||||
|
||||
def dep_paths(dep, extra) when is_binary(extra) do
|
||||
dep_path = dep_path(dep)
|
||||
|
||||
if dep_path do
|
||||
path = Path.join(dep_path, extra) |> path_if_exists()
|
||||
if path, do: [path], else: []
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def version(config) do
|
||||
config[:version]
|
||||
|> String.split("-", parts: 2)
|
||||
|> List.insert_at(1, flavour(config))
|
||||
|> Enum.join("-")
|
||||
end
|
||||
|
||||
# def compilers(:dev) do
|
||||
# [:unused] ++ compilers(nil)
|
||||
# end
|
||||
|
||||
def compilers(_) do
|
||||
Mix.compilers()
|
||||
end
|
||||
|
||||
def catalogues(_env) do
|
||||
[
|
||||
"deps/surface/priv/catalogue",
|
||||
dep_path("bonfire_ui_social") <> "/priv/catalogue"
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,103 +0,0 @@
|
|||
## About half of this code is taken from hex, therefore this whole
|
||||
## file is considered under the same license terms as hex.
|
||||
defmodule Mix.Tasks.Bonfire.Account.New do
|
||||
use Mix.Task
|
||||
|
||||
@shortdoc "Creates a new account in the database"
|
||||
|
||||
@moduledoc """
|
||||
Creates an account in the database, automatically activated
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
mix bonfire.account.new [email@address]
|
||||
```
|
||||
|
||||
You will be prompted for a password and an email if it was not provided.
|
||||
"""
|
||||
|
||||
alias Bonfire.Me.Fake
|
||||
|
||||
@spec run(OptionParser.argv()) :: :ok
|
||||
def run(args) do
|
||||
options = options(args, %{})
|
||||
Mix.Task.run("app.start")
|
||||
email = get("Enter an email address: ", :email, options, true)
|
||||
password = password("Enter a password:")
|
||||
IO.inspect(password: password)
|
||||
|
||||
Fake.fake_account!(%{
|
||||
credential: %{password: password},
|
||||
email: %{email_address: email}
|
||||
})
|
||||
end
|
||||
|
||||
defp options([], opts), do: opts
|
||||
defp options([email], opts), do: Map.put(opts, :email, email)
|
||||
|
||||
defp get(prompt, key, opts, must?) do
|
||||
case opts[key] do
|
||||
nil ->
|
||||
case IO.gets(prompt) do
|
||||
:eof ->
|
||||
raise RuntimeError, message: "EOF"
|
||||
|
||||
data when is_binary(data) ->
|
||||
get(prompt, key, Map.put(opts, key, data), must?)
|
||||
|
||||
data when is_list(data) ->
|
||||
get(prompt, key, Map.put(opts, key, to_string(data)), must?)
|
||||
end
|
||||
|
||||
data ->
|
||||
data = String.trim(data)
|
||||
|
||||
if data == "" do
|
||||
if must?,
|
||||
do: get(prompt, key, Map.delete(opts, key), must?),
|
||||
else: nil
|
||||
else
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Extracted from hex via https://dev.to/tizpuppi/password-input-in-elixir-31oo
|
||||
defp password(prompt) do
|
||||
pid = spawn_link(fn -> loop(prompt) end)
|
||||
ref = make_ref()
|
||||
password(prompt, pid, ref)
|
||||
end
|
||||
|
||||
defp password(prompt, pid, ref) do
|
||||
value = String.trim(IO.gets(prompt))
|
||||
|
||||
if String.length(value) < 10 do
|
||||
IO.puts(
|
||||
:standard_error,
|
||||
"Password too short, must be at least 10 characters long"
|
||||
)
|
||||
|
||||
password(prompt, pid, ref)
|
||||
else
|
||||
send(pid, {:done, self(), ref})
|
||||
|
||||
receive do
|
||||
{:done, ^pid, ^ref} -> value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp loop(prompt) do
|
||||
receive do
|
||||
{:done, parent, ref} ->
|
||||
send(parent, {:done, self(), ref})
|
||||
IO.write(:standard_error, "\e[2K\r")
|
||||
after
|
||||
1 ->
|
||||
IO.write(:standard_error, "\e[2K\r#{prompt}")
|
||||
loop(prompt)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
defmodule Mix.Tasks.Import2alias do
|
||||
use Mix.Task
|
||||
|
||||
@impl true
|
||||
def run(args) do
|
||||
unless Version.match?(System.version(), ">= 1.10.0-rc") do
|
||||
Mix.raise("Elixir v1.10+ is required!")
|
||||
end
|
||||
|
||||
case args do
|
||||
[module, alias] ->
|
||||
run(Module.concat([module]), Module.concat([alias]))
|
||||
|
||||
_ ->
|
||||
Mix.raise("Usage: elixir -r lib_import2alias.ex -S mix import2alias MODULE ALIAS")
|
||||
end
|
||||
end
|
||||
|
||||
defp run(module, alias) do
|
||||
{:ok, _} = Import2Alias.Server.start_link(module)
|
||||
|
||||
Code.compiler_options(parser_options: [columns: true])
|
||||
|
||||
args = ["--force", "--tracer", "Import2Alias.CallerTracer"]
|
||||
|
||||
# Mix.Task.rerun("compile.elixir", args)
|
||||
deps = Bonfire.Mixer.deps_for(:bonfire)
|
||||
# |> IO.inspect()
|
||||
|
||||
Mix.Tasks.Bonfire.Deps.Compile.try_compile(deps, args)
|
||||
|
||||
entries = Import2Alias.Server.entries()
|
||||
Import2Alias.import2alias(alias, entries)
|
||||
end
|
||||
end
|
|
@ -1,279 +0,0 @@
|
|||
defmodule Mix.Tasks.Bonfire.Deps.Compile do
|
||||
use Mix.Task
|
||||
import Untangle
|
||||
|
||||
@shortdoc "Compiles dependencies"
|
||||
|
||||
@moduledoc """
|
||||
(re)compiles dependencies.
|
||||
|
||||
This is a modified version of Elixir's `Mix.Tasks.Deps.Compile` which was needed to compile dependencies and extract localisable strings in `Mix.Tasks.Bonfire.Localise.Extract`
|
||||
|
||||
By default, compile all dependencies. A list of dependencies
|
||||
can be given compile multiple dependencies in order.
|
||||
|
||||
This task attempts to detect if the project contains one of
|
||||
the following files and act accordingly:
|
||||
|
||||
* `mix.exs` - invokes `mix compile`
|
||||
* otherwise skip
|
||||
|
||||
If a list of dependencies is given, Mix will attempt to compile
|
||||
them as is. For example, if project `a` depends on `b`, calling
|
||||
`mix deps.compile a` will compile `a` even if `b` is out of
|
||||
date. This is to allow parts of the dependency tree to be
|
||||
recompiled without propagating those changes upstream. To ensure
|
||||
`b` is included in the compilation step, pass `--include-children`.
|
||||
"""
|
||||
|
||||
import Mix.Dep, only: [available?: 1, mix?: 1]
|
||||
|
||||
@switches [include_children: :boolean, force: :boolean]
|
||||
|
||||
def force_compile(dep_or_deps, compile_args \\ []) do
|
||||
# mark deps to be recompiled (run this task)
|
||||
Mix.Tasks.Bonfire.Deps.Compile.run(["--force"] ++ List.wrap(dep_or_deps))
|
||||
|
||||
# If "compile" was never called, the reenabling is a no-op and
|
||||
# "compile.elixir" is a no-op as well (because it wasn't re-enabled after
|
||||
# running "compile"). If "compile" was already called, then running
|
||||
# "compile" is a no-op and running "compile.elixir" will work because we
|
||||
# manually re-enabled it.
|
||||
Mix.Task.reenable("compile.elixir")
|
||||
Mix.Task.run("compile", compile_args)
|
||||
Mix.Task.run("compile.elixir", compile_args)
|
||||
end
|
||||
|
||||
def try_compile(dep_or_deps, compile_args \\ []) do
|
||||
# mark deps to be recompiled (run this task)
|
||||
Mix.Tasks.Bonfire.Deps.Compile.run(["--force"] ++ List.wrap(dep_or_deps))
|
||||
|
||||
Mix.Task.rerun("compile.elixir", compile_args)
|
||||
end
|
||||
|
||||
@spec run(OptionParser.argv()) :: :ok
|
||||
def run(args) do
|
||||
unless "--no-archives-check" in args do
|
||||
Mix.Task.run("archive.check", args)
|
||||
end
|
||||
|
||||
Mix.Project.get!()
|
||||
|
||||
case OptionParser.parse(args, switches: @switches) do
|
||||
{opts, [], _} ->
|
||||
# Because this command may be invoked explicitly with
|
||||
# dep.compile, we simply try to compile any available
|
||||
# dependency.
|
||||
compile(Enum.filter(loaded_deps(), &available?/1), opts)
|
||||
|
||||
{opts, tail, _} ->
|
||||
compile(loaded_by_name(tail, [env: Mix.env()] ++ opts), opts)
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
def compile(deps, options \\ []) do
|
||||
shell = Mix.shell()
|
||||
config = Mix.Project.deps_config()
|
||||
|
||||
Mix.Task.run("deps.precompile")
|
||||
|
||||
compiled =
|
||||
Enum.map(deps, fn %Mix.Dep{app: app, status: status, opts: opts, scm: scm} = dep ->
|
||||
check_unavailable!(app, status)
|
||||
|
||||
compiled? =
|
||||
cond do
|
||||
mix?(dep) ->
|
||||
maybe_clean(dep, options)
|
||||
do_mix(dep, config)
|
||||
|
||||
true ->
|
||||
shell.error(
|
||||
"Could not compile #{inspect(app)}, no \"mix.exs\" found " <>
|
||||
"(pass :compile as an option to customize compilation, set it to \"false\" to do nothing)"
|
||||
)
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
# We should touch fetchable dependencies even if they
|
||||
# did not compile otherwise they will always be marked
|
||||
# as stale, even when there is nothing to do.
|
||||
fetchable? = touch_fetchable(scm, opts[:build])
|
||||
|
||||
compiled? and fetchable?
|
||||
end)
|
||||
|
||||
if true in compiled, do: Mix.Task.run("will_recompile"), else: :ok
|
||||
end
|
||||
|
||||
defp maybe_clean(dep, opts) do
|
||||
# If a dependency was marked as fetched or with an out of date lock
|
||||
# or missing the app file, we always compile it from scratch.
|
||||
if Keyword.get(opts, :force, false) or Mix.Dep.compilable?(dep) do
|
||||
File.rm_rf!(Path.join([Mix.Project.build_path(), "lib", Atom.to_string(dep.app)]))
|
||||
end
|
||||
end
|
||||
|
||||
defp touch_fetchable(scm, path) do
|
||||
if scm.fetchable? do
|
||||
File.mkdir_p!(path)
|
||||
File.touch!(Path.join(path, ".compile.fetch"))
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
defp check_unavailable!(app, {:unavailable, _}) do
|
||||
Mix.raise(
|
||||
"Cannot compile dependency #{inspect(app)} because " <>
|
||||
"it isn't available, run \"mix deps.get\" first"
|
||||
)
|
||||
end
|
||||
|
||||
defp check_unavailable!(_, _) do
|
||||
:ok
|
||||
end
|
||||
|
||||
defp do_mix(dep, _config) do
|
||||
Mix.Dep.in_dependency(dep, fn _ ->
|
||||
if req = old_elixir_req(Mix.Project.config()) do
|
||||
Mix.shell().error(
|
||||
"warning: the dependency #{inspect(dep.app)} requires Elixir #{inspect(req)} " <>
|
||||
"but you are running on v#{System.version()}"
|
||||
)
|
||||
end
|
||||
|
||||
Mix.shell().info("Recompiling extension #{inspect(dep.app)}")
|
||||
|
||||
try do
|
||||
# If "compile" was never called, the reenabling is a no-op and
|
||||
# "compile.elixir" is a no-op as well (because it wasn't re-enabled after
|
||||
# running "compile"). If "compile" was already called, then running
|
||||
# "compile" is a no-op and running "compile.elixir" will work because we
|
||||
# manually re-enabled it.
|
||||
Mix.Task.reenable("compile.elixir")
|
||||
Mix.Task.reenable("compile.leex")
|
||||
Mix.Task.reenable("compile.all")
|
||||
Mix.Task.reenable("compile")
|
||||
|
||||
options = [
|
||||
# "--force",
|
||||
"--no-deps-loading",
|
||||
"--no-apps-loading",
|
||||
"--no-archives-check",
|
||||
"--no-elixir-version-check",
|
||||
"--no-warnings-as-errors"
|
||||
]
|
||||
|
||||
res = Mix.Task.run("compile", options)
|
||||
|
||||
# Mix.shell.info(inspect res)
|
||||
|
||||
match?({:ok, _}, res)
|
||||
catch
|
||||
kind, reason ->
|
||||
app = dep.app
|
||||
|
||||
Mix.shell().error(
|
||||
"could not compile dependency #{inspect(app)}, \"mix compile\" failed. " <>
|
||||
"You can recompile this dependency with \"mix deps.compile #{app}\", update it " <>
|
||||
"with \"mix deps.update #{app}\" or clean it with \"mix deps.clean #{app}\""
|
||||
)
|
||||
|
||||
:erlang.raise(kind, reason, __STACKTRACE__)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp old_elixir_req(config) do
|
||||
req = config[:elixir]
|
||||
|
||||
if req && not Version.match?(System.version(), req) do
|
||||
req
|
||||
end
|
||||
end
|
||||
|
||||
defp loaded_deps() do
|
||||
if Keyword.has_key?(Mix.Dep.__info__(:functions), :cached) do
|
||||
Mix.Dep.cached()
|
||||
else
|
||||
Mix.Dep.loaded()
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Receives a list of dependency names and returns loaded `Mix.Dep`s.
|
||||
Logs a message if the dependency could not be found.
|
||||
## Exceptions
|
||||
This function raises an exception if any of the dependencies
|
||||
provided in the project are in the wrong format.
|
||||
"""
|
||||
def loaded_by_name(given, all_deps \\ nil, opts) do
|
||||
all_deps = all_deps || loaded_deps()
|
||||
# |> debug("all_deps")
|
||||
|
||||
# Ensure all apps are atoms
|
||||
apps =
|
||||
to_app_names(given)
|
||||
|> debug("deps to recompile")
|
||||
|
||||
deps =
|
||||
if opts[:include_children] do
|
||||
get_deps_with_children(all_deps, apps)
|
||||
else
|
||||
get_deps(all_deps, apps)
|
||||
end
|
||||
|
||||
Enum.each(apps, fn app ->
|
||||
unless Enum.any?(all_deps, &(&1.app == app)) do
|
||||
warn("Unknown dependency #{app} for environment #{Mix.env()}")
|
||||
end
|
||||
end)
|
||||
|
||||
deps
|
||||
end
|
||||
|
||||
defp to_app_names(given) do
|
||||
Enum.map(given, fn app ->
|
||||
if is_binary(app), do: String.to_atom(app), else: app
|
||||
end)
|
||||
end
|
||||
|
||||
defp get_deps(all_deps, apps) do
|
||||
Enum.filter(all_deps, &(&1.app in apps))
|
||||
end
|
||||
|
||||
defp get_deps_with_children(all_deps, apps) do
|
||||
deps = get_children(all_deps, apps)
|
||||
apps = deps |> Enum.map(& &1.app) |> Enum.uniq()
|
||||
get_deps(all_deps, apps)
|
||||
end
|
||||
|
||||
defp get_children(_all_deps, []), do: []
|
||||
|
||||
defp get_children(all_deps, apps) do
|
||||
# Current deps
|
||||
deps = get_deps(all_deps, apps)
|
||||
|
||||
# Children apps
|
||||
apps =
|
||||
for %{deps: children} <- deps,
|
||||
%{app: app} <- children,
|
||||
do: app
|
||||
|
||||
# Current deps + children deps
|
||||
deps ++ get_children(all_deps, apps)
|
||||
end
|
||||
|
||||
def touch_manifests() do
|
||||
# |> debug("manifests")
|
||||
Enum.map(Mix.Tasks.Compile.Elixir.manifests(), &make_old_if_exists/1)
|
||||
end
|
||||
|
||||
defp make_old_if_exists(path) do
|
||||
:file.change_time(path, {{2000, 1, 1}, {0, 0, 0}})
|
||||
end
|
||||
end
|
|
@ -1,109 +0,0 @@
|
|||
defmodule Mix.Tasks.Docs.Deps do
|
||||
use Mix.Task
|
||||
|
||||
@shortdoc "Generates docs for your app and its all deps"
|
||||
@recursive true
|
||||
@root Bonfire.Common.Config.get(:root_path)
|
||||
|
||||
@moduledoc """
|
||||
`mix docs.deps`
|
||||
|
||||
## Command line options
|
||||
* `--only` - the environment to include dependencies for
|
||||
* `--target` - the target to include dependencies for
|
||||
* `--exclude` - exclude dependencies which you do not want to see in docs.
|
||||
* any arguments supported by `mix docs` will be passed along
|
||||
"""
|
||||
@switches [only: :string, target: :string, exclude: :keep]
|
||||
|
||||
@impl true
|
||||
def run(args) do
|
||||
Mix.Project.get!()
|
||||
{opts, args, _} = OptionParser.parse(args, switches: @switches)
|
||||
|
||||
deps_opts =
|
||||
for {switch, key} <- [only: :env, target: :target],
|
||||
value = opts[switch],
|
||||
do: {key, :"#{value}"}
|
||||
|
||||
excluded = Keyword.get_values(opts, :exclude)
|
||||
|
||||
deps =
|
||||
Mix.Dep.load_on_environment(deps_opts)
|
||||
|> prepare_list(opts)
|
||||
|> List.flatten()
|
||||
|> Enum.reject(&(Atom.to_string(dep_name(&1)) in excluded))
|
||||
|> Enum.uniq_by(&dep_name(&1))
|
||||
|
||||
config = Mix.Project.config()
|
||||
build_path = Mix.Project.build_path()
|
||||
|
||||
docs_config = Keyword.get(config, :docs, [])
|
||||
|
||||
docs_config =
|
||||
docs_config
|
||||
|> Keyword.put(:deps, Enum.map(deps, &{dep_name(&1), "./"}))
|
||||
|> Keyword.put(
|
||||
:source_beam,
|
||||
Enum.map(
|
||||
deps,
|
||||
&Path.join([build_path, "lib", Atom.to_string(dep_name(&1)), "ebin"])
|
||||
)
|
||||
)
|
||||
|> Keyword.put(
|
||||
:extras,
|
||||
Keyword.get(docs_config, :extras, []) ++
|
||||
Enum.flat_map(deps, &readme_path/1)
|
||||
)
|
||||
|
||||
Mix.Tasks.Docs.run(args, Keyword.put(config, :docs, docs_config))
|
||||
end
|
||||
|
||||
defp prepare_list(deps, opts) when is_list(deps) do
|
||||
Enum.flat_map(deps, fn
|
||||
%Mix.Dep{deps: nested_deps} = dep ->
|
||||
[dep] ++ prepare_list(nested_deps, opts)
|
||||
|
||||
dep ->
|
||||
[dep]
|
||||
end)
|
||||
end
|
||||
|
||||
defp readme_path(dep) when not is_nil(dep),
|
||||
do: dep_paths(dep, "README.md") |> List.first() |> readme_path(dep)
|
||||
|
||||
defp readme_path(path, dep) when not is_nil(path),
|
||||
do: [{String.to_atom(path), [filename: "extension-#{dep_name(dep)}"]}]
|
||||
|
||||
defp readme_path(_, _), do: []
|
||||
|
||||
defp dep_path(dep) do
|
||||
path =
|
||||
if is_list(dep) && dep[:path],
|
||||
do: dep[:path],
|
||||
else: (Mix.Project.deps_path() <> "/#{dep_name(dep)}") |> Path.expand(@root)
|
||||
|
||||
path_if_exists(path)
|
||||
end
|
||||
|
||||
defp dep_paths(dep, extra) when is_list(extra),
|
||||
do: Enum.flat_map(extra, &dep_paths(dep, &1))
|
||||
|
||||
defp dep_paths(dep, extra) when is_binary(extra) do
|
||||
dep_path = dep_path(dep)
|
||||
|
||||
if dep_path do
|
||||
path = Path.join(dep_path, extra) |> path_if_exists()
|
||||
if path, do: [path], else: []
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
defp dep_name(%Mix.Dep{app: dep}) when is_atom(dep), do: dep
|
||||
defp dep_name(dep) when is_tuple(dep), do: elem(dep, 0) |> dep_name()
|
||||
defp dep_name(dep) when is_atom(dep), do: dep
|
||||
defp dep_name(dep) when is_binary(dep), do: dep
|
||||
|
||||
defp path_if_exists(path), do: if(File.exists?(path), do: path)
|
||||
end
|
|
@ -1,99 +0,0 @@
|
|||
defmodule Mix.Tasks.Bonfire.Localise.Extract do
|
||||
use Mix.Task
|
||||
import Untangle
|
||||
@recursive true
|
||||
|
||||
@shortdoc "Extracts translations from source code"
|
||||
|
||||
@moduledoc """
|
||||
Extracts translations by recompiling the Elixir source code.
|
||||
|
||||
mix gettext.extract [OPTIONS]
|
||||
|
||||
Translations are extracted into POT (Portable Object Template) files (with a
|
||||
`.pot` extension). The location of these files is determined by the `:otp_app`
|
||||
and `:priv` options given by Gettext modules when they call `use Gettext`. One
|
||||
POT file is generated for each translation domain.
|
||||
|
||||
It is possible to give the `--merge` option to perform merging
|
||||
for every Gettext backend updated during merge:
|
||||
|
||||
mix gettext.extract --merge
|
||||
|
||||
All other options passed to `gettext.extract` are forwarded to the
|
||||
`gettext.merge` task (`Mix.Tasks.Gettext.Merge`), which is called internally
|
||||
by this task. For example:
|
||||
|
||||
mix gettext.extract --merge --no-fuzzy
|
||||
|
||||
"""
|
||||
|
||||
@switches [merge: :boolean]
|
||||
|
||||
def run(args) do
|
||||
Application.ensure_all_started(:gettext)
|
||||
_ = Mix.Project.get!()
|
||||
mix_config = Mix.Project.config()
|
||||
{opts, _} = OptionParser.parse!(args, switches: @switches)
|
||||
|
||||
gettext_config =
|
||||
(mix_config[:gettext] || [])
|
||||
|> debug("gettext config")
|
||||
|
||||
exts_to_localise =
|
||||
Bonfire.Mixer.deps_for(:localise)
|
||||
|> debug("bonfire extensions to localise")
|
||||
|
||||
deps_to_localise =
|
||||
Bonfire.Mixer.deps_for(:localise_self)
|
||||
|> debug("other deps to localise")
|
||||
|
||||
Mix.Tasks.Bonfire.Deps.Compile.touch_manifests()
|
||||
|
||||
# first extract strings from all deps that use the Gettext module in bonfire_common
|
||||
pot_files = extract(:bonfire_common, gettext_config, exts_to_localise)
|
||||
|
||||
# then those that have their own Gettext
|
||||
pot_files =
|
||||
Enum.reduce(deps_to_localise, pot_files, fn dep, pot_files ->
|
||||
pot_files ++ extract(String.to_atom(dep), gettext_config, dep)
|
||||
end)
|
||||
|
||||
# pot_files |> debug("extracted pot_files")
|
||||
|
||||
for {path, contents} <- pot_files do
|
||||
File.mkdir_p!(Path.dirname(path))
|
||||
File.write!(path, contents)
|
||||
info("Extracted strings to #{Path.relative_to_cwd(path)}")
|
||||
end
|
||||
|
||||
if opts[:merge] do
|
||||
run_merge(pot_files, args)
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
defp extract(app, gettext_config, deps_to_localise) do
|
||||
Gettext.Extractor.enable()
|
||||
|
||||
Mix.Tasks.Bonfire.Deps.Compile.force_compile(deps_to_localise)
|
||||
|
||||
Gettext.Extractor.pot_files(
|
||||
app,
|
||||
gettext_config
|
||||
)
|
||||
after
|
||||
Gettext.Extractor.disable()
|
||||
end
|
||||
|
||||
defp run_merge(pot_files, argv) do
|
||||
pot_files
|
||||
|> Enum.map(fn {path, _} -> Path.dirname(path) end)
|
||||
|> Enum.uniq()
|
||||
|> Task.async_stream(&Mix.Tasks.Gettext.Merge.run([&1 | argv]),
|
||||
ordered: false
|
||||
)
|
||||
|> Stream.run()
|
||||
end
|
||||
end
|
30
lib/mix/tasks/release/.gitignore
vendored
30
lib/mix/tasks/release/.gitignore
vendored
|
@ -1,30 +0,0 @@
|
|||
# The directory Mix will write compiled artifacts to.
|
||||
/_build/
|
||||
|
||||
# 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").
|
||||
release-*.tar
|
||||
|
||||
|
||||
# Temporary files for e.g. tests
|
||||
/tmp
|
||||
|
||||
# The build
|
||||
release
|
|
@ -1,166 +0,0 @@
|
|||
defmodule Releaser.VersionUtils do
|
||||
@doc """
|
||||
Some utilities to get and set version numbers in the `mix.exs` file
|
||||
and to programmatically transform version numbers.
|
||||
Maybe the `bump_*` functions should be in the standard library?
|
||||
This script doesn't support pre-release versions or versions with build information.
|
||||
"""
|
||||
@version_line_regex ~r/(\n\s*version:\s+")([^\n]+)(")/
|
||||
|
||||
def bump_major(%Version{} = version) do
|
||||
%{version | major: version.major + 1, minor: 0, patch: 0}
|
||||
end
|
||||
|
||||
def bump_minor(%Version{} = version) do
|
||||
%{version | minor: version.minor + 1, patch: 0}
|
||||
end
|
||||
|
||||
def bump_patch(%Version{} = version) do
|
||||
%{version | patch: version.patch + 1}
|
||||
end
|
||||
|
||||
def bump_pre(%Version{} = version, pre_label) do
|
||||
IO.inspect(old_pre: version.pre)
|
||||
|
||||
new_pre =
|
||||
if is_list(version.pre) and List.first(version.pre) == pre_label do
|
||||
[pre_label, List.last(version.pre) + 1]
|
||||
else
|
||||
[pre_label, 1]
|
||||
end
|
||||
|
||||
%{version | pre: new_pre}
|
||||
end
|
||||
|
||||
def version_to_string(%Version{
|
||||
major: major,
|
||||
minor: minor,
|
||||
patch: patch,
|
||||
pre: pre
|
||||
})
|
||||
when is_list(pre) and length(pre) > 0 do
|
||||
"#{major}.#{minor}.#{patch}-" <> Enum.join(pre, ".")
|
||||
end
|
||||
|
||||
def version_to_string(%Version{major: major, minor: minor, patch: patch}) do
|
||||
"#{major}.#{minor}.#{patch}"
|
||||
end
|
||||
|
||||
def get_version(mix_path \\ ".") do
|
||||
version =
|
||||
if Code.ensure_loaded?(Mix.Project) do
|
||||
Mix.Project.config()[:version]
|
||||
else
|
||||
contents = File.read!(mix_path <> "/mix.exs")
|
||||
Regex.run(@version_line_regex, contents) |> Enum.fetch!(2)
|
||||
end
|
||||
|> IO.inspect()
|
||||
|
||||
Version.parse!(version)
|
||||
end
|
||||
|
||||
def set_version(version, mix_path \\ ".") do
|
||||
contents = File.read!(mix_path <> "/mix.exs")
|
||||
version_string = version_to_string(version)
|
||||
|
||||
replaced =
|
||||
Regex.replace(@version_line_regex, contents, fn _, pre, _version, post ->
|
||||
"#{pre}#{version_string}#{post}"
|
||||
end)
|
||||
|
||||
File.write!(mix_path <> "/mix.exs", replaced)
|
||||
end
|
||||
|
||||
def update_version(%Version{} = version, "major"), do: bump_major(version)
|
||||
def update_version(%Version{} = version, "minor"), do: bump_minor(version)
|
||||
def update_version(%Version{} = version, "patch"), do: bump_patch(version)
|
||||
|
||||
def update_version(%Version{} = version, "alpha" = pre_label),
|
||||
do: bump_pre(version, pre_label)
|
||||
|
||||
def update_version(%Version{} = version, "beta" = pre_label),
|
||||
do: bump_pre(version, pre_label)
|
||||
|
||||
def update_version(%Version{} = _version, type),
|
||||
do: raise("Invalid version type: #{type}")
|
||||
end
|
||||
|
||||
defmodule Releaser.Git do
|
||||
@doc """
|
||||
This module contains some git-specific functionality
|
||||
"""
|
||||
alias Releaser.VersionUtils
|
||||
|
||||
def add_commit_and_tag(version) do
|
||||
version_string = VersionUtils.version_to_string(version)
|
||||
Mix.Shell.IO.cmd("git add .", [])
|
||||
Mix.Shell.IO.cmd(~s'git commit -m "Bumped version number"')
|
||||
|
||||
Mix.Shell.IO.cmd(~s'git tag -a v#{version_string} -m "Version #{version_string}"')
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Releaser.Tests do
|
||||
def run_tests!() do
|
||||
error_code = Mix.Shell.IO.cmd("mix test", [])
|
||||
|
||||
if error_code != 0 do
|
||||
raise "This version can't be released because tests are failing."
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Releaser.Publish do
|
||||
def publish!() do
|
||||
error_code = Mix.Shell.IO.cmd("mix hex.publish", [])
|
||||
|
||||
if error_code != 0 do
|
||||
raise "Couldn't publish package on hex."
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Mix.Tasks.Bonfire.Release do
|
||||
alias Releaser.VersionUtils
|
||||
|
||||
# for running as escript
|
||||
def main(args) do
|
||||
run(args)
|
||||
end
|
||||
|
||||
# when running as Mix task
|
||||
def run(args) do
|
||||
mix_path = if is_list(args) and length(args) > 0, do: List.first(args), else: "."
|
||||
|
||||
# TODO make the default configurable
|
||||
release_type = if is_list(args) and length(args) > 1, do: List.last(args), else: "alpha"
|
||||
|
||||
IO.inspect(release_type: release_type)
|
||||
|
||||
# Run the tests before generating the release.
|
||||
# If any test fails, stop.
|
||||
# Tests.run_tests!()
|
||||
|
||||
# Get the current version from the mix.exs file.
|
||||
old_version = VersionUtils.get_version(mix_path)
|
||||
IO.inspect(old_version: old_version)
|
||||
|
||||
new_version = VersionUtils.update_version(old_version, release_type)
|
||||
IO.inspect(new_version: VersionUtils.version_to_string(new_version))
|
||||
|
||||
# Set a new version on the mix.exs file
|
||||
VersionUtils.set_version(new_version, mix_path)
|
||||
|
||||
# Commit the changes and ad a new 'v*.*.*' tag
|
||||
# Git.add_commit_and_tag(new_version)
|
||||
|
||||
# Try to publish the package on hex.
|
||||
# If this fails, we don't want to run all the code above,
|
||||
# so you should run `mix hex.publish" again manually to try to solve the problem
|
||||
# Publish.publish!()
|
||||
end
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
defmodule Bonfire.Release do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :release,
|
||||
version: "0.1.0-alpha.1",
|
||||
elixir: "~> 1.11",
|
||||
escript: [main_module: Mix.Tasks.Bonfire.Release]
|
||||
]
|
||||
end
|
||||
end
|
30
lib/mix/tasks/secrets/.gitignore
vendored
30
lib/mix/tasks/secrets/.gitignore
vendored
|
@ -1,30 +0,0 @@
|
|||
# The directory Mix will write compiled artifacts to.
|
||||
/_build/
|
||||
|
||||
# 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").
|
||||
release-*.tar
|
||||
|
||||
|
||||
# Temporary files for e.g. tests
|
||||
/tmp
|
||||
|
||||
# The build
|
||||
secrets
|
|
@ -1,45 +0,0 @@
|
|||
defmodule Mix.Tasks.Bonfire.Secrets do
|
||||
@shortdoc "Generates some secrets"
|
||||
|
||||
@moduledoc """
|
||||
Generates secrets and prints to the terminal.
|
||||
mix secrets [length]
|
||||
By default, it generates keys 64 characters long.
|
||||
The minimum value for `length` is 32.
|
||||
"""
|
||||
use Mix.Task
|
||||
|
||||
# for running as escript
|
||||
def main(args) do
|
||||
run(args)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def run([]), do: run(["64"])
|
||||
|
||||
def run([int]),
|
||||
do: int |> parse!() |> random_string() |> Kernel.<>("\r\n") |> IO.puts()
|
||||
|
||||
def run([int, iterate]), do: for(_ <- 1..parse!(iterate), do: run([int]))
|
||||
def run(args), do: invalid_args!(args)
|
||||
|
||||
defp parse!(int) do
|
||||
case Integer.parse(int) do
|
||||
{int, ""} -> int
|
||||
_ -> invalid_args!(int)
|
||||
end
|
||||
end
|
||||
|
||||
defp random_string(length) when length > 31 do
|
||||
:crypto.strong_rand_bytes(length)
|
||||
|> Base.encode64()
|
||||
|> binary_part(0, length)
|
||||
end
|
||||
|
||||
defp random_string(_),
|
||||
do: raise("Secrets should be at least 32 characters long")
|
||||
|
||||
defp invalid_args!(args) do
|
||||
raise "Expected a length as integer or no argument at all, got #{inspect(args)}"
|
||||
end
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
defmodule Bonfire.Secrets do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :secrets,
|
||||
version: "0.1.0-alpha.1",
|
||||
elixir: "~> 1.11",
|
||||
escript: [main_module: Mix.Tasks.Bonfire.Secrets]
|
||||
]
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
## About half of this code is taken from hex, therefore this whole
|
||||
## file is considered under the same license terms as hex.
|
||||
defmodule Mix.Tasks.Bonfire.User.Admin.Promote do
|
||||
use Mix.Task
|
||||
|
||||
@shortdoc "Promotes a user to an administrator"
|
||||
|
||||
@moduledoc """
|
||||
Creates an account in the database, automatically activated
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
mix bonfire.user.admin.promote username
|
||||
```
|
||||
"""
|
||||
|
||||
alias Bonfire.Me.Users
|
||||
|
||||
@spec run(OptionParser.argv()) :: :ok
|
||||
def run(args) do
|
||||
options = options(args, %{})
|
||||
Mix.Task.run("app.start")
|
||||
|
||||
case Users.by_username!(options.username) do
|
||||
nil ->
|
||||
raise RuntimeError, message: "User not found"
|
||||
|
||||
user ->
|
||||
Users.make_admin(user)
|
||||
end
|
||||
end
|
||||
|
||||
defp options([username], opts), do: Map.put(opts, :username, username)
|
||||
end
|
Loading…
Reference in a new issue