milestoner 16.2.1 → 17.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -1
- data/README.adoc +333 -57
- data/lib/milestoner/builders/ascii_doc.rb +32 -0
- data/lib/milestoner/builders/container.rb +17 -0
- data/lib/milestoner/builders/import.rb +9 -0
- data/lib/milestoner/builders/markdown.rb +32 -0
- data/lib/milestoner/builders/stream.rb +29 -0
- data/lib/milestoner/builders/web.rb +41 -0
- data/lib/milestoner/cli/actions/build/format.rb +24 -0
- data/lib/milestoner/cli/actions/build/label.rb +26 -0
- data/lib/milestoner/cli/actions/build/layout.rb +36 -0
- data/lib/milestoner/cli/actions/build/root.rb +25 -0
- data/lib/milestoner/cli/actions/build/version.rb +31 -0
- data/lib/milestoner/cli/actions/cache/create.rb +35 -0
- data/lib/milestoner/cli/actions/cache/delete.rb +31 -0
- data/lib/milestoner/cli/actions/cache/find.rb +31 -0
- data/lib/milestoner/cli/actions/cache/info.rb +29 -0
- data/lib/milestoner/cli/actions/cache/list.rb +33 -0
- data/lib/milestoner/cli/actions/publish.rb +9 -5
- data/lib/milestoner/cli/commands/build.rb +60 -0
- data/lib/milestoner/cli/commands/cache.rb +27 -0
- data/lib/milestoner/cli/shell.rb +3 -2
- data/lib/milestoner/commits/categorizer.rb +21 -29
- data/lib/milestoner/commits/collector.rb +18 -0
- data/lib/milestoner/commits/enricher.rb +51 -0
- data/lib/milestoner/commits/enrichers/author.rb +26 -0
- data/lib/milestoner/commits/enrichers/body.rb +28 -0
- data/lib/milestoner/commits/enrichers/colleague.rb +33 -0
- data/lib/milestoner/commits/enrichers/container.rb +25 -0
- data/lib/milestoner/commits/enrichers/format.rb +23 -0
- data/lib/milestoner/commits/enrichers/import.rb +11 -0
- data/lib/milestoner/commits/enrichers/issue.rb +28 -0
- data/lib/milestoner/commits/enrichers/milestone.rb +24 -0
- data/lib/milestoner/commits/enrichers/note.rb +28 -0
- data/lib/milestoner/commits/enrichers/review.rb +23 -0
- data/lib/milestoner/commits/enrichers/uri.rb +14 -0
- data/lib/milestoner/commits/versioner.rb +48 -0
- data/lib/milestoner/configuration/contract.rb +30 -3
- data/lib/milestoner/configuration/defaults.yml +31 -8
- data/lib/milestoner/configuration/model.rb +26 -1
- data/lib/milestoner/configuration/transformers/build/root.rb +21 -0
- data/lib/milestoner/configuration/transformers/build/template_paths.rb +32 -0
- data/lib/milestoner/configuration/transformers/citations/description.rb +39 -0
- data/lib/milestoner/configuration/transformers/citations/label.rb +39 -0
- data/lib/milestoner/configuration/transformers/gems/description.rb +34 -0
- data/lib/milestoner/configuration/transformers/gems/label.rb +35 -0
- data/lib/milestoner/configuration/transformers/gems/name.rb +34 -0
- data/lib/milestoner/configuration/transformers/gems/uri.rb +35 -0
- data/lib/milestoner/configuration/transformers/generator/label.rb +31 -0
- data/lib/milestoner/configuration/transformers/generator/uri.rb +31 -0
- data/lib/milestoner/configuration/transformers/project/author.rb +34 -0
- data/lib/milestoner/configuration/transformers/project/generator.rb +35 -0
- data/lib/milestoner/configuration/transformers/project/label.rb +23 -0
- data/lib/milestoner/configuration/transformers/project/name.rb +21 -0
- data/lib/milestoner/configuration/transformers/project/version.rb +33 -0
- data/lib/milestoner/configuration/transformers/uri/avatar.rb +21 -0
- data/lib/milestoner/configuration/transformers/uri/commit.rb +24 -0
- data/lib/milestoner/configuration/transformers/uri/profile.rb +21 -0
- data/lib/milestoner/configuration/transformers/uri/review.rb +24 -0
- data/lib/milestoner/configuration/transformers/uri/tracker.rb +24 -0
- data/lib/milestoner/container.rb +52 -9
- data/lib/milestoner/models/commit.rb +42 -0
- data/lib/milestoner/models/link.rb +12 -0
- data/lib/milestoner/models/user.rb +12 -0
- data/lib/milestoner/renderers/asciidoc.rb +20 -0
- data/lib/milestoner/renderers/markdown.rb +20 -0
- data/lib/milestoner/renderers/universal.rb +26 -0
- data/lib/milestoner/tags/creator.rb +31 -23
- data/lib/milestoner/tags/publisher.rb +5 -5
- data/lib/milestoner/tags/pusher.rb +9 -3
- data/lib/milestoner/templates/layouts/page.adoc.erb +2 -0
- data/lib/milestoner/templates/layouts/page.html.erb +37 -0
- data/lib/milestoner/templates/layouts/page.md.erb +2 -0
- data/lib/milestoner/templates/layouts/page.stream.erb +2 -0
- data/lib/milestoner/templates/milestones/_avatar.html.erb +5 -0
- data/lib/milestoner/templates/milestones/_commit.adoc.erb +1 -0
- data/lib/milestoner/templates/milestones/_commit.html.erb +104 -0
- data/lib/milestoner/templates/milestones/_commit.md.erb +1 -0
- data/lib/milestoner/templates/milestones/_commit.stream.erb +1 -0
- data/lib/milestoner/templates/milestones/_icon.html.erb +6 -0
- data/lib/milestoner/templates/milestones/_profile.html.erb +5 -0
- data/lib/milestoner/templates/milestones/show.adoc.erb +9 -0
- data/lib/milestoner/templates/milestones/show.html.erb +46 -0
- data/lib/milestoner/templates/milestones/show.md.erb +9 -0
- data/lib/milestoner/templates/milestones/show.stream.erb +9 -0
- data/lib/milestoner/templates/public/page.css.erb +373 -0
- data/lib/milestoner/views/context.rb +27 -0
- data/lib/milestoner/views/milestones/show.rb +47 -0
- data/lib/milestoner/views/parts/commit.rb +85 -0
- data/lib/milestoner.rb +1 -1
- data/milestoner.gemspec +17 -11
- data.tar.gz.sig +0 -0
- metadata +182 -26
- metadata.gz.sig +1 -1
- data/lib/milestoner/cli/actions/status.rb +0 -37
- data/lib/milestoner/presenters/commit.rb +0 -36
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "refinements/hash"
|
5
|
+
|
6
|
+
module Milestoner
|
7
|
+
module Configuration
|
8
|
+
module Transformers
|
9
|
+
module Project
|
10
|
+
# Conditionally updates author based on Git user.
|
11
|
+
class Author
|
12
|
+
include Import[:git]
|
13
|
+
include Dry::Monads[:result]
|
14
|
+
|
15
|
+
using Refinements::Hash
|
16
|
+
|
17
|
+
def initialize(key = :project_author, **)
|
18
|
+
@key = key
|
19
|
+
super(**)
|
20
|
+
end
|
21
|
+
|
22
|
+
def call content
|
23
|
+
content.fetch_value(key) { git.get("user.name", nil).value_or(nil) }
|
24
|
+
.then { |value| Success content.merge!(key => value) }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :key
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
|
5
|
+
module Milestoner
|
6
|
+
module Configuration
|
7
|
+
module Transformers
|
8
|
+
module Project
|
9
|
+
# Conditionally updates generator based on gem specification.
|
10
|
+
class Generator
|
11
|
+
include Import[:specification]
|
12
|
+
include Dry::Monads[:result]
|
13
|
+
|
14
|
+
def initialize(key = :project_generator, **)
|
15
|
+
@key = key
|
16
|
+
super(**)
|
17
|
+
end
|
18
|
+
|
19
|
+
def call content
|
20
|
+
warn "`#{self.class}##{__method__}` is deprecated, use " \
|
21
|
+
"`Milestoner::Configuration::Transformers::Generator::Label` or " \
|
22
|
+
"`Milestoner::Configuration::Transformers::Generator::URI` instead.",
|
23
|
+
category: :deprecated
|
24
|
+
|
25
|
+
Success({key => specification.labeled_version}.merge!(content))
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :key
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "pathname"
|
5
|
+
require "refinements/hash"
|
6
|
+
require "refinements/string"
|
7
|
+
|
8
|
+
module Milestoner
|
9
|
+
module Configuration
|
10
|
+
module Transformers
|
11
|
+
# Conditionally updates label based on current directory.
|
12
|
+
module Project
|
13
|
+
using Refinements::String
|
14
|
+
using Refinements::Hash
|
15
|
+
|
16
|
+
Label = lambda do |content, key = :project_label, default: Pathname.pwd.basename.to_s|
|
17
|
+
content.fetch_value(key) { default }
|
18
|
+
.then { |value| Dry::Monads::Success content.merge!(key => value.titleize) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "pathname"
|
5
|
+
require "refinements/hash"
|
6
|
+
|
7
|
+
module Milestoner
|
8
|
+
module Configuration
|
9
|
+
module Transformers
|
10
|
+
# Conditionally updates name based on current directory.
|
11
|
+
module Project
|
12
|
+
using Refinements::Hash
|
13
|
+
|
14
|
+
Name = lambda do |content, key = :project_name, default: Pathname.pwd.basename.to_s|
|
15
|
+
content.fetch_value(key) { default }
|
16
|
+
.then { |value| Dry::Monads::Success content.merge!(key => value) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "refinements/hash"
|
5
|
+
|
6
|
+
module Milestoner
|
7
|
+
module Configuration
|
8
|
+
module Transformers
|
9
|
+
module Project
|
10
|
+
# Conditionally updates version based on last Git tag.
|
11
|
+
class Version
|
12
|
+
include Dry::Monads[:result]
|
13
|
+
|
14
|
+
using Refinements::Hash
|
15
|
+
|
16
|
+
def initialize key = :project_version, versioner: Commits::Versioner.new
|
17
|
+
@key = key
|
18
|
+
@versioner = versioner
|
19
|
+
end
|
20
|
+
|
21
|
+
def call content
|
22
|
+
content.fetch_value(key) { versioner.call }
|
23
|
+
.then { |value| Success content.merge!(key => value) }
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :key, :versioner
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "pathname"
|
5
|
+
|
6
|
+
module Milestoner
|
7
|
+
module Configuration
|
8
|
+
module Transformers
|
9
|
+
module URI
|
10
|
+
Avatar = lambda do |content, key = :avatar_uri|
|
11
|
+
domain, uri = content.values_at :avatar_domain, key
|
12
|
+
|
13
|
+
return Dry::Monads::Success content unless uri
|
14
|
+
|
15
|
+
content[key] = format uri, domain:, id: "%<id>s"
|
16
|
+
Dry::Monads::Success content
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "pathname"
|
5
|
+
|
6
|
+
module Milestoner
|
7
|
+
module Configuration
|
8
|
+
module Transformers
|
9
|
+
module URI
|
10
|
+
Commit = lambda do |content, key = :commit_uri|
|
11
|
+
owner, name, domain, uri = content.values_at :project_owner,
|
12
|
+
:project_name,
|
13
|
+
:commit_domain,
|
14
|
+
key
|
15
|
+
|
16
|
+
return Dry::Monads::Success content unless uri
|
17
|
+
|
18
|
+
content[key] = format uri, domain:, owner:, name:, id: "%<id>s"
|
19
|
+
Dry::Monads::Success content
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "pathname"
|
5
|
+
|
6
|
+
module Milestoner
|
7
|
+
module Configuration
|
8
|
+
module Transformers
|
9
|
+
module URI
|
10
|
+
Profile = lambda do |content, key = :profile_uri|
|
11
|
+
domain, uri = content.values_at :profile_domain, key
|
12
|
+
|
13
|
+
return Dry::Monads::Success content unless uri
|
14
|
+
|
15
|
+
content[key] = format uri, domain:, id: "%<id>s"
|
16
|
+
Dry::Monads::Success content
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "pathname"
|
5
|
+
|
6
|
+
module Milestoner
|
7
|
+
module Configuration
|
8
|
+
module Transformers
|
9
|
+
module URI
|
10
|
+
Review = lambda do |content, key = :review_uri|
|
11
|
+
owner, name, domain, uri = content.values_at :project_owner,
|
12
|
+
:project_name,
|
13
|
+
:review_domain,
|
14
|
+
key
|
15
|
+
|
16
|
+
return Dry::Monads::Success content unless uri
|
17
|
+
|
18
|
+
content[key] = format uri, domain:, owner:, name:, id: "%<id>s"
|
19
|
+
Dry::Monads::Success content
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "pathname"
|
5
|
+
|
6
|
+
module Milestoner
|
7
|
+
module Configuration
|
8
|
+
module Transformers
|
9
|
+
module URI
|
10
|
+
Tracker = lambda do |content, key = :tracker_uri|
|
11
|
+
owner, name, domain, uri = content.values_at :project_owner,
|
12
|
+
:project_name,
|
13
|
+
:tracker_domain,
|
14
|
+
key
|
15
|
+
|
16
|
+
return Dry::Monads::Success content unless uri
|
17
|
+
|
18
|
+
content[key] = format uri, domain:, owner:, name:, id: "%<id>s"
|
19
|
+
Dry::Monads::Success content
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/milestoner/container.rb
CHANGED
@@ -4,7 +4,9 @@ require "cogger"
|
|
4
4
|
require "dry-container"
|
5
5
|
require "etcher"
|
6
6
|
require "gitt"
|
7
|
+
require "lode"
|
7
8
|
require "runcom"
|
9
|
+
require "sanitize"
|
8
10
|
require "spek"
|
9
11
|
|
10
12
|
module Milestoner
|
@@ -12,21 +14,62 @@ module Milestoner
|
|
12
14
|
module Container
|
13
15
|
extend Dry::Container::Mixin
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
+
namespace :xdg do
|
18
|
+
register(:cache, memoize: true) { Runcom::Cache.new "milestoner/database.store" }
|
19
|
+
register(:config, memoize: true) { Runcom::Config.new "milestoner/configuration.yml" }
|
20
|
+
end
|
21
|
+
|
22
|
+
register :cache, memoize: true do
|
23
|
+
# :nocov:
|
24
|
+
Lode.new self["xdg.cache"].passive do |config|
|
25
|
+
config.mode = :max
|
26
|
+
config.table = Lode::Tables::Value
|
27
|
+
config.register :users, model: Models::User, primary_key: :name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
register :configuration, memoize: true do
|
32
|
+
self[:defaults].add_loader(Etcher::Loaders::YAML.new(self["xdg.config"].active))
|
17
33
|
.then { |registry| Etcher.call registry }
|
18
34
|
end
|
19
35
|
|
20
|
-
register :defaults do
|
36
|
+
register :defaults, memoize: true do
|
21
37
|
Etcher::Registry.new(contract: Configuration::Contract, model: Configuration::Model)
|
22
38
|
.add_loader(Etcher::Loaders::YAML.new(self[:defaults_path]))
|
39
|
+
.add_transformer(Configuration::Transformers::Build::Root)
|
40
|
+
.add_transformer(Configuration::Transformers::Build::TemplatePaths.new)
|
41
|
+
.add_transformer(Configuration::Transformers::Gems::Label.new)
|
42
|
+
.add_transformer(Configuration::Transformers::Gems::Description.new)
|
43
|
+
.add_transformer(Configuration::Transformers::Gems::Name.new)
|
44
|
+
.add_transformer(Configuration::Transformers::Gems::URI.new)
|
45
|
+
.add_transformer(Configuration::Transformers::Citations::Label.new)
|
46
|
+
.add_transformer(Configuration::Transformers::Citations::Description.new)
|
47
|
+
.add_transformer(Configuration::Transformers::Project::Author.new)
|
48
|
+
.add_transformer(Configuration::Transformers::Project::Label)
|
49
|
+
.add_transformer(Configuration::Transformers::Project::Name)
|
50
|
+
.add_transformer(Configuration::Transformers::Project::Version.new)
|
51
|
+
.add_transformer(Configuration::Transformers::Generator::Label.new)
|
52
|
+
.add_transformer(Configuration::Transformers::Generator::URI.new)
|
53
|
+
.add_transformer(Configuration::Transformers::URI::Avatar)
|
54
|
+
.add_transformer(Configuration::Transformers::URI::Commit)
|
55
|
+
.add_transformer(Configuration::Transformers::URI::Profile)
|
56
|
+
.add_transformer(Configuration::Transformers::URI::Review)
|
57
|
+
.add_transformer(Configuration::Transformers::URI::Tracker)
|
58
|
+
end
|
59
|
+
|
60
|
+
register :specification, memoize: true do
|
61
|
+
self[:spec_loader].call "#{__dir__}/../../milestoner.gemspec"
|
62
|
+
end
|
63
|
+
|
64
|
+
register :sanitizer, memoize: true do
|
65
|
+
-> content { Sanitize.fragment content, Sanitize::Config::BASIC }
|
23
66
|
end
|
24
67
|
|
25
|
-
register(:
|
26
|
-
register(:
|
27
|
-
register(:
|
28
|
-
register(:
|
29
|
-
register(:
|
30
|
-
register
|
68
|
+
register(:spec_loader, memoize: true) { Spek::Loader.new }
|
69
|
+
register(:git, memoize: true) { Gitt::Repository.new }
|
70
|
+
register(:input, memoize: true) { self[:configuration].dup }
|
71
|
+
register(:defaults_path, memoize: true) { Pathname(__dir__).join("configuration/defaults.yml") }
|
72
|
+
register(:logger, memoize: true) { Cogger.new id: :milestoner }
|
73
|
+
register :kernel, Kernel
|
31
74
|
end
|
32
75
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "gitt"
|
4
|
+
|
5
|
+
module Milestoner
|
6
|
+
module Models
|
7
|
+
COMMIT_COMMON_ATTRIBUTES = %i[
|
8
|
+
authored_at
|
9
|
+
body
|
10
|
+
deletions
|
11
|
+
files_changed
|
12
|
+
insertions
|
13
|
+
notes
|
14
|
+
sha
|
15
|
+
signature
|
16
|
+
subject
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
COMMIT_ENRICHED_ATTRIBUTES = %i[
|
20
|
+
author
|
21
|
+
collaborators
|
22
|
+
format
|
23
|
+
issue
|
24
|
+
milestone
|
25
|
+
review
|
26
|
+
signers
|
27
|
+
uri
|
28
|
+
].freeze
|
29
|
+
|
30
|
+
# Represents an enriched commit.
|
31
|
+
Commit = Struct.new(*COMMIT_COMMON_ATTRIBUTES, *COMMIT_ENRICHED_ATTRIBUTES) do
|
32
|
+
include Gitt::Directable
|
33
|
+
|
34
|
+
def self.for(commit, **) = new(**commit.to_h.slice(*COMMIT_COMMON_ATTRIBUTES), **)
|
35
|
+
|
36
|
+
def initialize(**)
|
37
|
+
super
|
38
|
+
freeze
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "asciidoctor"
|
4
|
+
|
5
|
+
module Milestoner
|
6
|
+
module Renderers
|
7
|
+
# Renders ASCII Doc as HTML.
|
8
|
+
class Asciidoc
|
9
|
+
def initialize client: Asciidoctor
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(content) = client.convert content
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
attr_reader :client
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "redcarpet"
|
4
|
+
|
5
|
+
module Milestoner
|
6
|
+
module Renderers
|
7
|
+
# Renders Markdown as HTML.
|
8
|
+
class Markdown
|
9
|
+
def initialize client: Redcarpet::Markdown.new(Redcarpet::Render::HTML.new)
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(content) = client.render content
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
attr_reader :client
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Milestoner
|
4
|
+
module Renderers
|
5
|
+
# The primary renderer for multiple input formats as HTML.
|
6
|
+
class Universal
|
7
|
+
include Import[:input]
|
8
|
+
|
9
|
+
DELEGATES = {asciidoc: Asciidoc.new, markdown: Markdown.new}.freeze
|
10
|
+
|
11
|
+
def initialize(delegates: DELEGATES, **)
|
12
|
+
super(**)
|
13
|
+
@delegates = delegates
|
14
|
+
@default_format = input.commit_format.to_sym
|
15
|
+
end
|
16
|
+
|
17
|
+
def call content, for: default_format
|
18
|
+
delegates.fetch(binding.local_variable_get(:for)).call content
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :delegates, :default_format
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,38 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "gitt"
|
4
|
+
require "refinements/string_io"
|
4
5
|
require "versionaire"
|
5
6
|
|
6
7
|
module Milestoner
|
7
8
|
module Tags
|
8
9
|
# Handles the creation of project repository tags.
|
9
10
|
class Creator
|
10
|
-
include Import[:git, :logger]
|
11
|
+
include Import[:input, :git, :logger]
|
11
12
|
|
13
|
+
using Refinements::StringIO
|
12
14
|
using Versionaire::Cast
|
13
15
|
|
14
|
-
def initialize(
|
16
|
+
def initialize(
|
17
|
+
collector: Commits::Collector.new,
|
18
|
+
builder: Builders::Stream.new(kernel: StringIO.new),
|
19
|
+
**
|
20
|
+
)
|
21
|
+
@collector = collector
|
22
|
+
@builder = builder
|
15
23
|
super(**)
|
16
|
-
@categorizer = categorizer
|
17
|
-
@presenter = presenter
|
18
24
|
end
|
19
25
|
|
20
|
-
def call
|
21
|
-
|
22
|
-
fail Error, "Unable to tag without commits." if categorizer.call.empty?
|
26
|
+
def call override = nil
|
27
|
+
version = compute_version override
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
|
29
|
+
return false if local? version
|
30
|
+
fail Error, "Unable to tag without commits." if collector.call.value_or([]).empty?
|
31
|
+
|
32
|
+
create version
|
27
33
|
end
|
28
34
|
|
29
35
|
private
|
30
36
|
|
31
|
-
attr_reader :
|
37
|
+
attr_reader :collector, :builder
|
32
38
|
|
33
|
-
def
|
34
|
-
|
39
|
+
def compute_version value
|
40
|
+
Version value || input.project_version
|
41
|
+
rescue Versionaire::Error => error
|
42
|
+
raise Error, error
|
43
|
+
end
|
35
44
|
|
45
|
+
def local? version
|
36
46
|
if git.tag_local? version
|
37
47
|
logger.warn { "Local tag exists: #{version}. Skipped." }
|
38
48
|
true
|
@@ -41,18 +51,16 @@ module Milestoner
|
|
41
51
|
end
|
42
52
|
end
|
43
53
|
|
44
|
-
def create
|
45
|
-
git.tag_create
|
46
|
-
|
47
|
-
|
54
|
+
def create version
|
55
|
+
build(version).fmap { |body| git.tag_create version, body }
|
56
|
+
.or { |error| fail Error, error }
|
57
|
+
.bind { true }
|
48
58
|
end
|
49
59
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
%(Version #{configuration.version}\n\n#{line_items.join "\n"}\n\n)
|
55
|
-
end
|
60
|
+
def build version
|
61
|
+
builder.call.fmap do |body|
|
62
|
+
"Version #{version}\n\n#{body.reread}\n\n"
|
63
|
+
end
|
56
64
|
end
|
57
65
|
end
|
58
66
|
end
|
@@ -4,7 +4,7 @@ module Milestoner
|
|
4
4
|
module Tags
|
5
5
|
# Handles the tagging and pushing of a tag to a remote repository.
|
6
6
|
class Publisher
|
7
|
-
include Import[:logger]
|
7
|
+
include Import[:input, :logger]
|
8
8
|
|
9
9
|
def initialize(creator: Tags::Creator.new, pusher: Tags::Pusher.new, **)
|
10
10
|
super(**)
|
@@ -12,10 +12,10 @@ module Milestoner
|
|
12
12
|
@pusher = pusher
|
13
13
|
end
|
14
14
|
|
15
|
-
def call
|
16
|
-
creator.call
|
17
|
-
pusher.call
|
18
|
-
logger.info { "Published: #{
|
15
|
+
def call override = nil
|
16
|
+
creator.call override
|
17
|
+
pusher.call override
|
18
|
+
logger.info { "Published: #{input.project_version}!" }
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
@@ -6,12 +6,12 @@ module Milestoner
|
|
6
6
|
module Tags
|
7
7
|
# Handles publishing of tags to a remote repository.
|
8
8
|
class Pusher
|
9
|
-
include Import[:git, :logger]
|
9
|
+
include Import[:input, :git, :logger]
|
10
10
|
|
11
11
|
using Versionaire::Cast
|
12
12
|
|
13
|
-
def call
|
14
|
-
version =
|
13
|
+
def call override = nil
|
14
|
+
version = compute_version override
|
15
15
|
|
16
16
|
fail Error, "Remote repository not configured." unless git.origin?
|
17
17
|
fail Error, "Remote tag exists: #{version}." if git.tag_remote? version
|
@@ -19,6 +19,12 @@ module Milestoner
|
|
19
19
|
|
20
20
|
logger.debug "Local tag pushed: #{version}."
|
21
21
|
end
|
22
|
+
|
23
|
+
def compute_version value
|
24
|
+
Version value || input.project_version
|
25
|
+
rescue Versionaire::Error => error
|
26
|
+
raise Error, error
|
27
|
+
end
|
22
28
|
end
|
23
29
|
end
|
24
30
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
|
3
|
+
<html lang="en">
|
4
|
+
<head>
|
5
|
+
<title><%= project_title %></title>
|
6
|
+
|
7
|
+
<meta charset="utf-8">
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
9
|
+
<meta name="description" content="<%= project_description %>">
|
10
|
+
<meta name="author" content="<%= project_author %>">
|
11
|
+
<meta name="generator" content="<%= generator_label %>">
|
12
|
+
|
13
|
+
<link title="<%= project_label %>: Favorite Icon"
|
14
|
+
rel="icon"
|
15
|
+
href="https://alchemists.io/images/projects/milestoner/icons/brand/favicon.ico"
|
16
|
+
sizes="32x32">
|
17
|
+
<link title="<%= project_label %>: Apple Icon"
|
18
|
+
rel="apple-touch-icon"
|
19
|
+
href="https://alchemists.io/images/projects/milestoner/icons/brand/apple.png"
|
20
|
+
type="image/png">
|
21
|
+
<link title="<%= project_label %>: Stylesheet" rel="stylesheet" href="page.css" type="text/css">
|
22
|
+
|
23
|
+
<script src="https://unpkg.com/alpinejs@3.13" defer></script>
|
24
|
+
</head>
|
25
|
+
|
26
|
+
<body>
|
27
|
+
<main>
|
28
|
+
<%= yield %>
|
29
|
+
</main>
|
30
|
+
|
31
|
+
<footer class="footer">
|
32
|
+
<p class="generator">
|
33
|
+
Generated by <a href="<%= generator_uri %>" class="link"><%= generator_label %></a>.
|
34
|
+
</p>
|
35
|
+
</footer>
|
36
|
+
</body>
|
37
|
+
</html>
|