Skip to content

Commit 11ed48d

Browse files
authored
feat: add igniter installer (#71)
1 parent 388c021 commit 11ed48d

12 files changed

+279
-32
lines changed

README.md

+19-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,25 @@ word lists `feat(Something Special, Something Else Special): message`. Keep in
3535
mind that you are very limited on space in these messages, and if you find
3636
yourself using multiple scopes your commit is probably too big.
3737

38-
## Installation
38+
## Installation with Igniter
39+
40+
If `Igniter` is not already in your project, add it to your deps:
41+
42+
```elixir
43+
def deps do
44+
[
45+
{:igniter, "~> 0.5", only: [:dev, :test]}
46+
]
47+
end
48+
```
49+
50+
Then, run the installer:
51+
52+
```sh
53+
mix igniter.install git_ops
54+
```
55+
56+
## Manual Installation
3957

4058
```elixir
4159
def deps do

lib/git_ops/changelog.ex

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ defmodule GitOps.Changelog do
7373
rest
7474
])
7575

76-
unless opts[:dry_run] do
76+
if !opts[:dry_run] do
7777
File.write!(path, new_contents)
7878
end
7979

@@ -95,7 +95,7 @@ defmodule GitOps.Changelog do
9595
raise "\nFile already exists: #{path}. Please remove it to initialize."
9696
end
9797

98-
unless opts[:dry_run] do
98+
if !opts[:dry_run] do
9999
File.write!(path, String.trim_leading(contents))
100100
end
101101

lib/git_ops/commit.ex

+5-5
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ defmodule GitOps.Commit do
119119
message: Enum.at(result[:message], 0),
120120
body: body,
121121
footer: footer,
122-
breaking?: is_breaking?(result[:breaking?], body, footer)
122+
breaking?: breaking?(result[:breaking?], body, footer)
123123
}
124124
end)
125125

@@ -143,8 +143,8 @@ defmodule GitOps.Commit do
143143
defp scopes([value]) when is_bitstring(value), do: String.split(value, ",")
144144
defp scopes(_), do: nil
145145

146-
defp is_breaking?(breaking, _, _) when not is_nil(breaking), do: true
147-
defp is_breaking?(_, "BREAKING CHANGE:" <> _, _), do: true
148-
defp is_breaking?(_, _, "BREAKING CHANGE:" <> _), do: true
149-
defp is_breaking?(_, _, _), do: false
146+
defp breaking?(breaking, _, _) when not is_nil(breaking), do: true
147+
defp breaking?(_, "BREAKING CHANGE:" <> _, _), do: true
148+
defp breaking?(_, _, "BREAKING CHANGE:" <> _), do: true
149+
defp breaking?(_, _, _), do: false
150150
end

lib/git_ops/config.ex

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ defmodule GitOps.Config do
4444
]
4545

4646
def mix_project_check(opts \\ []) do
47-
unless mix_project().project()[:version] do
47+
if !mix_project().project()[:version] do
4848
raise "mix_project must be configured in order to use git_ops. Please see the configuration in the README.md for an example."
4949
end
5050

5151
changelog_path = Path.expand(changelog_file())
5252

53-
unless opts[:initial] || File.exists?(changelog_path) do
53+
if !(opts[:initial] || File.exists?(changelog_path)) do
5454
raise "\nFile: #{changelog_path} did not exist. Please use the `--initial` command to initialize."
5555
end
5656
end

lib/git_ops/version_replace.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ defmodule GitOps.VersionReplace do
3535
if new_contents == contents do
3636
{:error, :bad_replace}
3737
else
38-
unless opts[:dry_run] do
38+
if !opts[:dry_run] do
3939
File.write!(file, new_contents)
4040
end
4141

lib/mix/tasks/git_ops.install.ex

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
defmodule Mix.Tasks.GitOps.Install.Docs do
2+
@moduledoc false
3+
4+
def short_doc do
5+
"Installs GitOps into a project."
6+
end
7+
8+
def example do
9+
"mix igniter.install git_ops"
10+
end
11+
12+
def long_doc do
13+
"""
14+
#{short_doc()}
15+
16+
## Example
17+
18+
```bash
19+
#{example()}
20+
```
21+
22+
## Switches
23+
24+
- `--no-manage-readme` - Disables mangaging the package version in the README file.
25+
- `--no-manage-mix` - Disables mangaging the package version in the `mix.exs` file.
26+
"""
27+
end
28+
end
29+
30+
if Code.ensure_loaded?(Igniter) do
31+
defmodule Mix.Tasks.GitOps.Install do
32+
@shortdoc "#{__MODULE__.Docs.short_doc()}"
33+
34+
@moduledoc __MODULE__.Docs.long_doc()
35+
36+
use Igniter.Mix.Task
37+
38+
@impl Igniter.Mix.Task
39+
def info(_argv, _composing_task) do
40+
%Igniter.Mix.Task.Info{
41+
group: :git_ops,
42+
adds_deps: [],
43+
installs: [],
44+
example: __MODULE__.Docs.example(),
45+
only: [:dev],
46+
positional: [],
47+
composes: [],
48+
schema: [
49+
manage_readme: :boolean,
50+
manage_mix: :boolean
51+
],
52+
defaults: [manage_readme: true, manage_mix: true],
53+
aliases: [],
54+
required: []
55+
}
56+
end
57+
58+
@impl Igniter.Mix.Task
59+
def igniter(igniter) do
60+
opts = igniter.args.options
61+
62+
manage_mix? = opts[:manage_mix]
63+
manage_readme? = opts[:manage_readme]
64+
65+
igniter
66+
|> Igniter.Project.Config.configure_new(
67+
"dev.exs",
68+
:git_ops,
69+
[:mix_project],
70+
{:code, Sourceror.parse_string!("Mix.Project.get!()")}
71+
)
72+
|> Igniter.Project.Config.configure_new("dev.exs", :git_ops, [:types],
73+
types: [tidbit: [hidden?: true], important: [header: "Important Changes"]]
74+
)
75+
|> Igniter.Project.Config.configure_new("dev.exs", :git_ops, [:version_tag_prefix], "v")
76+
|> then(fn igniter ->
77+
igniter =
78+
if manage_mix? do
79+
Igniter.Project.MixProject.update(igniter, :project, [:version], fn zipper ->
80+
version = zipper.node
81+
82+
zipper
83+
|> Igniter.Code.Common.replace_code("@version")
84+
|> Sourceror.Zipper.top()
85+
|> Sourceror.Zipper.move_to_cursor("""
86+
defmodule __ do
87+
use __
88+
__cursor__()
89+
end
90+
""")
91+
|> Igniter.Code.Common.add_code("@version \"#{version}\"", placement: :before)
92+
end)
93+
else
94+
igniter
95+
end
96+
97+
igniter
98+
|> Igniter.Project.Config.configure(
99+
"dev.exs",
100+
:git_ops,
101+
[:manage_mix_verions?],
102+
manage_mix?
103+
)
104+
end)
105+
|> Igniter.Project.Config.configure(
106+
"dev.exs",
107+
:git_ops,
108+
[:manage_readme_version],
109+
manage_readme?
110+
)
111+
|> Igniter.Project.Config.configure_new(
112+
"dev.exs",
113+
:git_ops,
114+
[:mix_project],
115+
Sourceror.parse_string!("Mix.Project.get!()")
116+
)
117+
|> Igniter.add_notice("""
118+
GitOps has been installed. To create the first release:
119+
120+
mix git_ops.release --initial
121+
122+
On subsequent releases, use:
123+
124+
mix git_ops.release
125+
126+
""")
127+
end
128+
end
129+
else
130+
defmodule Mix.Tasks.GitOps.Install do
131+
@shortdoc "#{__MODULE__.Docs.short_doc()} | Install `igniter` to use"
132+
133+
@moduledoc __MODULE__.Docs.long_doc()
134+
135+
use Mix.Task
136+
137+
def run(_argv) do
138+
Mix.shell().error("""
139+
The task 'git_ops.install' requires igniter. Please install igniter and try again.
140+
141+
For more information, see: https://hexdocs.pm/igniter/readme.html#installation
142+
""")
143+
144+
exit({:shutdown, 1})
145+
end
146+
end
147+
end

mix.exs

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ defmodule GitOps.MixProject do
7070
{:ex_doc, "~> 0.19", only: :dev, runtime: false},
7171
{:excoveralls, "~> 0.6", only: :test},
7272
{:git_cli, "~> 0.2"},
73+
{:igniter, "~> 0.5", optional: true},
7374
{:nimble_parsec, "~> 1.0"}
7475
]
7576
end

0 commit comments

Comments
 (0)