milestoner 18.12.0 → 19.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.adoc +85 -71
  4. data/lib/milestoner/builders/adoc/container.rb +15 -0
  5. data/lib/milestoner/builders/adoc/dependencies.rb +9 -0
  6. data/lib/milestoner/builders/adoc/indexer.rb +28 -0
  7. data/lib/milestoner/builders/adoc/pager.rb +35 -0
  8. data/lib/milestoner/builders/ascii_doc.rb +10 -18
  9. data/lib/milestoner/builders/{import.rb → dependencies.rb} +1 -1
  10. data/lib/milestoner/builders/feed.rb +6 -15
  11. data/lib/milestoner/builders/markdown.rb +10 -18
  12. data/lib/milestoner/builders/md/container.rb +15 -0
  13. data/lib/milestoner/builders/md/dependencies.rb +9 -0
  14. data/lib/milestoner/builders/md/indexer.rb +28 -0
  15. data/lib/milestoner/builders/md/pager.rb +35 -0
  16. data/lib/milestoner/builders/path_resolver.rb +23 -0
  17. data/lib/milestoner/builders/site/container.rb +16 -0
  18. data/lib/milestoner/builders/site/dependencies.rb +9 -0
  19. data/lib/milestoner/builders/site/indexer.rb +33 -0
  20. data/lib/milestoner/builders/site/pager.rb +35 -0
  21. data/lib/milestoner/builders/site/styler.rb +47 -0
  22. data/lib/milestoner/builders/stream.rb +3 -3
  23. data/lib/milestoner/builders/syndication/builder.rb +125 -0
  24. data/lib/milestoner/builders/syndication/indexer.rb +29 -0
  25. data/lib/milestoner/builders/syndication/refine.rb +27 -0
  26. data/lib/milestoner/builders/syndication/shared.rb +27 -0
  27. data/lib/milestoner/builders/web.rb +11 -43
  28. data/lib/milestoner/cli/actions/build/basename.rb +1 -1
  29. data/lib/milestoner/cli/actions/build/format.rb +1 -1
  30. data/lib/milestoner/cli/actions/build/index.rb +26 -0
  31. data/lib/milestoner/cli/actions/build/label.rb +1 -1
  32. data/lib/milestoner/cli/actions/build/layout.rb +1 -1
  33. data/lib/milestoner/cli/actions/build/max.rb +1 -1
  34. data/lib/milestoner/cli/actions/build/output.rb +25 -0
  35. data/lib/milestoner/cli/actions/build/stylesheet.rb +5 -7
  36. data/lib/milestoner/cli/actions/build/tail.rb +1 -1
  37. data/lib/milestoner/cli/actions/build/version.rb +1 -1
  38. data/lib/milestoner/cli/actions/cache/create.rb +1 -1
  39. data/lib/milestoner/cli/actions/cache/delete.rb +1 -1
  40. data/lib/milestoner/cli/actions/cache/find.rb +1 -1
  41. data/lib/milestoner/cli/actions/cache/info.rb +1 -1
  42. data/lib/milestoner/cli/actions/cache/list.rb +1 -1
  43. data/lib/milestoner/cli/actions/next.rb +1 -1
  44. data/lib/milestoner/cli/actions/publish.rb +1 -1
  45. data/lib/milestoner/cli/commands/build.rb +4 -5
  46. data/lib/milestoner/cli/commands/cache.rb +1 -1
  47. data/lib/milestoner/cli/shell.rb +1 -1
  48. data/lib/milestoner/commits/categorizer.rb +7 -5
  49. data/lib/milestoner/commits/collector.rb +1 -1
  50. data/lib/milestoner/commits/enricher.rb +7 -5
  51. data/lib/milestoner/commits/enrichers/author.rb +1 -1
  52. data/lib/milestoner/commits/enrichers/body.rb +1 -1
  53. data/lib/milestoner/commits/enrichers/colleague.rb +1 -1
  54. data/lib/milestoner/commits/enrichers/container.rb +2 -2
  55. data/lib/milestoner/commits/enrichers/{import.rb → dependencies.rb} +1 -1
  56. data/lib/milestoner/commits/enrichers/format.rb +1 -1
  57. data/lib/milestoner/commits/enrichers/issue.rb +1 -1
  58. data/lib/milestoner/commits/enrichers/milestone.rb +1 -1
  59. data/lib/milestoner/commits/enrichers/note.rb +1 -1
  60. data/lib/milestoner/commits/enrichers/review.rb +1 -1
  61. data/lib/milestoner/commits/enrichers/uri.rb +1 -1
  62. data/lib/milestoner/commits/versioner.rb +1 -1
  63. data/lib/milestoner/configuration/contract.rb +6 -2
  64. data/lib/milestoner/configuration/defaults.yml +10 -4
  65. data/lib/milestoner/configuration/model.rb +5 -1
  66. data/lib/milestoner/configuration/transformers/gems/description.rb +1 -1
  67. data/lib/milestoner/configuration/transformers/gems/label.rb +2 -2
  68. data/lib/milestoner/configuration/transformers/gems/name.rb +1 -1
  69. data/lib/milestoner/configuration/transformers/gems/uri.rb +1 -1
  70. data/lib/milestoner/configuration/transformers/generator/label.rb +1 -1
  71. data/lib/milestoner/configuration/transformers/generator/uri.rb +1 -1
  72. data/lib/milestoner/configuration/transformers/generator/version.rb +1 -1
  73. data/lib/milestoner/configuration/transformers/project/author.rb +1 -1
  74. data/lib/milestoner/container.rb +3 -2
  75. data/lib/milestoner/{import.rb → dependencies.rb} +1 -1
  76. data/lib/milestoner/durationer.rb +25 -0
  77. data/lib/milestoner/models/commit.rb +2 -1
  78. data/lib/milestoner/renderers/universal.rb +1 -1
  79. data/lib/milestoner/tags/builder.rb +40 -0
  80. data/lib/milestoner/tags/creator.rb +7 -9
  81. data/lib/milestoner/{commits/tagger.rb → tags/enricher.rb} +27 -15
  82. data/lib/milestoner/tags/publisher.rb +1 -1
  83. data/lib/milestoner/tags/pusher.rb +1 -1
  84. data/lib/milestoner/templates/layouts/page.adoc.erb +4 -0
  85. data/lib/milestoner/templates/layouts/page.git.erb +1 -0
  86. data/lib/milestoner/templates/layouts/page.html.erb +17 -10
  87. data/lib/milestoner/templates/layouts/page.md.erb +3 -0
  88. data/lib/milestoner/templates/layouts/page.stream.erb +2 -1
  89. data/lib/milestoner/templates/layouts/page.xml.erb +4 -0
  90. data/lib/milestoner/templates/milestones/_commit.adoc.erb +4 -4
  91. data/lib/milestoner/templates/milestones/_commit.html.erb +7 -4
  92. data/lib/milestoner/templates/milestones/_commit.stream.erb +1 -1
  93. data/lib/milestoner/templates/milestones/_commit.xml.erb +2 -6
  94. data/lib/milestoner/templates/milestones/_logo.adoc.erb +1 -1
  95. data/lib/milestoner/templates/milestones/_logo.html.erb +1 -1
  96. data/lib/milestoner/templates/milestones/index.adoc.erb +13 -0
  97. data/lib/milestoner/templates/milestones/index.html.erb +31 -0
  98. data/lib/milestoner/templates/milestones/index.md.erb +13 -0
  99. data/lib/milestoner/templates/milestones/show.adoc.erb +17 -1
  100. data/lib/milestoner/templates/milestones/show.git.erb +8 -0
  101. data/lib/milestoner/templates/milestones/show.html.erb +119 -1
  102. data/lib/milestoner/templates/milestones/show.md.erb +16 -1
  103. data/lib/milestoner/templates/milestones/show.stream.erb +17 -1
  104. data/lib/milestoner/templates/milestones/show.xml.erb +22 -1
  105. data/lib/milestoner/templates/public/page.css.erb +402 -299
  106. data/lib/milestoner/views/context.rb +2 -1
  107. data/lib/milestoner/views/milestones/index.rb +23 -0
  108. data/lib/milestoner/views/milestones/show.rb +2 -2
  109. data/lib/milestoner/views/parts/commit.rb +47 -37
  110. data/lib/milestoner/views/parts/tag.rb +25 -17
  111. data/lib/milestoner/views/parts/user.rb +1 -1
  112. data/lib/milestoner.rb +5 -1
  113. data/milestoner.gemspec +18 -18
  114. data.tar.gz.sig +0 -0
  115. metadata +68 -57
  116. metadata.gz.sig +0 -0
  117. data/lib/milestoner/cli/actions/build/root.rb +0 -25
  118. data/lib/milestoner/configuration/transformers/build/root.rb +0 -21
  119. data/lib/milestoner/syndication/builder.rb +0 -123
  120. data/lib/milestoner/syndication/refine.rb +0 -25
  121. data/lib/milestoner/syndication/shared.rb +0 -25
  122. data/lib/milestoner/templates/milestones/_tag.adoc.erb +0 -13
  123. data/lib/milestoner/templates/milestones/_tag.html.erb +0 -56
  124. data/lib/milestoner/templates/milestones/_tag.md.erb +0 -14
  125. data/lib/milestoner/templates/milestones/_tag.stream.erb +0 -15
  126. data/lib/milestoner/templates/milestones/_tag.xml.erb +0 -22
@@ -7,7 +7,7 @@ module Milestoner
7
7
  module Actions
8
8
  # Handles calculation of next version.
9
9
  class Next < Sod::Action
10
- include Import[:settings, :io]
10
+ include Dependencies[:settings, :io]
11
11
 
12
12
  description "Show next version."
13
13
 
@@ -9,7 +9,7 @@ module Milestoner
9
9
  module Actions
10
10
  # Handles tag creation and pushing of tag to local repository.
11
11
  class Publish < Sod::Action
12
- include Import[:settings, :logger]
12
+ include Dependencies[:settings, :logger]
13
13
  include Dry::Monads[:result]
14
14
 
15
15
  using Versionaire::Cast
@@ -7,8 +7,8 @@ module Milestoner
7
7
  module Commands
8
8
  # Handles the building of different milestone formats.
9
9
  class Build < Sod::Command
10
- include Import[:settings, :logger, :io]
11
- include Builders::Import[:ascii_doc, :feed, :markdown, :stream, :web]
10
+ include Dependencies[:settings, :logger, :io]
11
+ include Builders::Dependencies[:ascii_doc, :feed, :markdown, :stream, :web]
12
12
 
13
13
  handle "build"
14
14
 
@@ -16,10 +16,11 @@ module Milestoner
16
16
 
17
17
  on Actions::Build::Basename
18
18
  on Actions::Build::Format
19
+ on Actions::Build::Index
19
20
  on Actions::Build::Label
20
21
  on Actions::Build::Layout
21
22
  on Actions::Build::Max
22
- on Actions::Build::Root
23
+ on Actions::Build::Output
23
24
  on Actions::Build::Stylesheet
24
25
  on Actions::Build::Tail
25
26
  on Actions::Build::Version
@@ -38,8 +39,6 @@ module Milestoner
38
39
 
39
40
  private
40
41
 
41
- attr_reader :view, :enricher
42
-
43
42
  def log_info(message) = logger.info { message }
44
43
  end
45
44
  end
@@ -7,7 +7,7 @@ module Milestoner
7
7
  module Commands
8
8
  # Handles the building of milestone output.
9
9
  class Cache < Sod::Command
10
- include Import[:settings, :logger]
10
+ include Dependencies[:settings, :logger]
11
11
 
12
12
  handle "cache"
13
13
 
@@ -6,7 +6,7 @@ module Milestoner
6
6
  module CLI
7
7
  # The main Command Line Interface (CLI) object.
8
8
  class Shell
9
- include Import[:defaults_path, :specification, xdg_config: "xdg.config"]
9
+ include Dependencies[:defaults_path, :specification, xdg_config: "xdg.config"]
10
10
 
11
11
  def initialize(context: Sod::Context, dsl: Sod, **)
12
12
  super(**)
@@ -7,7 +7,7 @@ module Milestoner
7
7
  module Commits
8
8
  # Retrieves and categorizes Git repository commit tagged or untagged history.
9
9
  class Categorizer
10
- include Import[:settings]
10
+ include Dependencies[:settings]
11
11
 
12
12
  using Refinements::Array
13
13
 
@@ -19,10 +19,11 @@ module Milestoner
19
19
  @pattern = labels.empty? ? // : Regexp.union(labels)
20
20
  end
21
21
 
22
+ # :reek:NestedIterators
22
23
  def call min: Collector::MIN, max: Collector::MAX
23
- collect(min, max).each_value { |commits| commits.sort_by!(&:subject) }
24
+ collect(min, max).each_value { |commits| commits.sort_by! { |_, commit| commit.subject } }
24
25
  .values
25
- .flatten
26
+ .reduce(&:concat)
26
27
  end
27
28
 
28
29
  private
@@ -33,10 +34,11 @@ module Milestoner
33
34
  collector.call(min:, max:)
34
35
  .value_or(Core::EMPTY_ARRAY)
35
36
  .each
36
- .with_object categories do |commit, collection|
37
+ .with_index(1)
38
+ .with_object categories do |(commit, position), collection|
37
39
  category = commit.subject[pattern]
38
40
  key = collection.key?(category) ? category : "Unknown"
39
- collection[key] << commit
41
+ collection[key] << [position, commit]
40
42
  end
41
43
  end
42
44
 
@@ -7,7 +7,7 @@ module Milestoner
7
7
  # Collects commits since last tag, a specific range, or all commits if untagged.
8
8
  class Collector
9
9
  include Dry::Monads[:result]
10
- include Import[:git]
10
+ include Dependencies[:git]
11
11
 
12
12
  MIN = :last
13
13
  MAX = :HEAD
@@ -6,17 +6,17 @@ module Milestoner
6
6
  module Commits
7
7
  # Enriches commits and associated trailers for final processing.
8
8
  class Enricher
9
- include Import[:settings]
9
+ include Dependencies[:settings]
10
10
 
11
- include Enrichers::Import[
11
+ include Enrichers::Dependencies[
12
12
  :author,
13
- :body,
13
+ :body_html,
14
14
  :collaborators,
15
15
  :created_at,
16
16
  :format,
17
17
  :issue,
18
18
  :milestone,
19
- :notes,
19
+ :notes_html,
20
20
  :review,
21
21
  :signers,
22
22
  :updated_at,
@@ -33,7 +33,7 @@ module Milestoner
33
33
 
34
34
  def call min: Collector::MIN, max: Collector::MAX
35
35
  categorizer.call(min:, max:)
36
- .map { |commit| model.for(commit, **build_attributes(commit)) }
36
+ .map { |(position, commit)| build_record position, commit }
37
37
  .then { |commits| Success commits }
38
38
  end
39
39
 
@@ -41,6 +41,8 @@ module Milestoner
41
41
 
42
42
  attr_reader :categorizer, :model
43
43
 
44
+ def build_record(position, commit) = model.for commit, position:, **build_attributes(commit)
45
+
44
46
  def build_attributes commit
45
47
  infused_keys.each.with_object({}) do |key, attributes|
46
48
  attributes[key] = __send__(key).call commit
@@ -5,7 +5,7 @@ module Milestoner
5
5
  module Enrichers
6
6
  # Enriches a commit author by using cache.
7
7
  class Author
8
- include Milestoner::Import[:cache]
8
+ include Milestoner::Dependencies[:cache]
9
9
 
10
10
  def initialize(model: Models::User, **)
11
11
  super(**)
@@ -5,7 +5,7 @@ module Milestoner
5
5
  module Enrichers
6
6
  # Enriches commit text by rendering as HTML based on trailer information.
7
7
  class Body
8
- include Milestoner::Import[:settings]
8
+ include Milestoner::Dependencies[:settings]
9
9
 
10
10
  def initialize(key: "Format", renderer: Renderers::Universal.new, **)
11
11
  super(**)
@@ -7,7 +7,7 @@ module Milestoner
7
7
  module Enrichers
8
8
  # Enriches a commit colleague by using cache.
9
9
  class Colleague
10
- include Milestoner::Import[:cache]
10
+ include Milestoner::Dependencies[:cache]
11
11
 
12
12
  def initialize(key:, parser: Gitt::Parsers::Person.new, **)
13
13
  super(**)
@@ -10,13 +10,13 @@ module Milestoner
10
10
  extend Containable
11
11
 
12
12
  register(:author) { Author.new }
13
- register(:body) { Body.new }
13
+ register(:body_html) { Body.new }
14
14
  register(:collaborators) { Colleague.new key: "Co-authored-by" }
15
15
  register(:created_at) { Time.new key: :authored_at }
16
16
  register(:format) { Format.new }
17
17
  register(:issue) { Issue.new }
18
18
  register(:milestone) { Milestone.new }
19
- register(:notes) { Note.new }
19
+ register(:notes_html) { Note.new }
20
20
  register(:review) { Review.new }
21
21
  register(:signers) { Colleague.new key: "Signed-off-by" }
22
22
  register(:updated_at) { Time.new key: :committed_at }
@@ -5,7 +5,7 @@ require "infusible"
5
5
  module Milestoner
6
6
  module Commits
7
7
  module Enrichers
8
- Import = Infusible[Container]
8
+ Dependencies = Infusible[Container]
9
9
  end
10
10
  end
11
11
  end
@@ -5,7 +5,7 @@ module Milestoner
5
5
  module Enrichers
6
6
  # Enriches a commit format based on trailer information.
7
7
  class Format
8
- include Milestoner::Import[:settings]
8
+ include Milestoner::Dependencies[:settings]
9
9
 
10
10
  def initialize(key: "Format", **)
11
11
  super(**)
@@ -5,7 +5,7 @@ module Milestoner
5
5
  module Enrichers
6
6
  # Enriches a commit issue based on trailer information.
7
7
  class Issue
8
- include Milestoner::Import[:settings]
8
+ include Milestoner::Dependencies[:settings]
9
9
 
10
10
  def initialize(key: "Issue", model: Models::Link, **)
11
11
  super(**)
@@ -5,7 +5,7 @@ module Milestoner
5
5
  module Enrichers
6
6
  # Enriches a commit milestone based on trailer information.
7
7
  class Milestone
8
- include Milestoner::Import[:settings]
8
+ include Milestoner::Dependencies[:settings]
9
9
 
10
10
  def initialize(key: "Milestone", default: "unknown", **)
11
11
  super(**)
@@ -5,7 +5,7 @@ module Milestoner
5
5
  module Enrichers
6
6
  # Enriches commit notes by rendering as HTML based on trailer information.
7
7
  class Note
8
- include Milestoner::Import[:settings]
8
+ include Milestoner::Dependencies[:settings]
9
9
 
10
10
  def initialize(key: "Format", renderer: Renderers::Universal.new, **)
11
11
  super(**)
@@ -5,7 +5,7 @@ module Milestoner
5
5
  module Enrichers
6
6
  # Enriches a commit review based on trailer information.
7
7
  class Review
8
- include Milestoner::Import[:settings]
8
+ include Milestoner::Dependencies[:settings]
9
9
 
10
10
  def initialize(model: Models::Link, **)
11
11
  super(**)
@@ -5,7 +5,7 @@ module Milestoner
5
5
  module Enrichers
6
6
  # Enriches a commit URI based on trailer information.
7
7
  class URI
8
- include Milestoner::Import[:settings]
8
+ include Milestoner::Dependencies[:settings]
9
9
 
10
10
  def call(commit) = format settings.commit_uri, id: commit.sha
11
11
  end
@@ -8,7 +8,7 @@ module Milestoner
8
8
  module Commits
9
9
  # Calculates next version based on commit trailer version keys.
10
10
  class Versioner
11
- include Import[:git, :logger]
11
+ include Dependencies[:git, :logger]
12
12
  include Dry::Monads[:result]
13
13
 
14
14
  using Versionaire::Cast
@@ -11,10 +11,11 @@ module Milestoner
11
11
  required(:avatar_uri).filled :string
12
12
  required(:build_basename).filled :string
13
13
  required(:build_format).filled :string
14
+ required(:build_index).filled :bool
14
15
  required(:build_layout) { str? | bool? }
15
16
  required(:build_max).filled :integer
16
- required(:build_root).filled Etcher::Types::Pathname
17
- required(:build_stylesheet) { bool? | str? }
17
+ required(:build_output).filled Etcher::Types::Pathname
18
+ required(:build_stylesheet).filled :bool
18
19
  required(:build_tail).filled :string
19
20
  required(:build_template_paths).array Etcher::Types::Pathname
20
21
 
@@ -43,6 +44,8 @@ module Milestoner
43
44
  required(:project_uri_version).filled :string
44
45
  required(:project_version).filled Etcher::Types::Version
45
46
  required(:review_uri).filled :string
47
+ required(:stylesheet_path).filled :string
48
+ required(:stylesheet_uri).filled :string
46
49
 
47
50
  required(:syndication_categories).array(:hash) do
48
51
  required(:label).filled :string
@@ -61,6 +64,7 @@ module Milestoner
61
64
  required(:uri).filled :string
62
65
  end
63
66
 
67
+ required(:tag_subject).filled :string
64
68
  required(:tracker_uri).filled :string
65
69
  end
66
70
  end
@@ -3,19 +3,20 @@ avatar:
3
3
  build:
4
4
  basename: "index"
5
5
  format: "stream"
6
+ index: true
6
7
  layout: "page"
7
8
  max: 1
8
- root: "tmp/milestones"
9
- stylesheet: "page"
9
+ output: "tmp/milestones"
10
+ stylesheet: true
10
11
  tail: "head"
11
12
  commit:
12
13
  categories:
13
- - emoji: "✅"
14
- label: "Fixed"
15
14
  - emoji: "🟢"
16
15
  label: "Added"
17
16
  - emoji: "🔼"
18
17
  label: "Updated"
18
+ - emoji: "✅"
19
+ label: "Fixed"
19
20
  - emoji: "⛔️"
20
21
  label: "Removed"
21
22
  - emoji: "🔁"
@@ -34,6 +35,9 @@ project:
34
35
  version: "%<project_uri_home>s/versions/%<id>s"
35
36
  review:
36
37
  uri: "https://github.com/%<project_owner>s/%<project_name>s/pulls/%<id>s"
38
+ stylesheet:
39
+ path: "page.css"
40
+ uri: "../page"
37
41
  syndication:
38
42
  categories:
39
43
  - label: "Milestones"
@@ -52,5 +56,7 @@ syndication:
52
56
  mime: "application/atom+xml"
53
57
  relation: "self"
54
58
  uri: "%<project_uri_home>s/versions.xml"
59
+ tag:
60
+ subject: "Version %<project_version>s"
55
61
  tracker:
56
62
  uri: "https://github.com/%<project_owner>s/%<project_name>s/issues/%<id>s"
@@ -6,9 +6,10 @@ module Milestoner
6
6
  Model = Struct.new :avatar_uri,
7
7
  :build_basename,
8
8
  :build_format,
9
+ :build_index,
9
10
  :build_layout,
10
11
  :build_max,
11
- :build_root,
12
+ :build_output,
12
13
  :build_stylesheet,
13
14
  :build_tail,
14
15
  :build_template_paths,
@@ -33,12 +34,15 @@ module Milestoner
33
34
  :project_uri_version,
34
35
  :project_version,
35
36
  :review_uri,
37
+ :stylesheet_path,
38
+ :stylesheet_uri,
36
39
  :syndication_categories,
37
40
  :syndication_entry_label,
38
41
  :syndication_entry_uri,
39
42
  :syndication_id,
40
43
  :syndication_label,
41
44
  :syndication_links,
45
+ :tag_subject,
42
46
  :tracker_uri
43
47
  end
44
48
  end
@@ -9,7 +9,7 @@ module Milestoner
9
9
  module Gems
10
10
  # Conditionally updates project description based on specification summary.
11
11
  class Description
12
- include Import[:spec_loader]
12
+ include Dependencies[:spec_loader]
13
13
  include Dry::Monads[:result]
14
14
 
15
15
  def initialize(key = :project_description, path: "#{Pathname.pwd.basename}.gemspec", **)
@@ -9,7 +9,7 @@ module Milestoner
9
9
  module Gems
10
10
  # Conditionally updates project label based on specification label.
11
11
  class Label
12
- include Import[:spec_loader]
12
+ include Dependencies[:spec_loader]
13
13
  include Dry::Monads[:result]
14
14
 
15
15
  def initialize(key = :project_label, path: "#{Pathname.pwd.basename}.gemspec", **)
@@ -21,7 +21,7 @@ module Milestoner
21
21
  def call attributes
22
22
  attributes.fetch key do
23
23
  value = spec_loader.call(path).label
24
- attributes.merge! key => value unless value == "Undefined"
24
+ attributes.merge! key => value unless value.empty?
25
25
  end
26
26
 
27
27
  Success attributes
@@ -9,7 +9,7 @@ module Milestoner
9
9
  module Gems
10
10
  # Conditionally updates project name based on specification name.
11
11
  class Name
12
- include Import[:spec_loader]
12
+ include Dependencies[:spec_loader]
13
13
  include Dry::Monads[:result]
14
14
 
15
15
  def initialize(key = :project_name, path: "#{Pathname.pwd.basename}.gemspec", **)
@@ -9,7 +9,7 @@ module Milestoner
9
9
  module Gems
10
10
  # Conditionally updates project URI based on specification home page URL.
11
11
  class URI
12
- include Import[:spec_loader]
12
+ include Dependencies[:spec_loader]
13
13
  include Dry::Monads[:result]
14
14
 
15
15
  def initialize(key = :project_uri, path: "#{Pathname.pwd.basename}.gemspec", **)
@@ -8,7 +8,7 @@ module Milestoner
8
8
  module Generator
9
9
  # Conditionally updates generator label based on gem specification.
10
10
  class Label
11
- include Import[:specification]
11
+ include Dependencies[:specification]
12
12
  include Dry::Monads[:result]
13
13
 
14
14
  def initialize(key = :generator_label, **)
@@ -8,7 +8,7 @@ module Milestoner
8
8
  module Generator
9
9
  # Conditionally updates generator URI based on gem specification.
10
10
  class URI
11
- include Import[:specification]
11
+ include Dependencies[:specification]
12
12
  include Dry::Monads[:result]
13
13
 
14
14
  def initialize(key = :generator_uri, **)
@@ -8,7 +8,7 @@ module Milestoner
8
8
  module Generator
9
9
  # Conditionally updates generator version based on gem specification.
10
10
  class Version
11
- include Import[:specification]
11
+ include Dependencies[:specification]
12
12
  include Dry::Monads[:result]
13
13
 
14
14
  def initialize(key = :generator_version, **)
@@ -8,7 +8,7 @@ module Milestoner
8
8
  module Project
9
9
  # Conditionally updates author based on Git user.
10
10
  class Author
11
- include Import[:git]
11
+ include Dependencies[:git]
12
12
  include Dry::Monads[:result]
13
13
 
14
14
  def initialize(key = :project_author, **)
@@ -28,11 +28,11 @@ module Milestoner
28
28
  end
29
29
  end
30
30
 
31
- register :registry do
31
+ register :registry, as: :fresh do
32
32
  Etcher::Registry.new(contract: Configuration::Contract, model: Configuration::Model)
33
33
  .add_loader(:yaml, self[:defaults_path])
34
34
  .add_loader(:yaml, self["xdg.config"].active)
35
- .add_transformer(Configuration::Transformers::Build::Root)
35
+ .add_transformer(:root, :build_output)
36
36
  .add_transformer(Configuration::Transformers::Build::TemplatePaths.new)
37
37
  .add_transformer(Configuration::Transformers::Gems::Label.new)
38
38
  .add_transformer(Configuration::Transformers::Gems::Description.new)
@@ -70,6 +70,7 @@ module Milestoner
70
70
  register(:git) { Gitt::Repository.new }
71
71
  register(:defaults_path) { Pathname(__dir__).join("configuration/defaults.yml") }
72
72
  register(:color) { Tone.new }
73
+ register :durationer, Durationer
73
74
  register(:logger) { Cogger.new id: :milestoner }
74
75
  register :io, STDOUT
75
76
  end
@@ -3,5 +3,5 @@
3
3
  require "infusible"
4
4
 
5
5
  module Milestoner
6
- Import = Infusible[Container]
6
+ Dependencies = Infusible[Container]
7
7
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/array"
4
+ require "refinements/string"
5
+
6
+ # Computes duration (in seconds) into human readable days, hours, minutes, and seconds.
7
+ module Milestoner
8
+ using Refinements::Array
9
+ using Refinements::String
10
+
11
+ DURATION_UNITS = {"second" => 60, "minute" => 60, "hour" => 24, "day" => 86_400}.freeze
12
+
13
+ Durationer = lambda do |seconds, units: DURATION_UNITS|
14
+ result = units.map do |unit, value|
15
+ next unless seconds.positive?
16
+
17
+ seconds, number = seconds.divmod value
18
+ number = number.to_i
19
+
20
+ %(#{number} #{unit.pluralize "s", number}) if number.nonzero?
21
+ end
22
+
23
+ result.compact.reverse.to_sentence
24
+ end
25
+ end
@@ -8,7 +8,6 @@ module Milestoner
8
8
  authored_at
9
9
  authored_relative_at
10
10
  body
11
- body_lines
12
11
  committed_at
13
12
  committed_relative_at
14
13
  deletions
@@ -25,11 +24,13 @@ module Milestoner
25
24
 
26
25
  COMMIT_ENRICHED_ATTRIBUTES = %i[
27
26
  author
27
+ body_html
28
28
  collaborators
29
29
  created_at
30
30
  format
31
31
  issue
32
32
  milestone
33
+ notes_html
33
34
  position
34
35
  review
35
36
  signers
@@ -6,7 +6,7 @@ module Milestoner
6
6
  module Renderers
7
7
  # The primary renderer for multiple input formats as HTML.
8
8
  class Universal
9
- include Import[:settings]
9
+ include Dependencies[:settings]
10
10
 
11
11
  using Refinements::Binding
12
12
 
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Milestoner
4
+ module Tags
5
+ # Builds tag message.
6
+ class Builder
7
+ include Milestoner::Dependencies[:settings, :logger]
8
+
9
+ def initialize(enricher: Enricher.new, view: Views::Milestones::Show.new, **)
10
+ super(**)
11
+ @enricher = enricher
12
+ @view = view
13
+ end
14
+
15
+ def call version
16
+ force_minimum
17
+
18
+ enricher.call
19
+ .fmap { |tags| render tags.first, version }
20
+ .alt_map { |message| failure message }
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :enricher, :view
26
+
27
+ def force_minimum = settings.build_max = 1
28
+
29
+ def render tag, version
30
+ tag.version = version
31
+ view.call(tag:, layout: settings.build_layout, format: :git).to_s.lstrip
32
+ end
33
+
34
+ def failure message
35
+ logger.error { message }
36
+ message
37
+ end
38
+ end
39
+ end
40
+ end
@@ -7,17 +7,13 @@ module Milestoner
7
7
  module Tags
8
8
  # Handles the creation of project repository tags.
9
9
  class Creator
10
- include Import[:git, :logger]
10
+ include Dependencies[:settings, :git, :logger]
11
11
  include Dry::Monads[:result]
12
12
 
13
- def initialize(
14
- collector: Commits::Collector.new,
15
- builder: Builders::Stream.new(io: StringIO.new),
16
- **
17
- )
13
+ def initialize(collector: Commits::Collector.new, builder: Builder.new, **)
14
+ super(**)
18
15
  @collector = collector
19
16
  @builder = builder
20
- super(**)
21
17
  end
22
18
 
23
19
  def call version
@@ -41,9 +37,11 @@ module Milestoner
41
37
 
42
38
  def collect = collector.call.alt_map { |message| message.sub("fatal: y", "Y").sub("\n", ".") }
43
39
 
44
- def create(version) = build(version).bind { |body| git.tag_create version, body }
40
+ def create version
41
+ builder.call(version).bind { |body| git.tag_create version, "#{subject}\n\n#{body}\n\n" }
42
+ end
45
43
 
46
- def build(version) = builder.call.fmap { |body| "Version #{version}\n\n#{body}\n\n" }
44
+ def subject = format(settings.tag_subject, **settings.to_h)
47
45
  end
48
46
  end
49
47
  end