toys-release 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/toys/.toys.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- toys_version!("~> 0.17")
3
+ toys_version!("~> 0.18")
4
4
 
5
- desc "Release tools namespace"
5
+ desc "Namespace for toys-release tools"
data/toys/_onclosed.rb CHANGED
@@ -83,12 +83,13 @@ end
83
83
 
84
84
  def handle_release_merged
85
85
  setup_git
86
+ report_release_starting
86
87
  github_check_errors = @repository.wait_github_checks
87
88
  unless github_check_errors.empty?
88
89
  @utils.error("GitHub checks failed", *github_check_errors)
89
90
  end
90
91
  performer = create_performer
91
- performer.perform_pr_releases
92
+ performer.perform_pr_releases unless performer.error?
92
93
  performer.report_results
93
94
  if performer.error?
94
95
  @utils.error("Releases reported failure")
@@ -103,6 +104,13 @@ def setup_git
103
104
  exec(["git", "switch", "release/current"], e: true)
104
105
  end
105
106
 
107
+ def report_release_starting
108
+ reports = ["Starting release automation."]
109
+ url = @utils.current_workflow_run_url
110
+ reports << "See #{url} for execution logs." if url
111
+ @pull_request.add_comment(reports.join(" "))
112
+ end
113
+
106
114
  def create_performer
107
115
  require "toys/release/performer"
108
116
  dry_run = /^t/i.match?(::ENV["TOYS_RELEASE_DRY_RUN"].to_s)
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ desc "Generate an initial config file"
4
+
5
+ long_desc \
6
+ "This tool generates an initial config file for this repo." \
7
+ " You will generally need to make additional edits to this file after" \
8
+ " initial generation."
9
+
10
+ flag :repo, "--repo=REPO" do
11
+ desc "GitHub repo owner and name (e.g. dazuma/toys)"
12
+ end
13
+ flag :git_user, "--git-user=NAME" do
14
+ default ""
15
+ desc "User name for git commits (defaults to the git user.name config)"
16
+ end
17
+ flag :git_email, "--git-email=EMAIL" do
18
+ default ""
19
+ desc "User email for git commits (defaults to the git user.email config)"
20
+ end
21
+ flag :file_path, "-o PATH", "--output=PATH" do
22
+ desc "Output file path (defaults to .toys/.data/releases.yml)"
23
+ end
24
+ flag :yes, "--yes", "-y" do
25
+ desc "Automatically answer yes to all confirmations"
26
+ end
27
+
28
+ include :exec, e: true
29
+ include :terminal, styled: true
30
+ include :fileutils
31
+
32
+ def run
33
+ setup
34
+ interpret_github_repo
35
+ interpret_git_user
36
+ check_file_path
37
+ gems_and_dirs = find_gems
38
+ confirm_with_user
39
+ mkdir_p(::File.dirname(file_path))
40
+ ::File.open(file_path, "w") do |file|
41
+ write_settings(file, gems_and_dirs)
42
+ end
43
+ puts("Wrote initial config file to #{file_path}.", :green, :bold)
44
+ end
45
+
46
+ def setup
47
+ require "toys/release/environment_utils"
48
+ @utils = Toys::Release::EnvironmentUtils.new(self)
49
+ cd(@utils.repo_root_directory)
50
+ end
51
+
52
+ def interpret_github_repo
53
+ return if repo
54
+ current_guess = nil
55
+ capture(["git", "remote", "-v"]).split("\n").each do |line|
56
+ match = %r{^(\S+)\s+git@github\.com:([^/.\s]+/[^/.\s]+)(?:\.git)?}.match(line)
57
+ current_guess = match[2] if match && (match[1] == "origin" || current_guess.nil?)
58
+ match = %r{^(\S+)\s+https://github\.com/([^/.\s]+/[^/.\s]+)(?:\.git)?}.match(line)
59
+ current_guess = match[2] if match && (match[1] == "origin" || current_guess.nil?)
60
+ end
61
+ if current_guess.nil?
62
+ puts "Unable to determine the GitHub repo associated with this repository.", :red, :bold
63
+ exit(1)
64
+ end
65
+ puts "GitHub repository inferred to be #{current_guess}."
66
+ puts "If this is incorrect, specify the correct repo using the --repo= flag."
67
+ set(:repo, current_guess)
68
+ end
69
+
70
+ def interpret_git_user
71
+ if git_user.empty?
72
+ set(:git_user, capture(["git", "config", "get", "user.name"]).strip)
73
+ if git_user.empty?
74
+ puts "Unable to determine git user.name. Using a hard-coded fallback", :yellow
75
+ set(:git_user, "Example User")
76
+ else
77
+ puts "Using the current git user.name of #{git_user}"
78
+ end
79
+ end
80
+ if git_email.empty?
81
+ set(:git_email, capture(["git", "config", "get", "user.email"]).strip)
82
+ if git_email.empty?
83
+ puts "Unable to determine git user.email. Using a hard-coded fallback", :yellow
84
+ set(:git_email, "hello@example.com")
85
+ else
86
+ puts "Using the current git user.email of #{git_email}"
87
+ end
88
+ end
89
+ end
90
+
91
+ def check_file_path
92
+ set(:file_path, ::File.join(".toys", ".data", "releases.yml")) unless file_path
93
+ if ::File.readable?(file_path)
94
+ puts "Cannot overwrite existing file: #{file_path}", :red, :bold
95
+ exit(1)
96
+ end
97
+ end
98
+
99
+ def confirm_with_user
100
+ exit unless yes || confirm("Create config file #{file_path}? ", default: true)
101
+ end
102
+
103
+ def find_gems
104
+ toplevel = ::Dir.glob("*.gemspec")
105
+ subdirs = ::Dir.glob("*/*.gemspec")
106
+ if toplevel.size > 1
107
+ puts "Unexpected: Found multiple gemspecs at the top level.", :red, :bold
108
+ exit(1)
109
+ end
110
+ if toplevel.size == 1 && subdirs.empty?
111
+ path = toplevel.first
112
+ puts "Found #{path} at the toplevel of the repo."
113
+ [[::File.basename(path, ".gemspec"), "."]]
114
+ elsif toplevel.empty? && !subdirs.empty?
115
+ subdirs.map do |path|
116
+ puts "Found #{path} in the repo."
117
+ [::File.basename(path, ".gemspec"), ::File.dirname(path)]
118
+ end
119
+ else
120
+ puts "Unexpected: Found gemspecs at the toplevel and in subdirectories.", :red, :bold
121
+ exit(1)
122
+ end
123
+ end
124
+
125
+ def write_settings(file, gems_and_dirs)
126
+ file.puts("repo: #{repo}")
127
+ file.puts("git_user_name: #{git_user}")
128
+ file.puts("git_user_email: #{git_email}")
129
+ file.puts("# Insert additional repo-level settings here.")
130
+ file.puts
131
+ file.puts("gems:")
132
+ gems_and_dirs.sort_by(&:first).each do |(name, dir)|
133
+ file.puts(" - name: #{name}")
134
+ file.puts(" directory: #{dir}")
135
+ file.puts(" # Insert additional gem-level settings here.")
136
+ end
137
+ end
@@ -5,12 +5,16 @@ desc "Generate GitHub Actions workflow files"
5
5
  long_desc \
6
6
  "This tool generates workflow files for GitHub Actions."
7
7
 
8
+ flag :workflows_dir, "-o PATH", "--output=PATH" do
9
+ desc "Output directory (defaults to .github/workflows)"
10
+ end
8
11
  flag :yes, "--yes", "-y" do
9
12
  desc "Automatically answer yes to all confirmations"
10
13
  end
11
14
 
12
- include :exec
15
+ include :exec, e: true
13
16
  include :terminal, styled: true
17
+ include :fileutils
14
18
 
15
19
  # Context for ERB templates
16
20
  class ErbContext
@@ -24,21 +28,35 @@ class ErbContext
24
28
  end
25
29
 
26
30
  def run
31
+ setup
32
+ user_confirmation
33
+ generate_all_files
34
+ end
35
+
36
+ def setup
27
37
  require "erb"
38
+ require "fileutils"
28
39
  require "toys/release/environment_utils"
29
40
  require "toys/release/repo_settings"
30
41
 
31
42
  @utils = Toys::Release::EnvironmentUtils.new(self)
43
+ cd(@utils.repo_root_directory)
32
44
  @settings = Toys::Release::RepoSettings.load_from_environment(@utils)
33
45
 
46
+ set(:workflows_dir, ::File.join(".github", "workflows")) if workflows_dir.to_s.empty?
47
+ end
48
+
49
+ def user_confirmation
34
50
  unless @settings.enable_release_automation?
35
51
  puts "Release automation disabled in settings."
36
52
  unless yes || confirm("Create workflow files anyway? ", default: false)
37
53
  @utils.error("Aborted.")
38
54
  end
39
55
  end
56
+ end
40
57
 
41
- @workflows_dir = ::File.join(context_directory, ".github", "workflows")
58
+ def generate_all_files
59
+ mkdir_p(workflows_dir)
42
60
  files = [
43
61
  "release-hook-on-closed.yml",
44
62
  "release-hook-on-push.yml",
@@ -46,12 +64,11 @@ def run
46
64
  "release-request.yml",
47
65
  "release-retry.yml",
48
66
  ]
49
-
50
- files.each { |name| generate(name) }
67
+ files.each { |name| generate_file(name) }
51
68
  end
52
69
 
53
- def generate(name)
54
- destination = ::File.join(@workflows_dir, name)
70
+ def generate_file(name)
71
+ destination = ::File.join(workflows_dir, name)
55
72
  if ::File.readable?(destination)
56
73
  puts "Destination file #{destination} exists.", :yellow, :bold
57
74
  return unless yes || confirm("Overwrite? ", default: true)
data/toys/perform.rb CHANGED
@@ -106,11 +106,13 @@ def run
106
106
 
107
107
  setup_arguments
108
108
  setup_performer
109
- components.each do |component_spec|
110
- name, version = component_spec.split(/[:=]/, 2)
111
- confirmation_ui(name, version)
112
- gem_version = version ? ::Gem::Version.new(version) : nil
113
- @performer.perform_adhoc_release(name, assert_version: gem_version)
109
+ unless @performer.error?
110
+ components.each do |component_spec|
111
+ name, version = component_spec.split(/[:=]/, 2)
112
+ confirmation_ui(name, version)
113
+ gem_version = version ? ::Gem::Version.new(version) : nil
114
+ @performer.perform_adhoc_release(name, assert_version: gem_version)
115
+ end
114
116
  end
115
117
  puts @performer.build_report_text
116
118
  end
data/toys/retry.rb CHANGED
@@ -18,12 +18,13 @@ flag_group desc: "Flags" do
18
18
  "Run in dry-run mode, where checks are made and releases are built" \
19
19
  " but are not pushed."
20
20
  end
21
- flag :gh_pages_dir, "--gh-pages-dir=VAL" do
22
- desc "The directory to use for the gh-pages branch"
21
+ flag :work_dir, "--work-dir=VAL" do
22
+ desc "The directory to use for artifacts and temporary files"
23
23
  long_desc \
24
- "Set to the path of a directory to use as the gh-pages workspace when" \
25
- " building and pushing gem documentation. If left unset, a temporary" \
26
- " directory will be created (and removed when finished)."
24
+ "If provided, the given directory path is used for artifacts and" \
25
+ " temporary files, and is left intact after the release so the" \
26
+ " artifacts can be inspected. If omitted, a new temporary directory" \
27
+ " is created, and is automatically deleted after the release."
27
28
  end
28
29
  flag :git_remote, "--git-remote=VAL" do
29
30
  default "origin"
@@ -84,13 +85,13 @@ def setup_objects
84
85
  @repo_settings = Toys::Release::RepoSettings.load_from_environment(@utils)
85
86
  @repository = Toys::Release::Repository.new(@utils, @repo_settings)
86
87
  @repository.git_set_user_info
88
+ @pull_request = @repository.load_pr(release_pr)
87
89
  end
88
90
 
89
91
  def verify_release_pr
90
- @pr_info = @repository.load_pr(release_pr)
91
- @utils.error("Could not load pull request ##{release_pr}") unless @pr_info
92
+ @utils.error("Could not load pull request ##{release_pr}") unless @pull_request
92
93
  expected_labels = [@repo_settings.release_pending_label, @repo_settings.release_error_label]
93
- return if @pr_info["labels"].any? { |label| expected_labels.include?(label["name"]) }
94
+ return if @pull_request.labels.any? { |label| expected_labels.include?(label) }
94
95
  warning = "PR #{release_pr} doesn't have the release pending or release error label."
95
96
  if yes
96
97
  logger.warn(warning)
@@ -102,12 +103,17 @@ def verify_release_pr
102
103
  end
103
104
 
104
105
  def setup_params
105
- [:gh_pages_dir, :rubygems_api_key].each do |key|
106
+ [
107
+ :git_remote,
108
+ :release_ref,
109
+ :rubygems_api_key,
110
+ :work_dir,
111
+ ].each do |key|
106
112
  set(key, nil) if get(key).to_s.empty?
107
113
  end
108
- ::ENV["GEM_HOST_API_KEY"] = rubygems_api_key if rubygems_api_key
109
114
  set(:dry_run, /^t/i.match?(::ENV["TOYS_RELEASE_DRY_RUN"].to_s)) if dry_run.nil?
110
- set :release_ref, @repository.current_sha(release_ref || @pr_info["merge_commit_sha"])
115
+ ::ENV["GEM_HOST_API_KEY"] = rubygems_api_key if rubygems_api_key
116
+ set :release_ref, @repository.current_sha(release_ref || @pull_request.merge_commit_sha)
111
117
  end
112
118
 
113
119
  def create_performer
@@ -116,14 +122,14 @@ def create_performer
116
122
  release_pr: release_pr,
117
123
  enable_prechecks: enable_prechecks,
118
124
  git_remote: git_remote,
119
- gh_pages_dir: gh_pages_dir,
125
+ work_dir: work_dir,
120
126
  dry_run: dry_run)
121
127
  end
122
128
 
123
129
  def perform_pending_releases
124
- @repository.wait_github_checks(release_ref) if enable_prechecks
130
+ @repository.wait_github_checks(ref: release_ref) if enable_prechecks
125
131
  performer = create_performer
126
- performer.perform_pr_releases
132
+ performer.perform_pr_releases unless performer.error?
127
133
  performer.report_results
128
134
  if performer.error?
129
135
  @utils.error("Releases reported failure")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toys-release
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Azuma
@@ -48,7 +48,6 @@ files:
48
48
  - toys/.data/templates/gh-pages-gitignore.erb
49
49
  - toys/.data/templates/gh-pages-index.html.erb
50
50
  - toys/.data/templates/release-hook-on-closed.yml.erb
51
- - toys/.data/templates/release-hook-on-open.yml.erb
52
51
  - toys/.data/templates/release-hook-on-push.yml.erb
53
52
  - toys/.data/templates/release-perform.yml.erb
54
53
  - toys/.data/templates/release-request.yml.erb
@@ -59,6 +58,7 @@ files:
59
58
  - toys/.lib/toys/release/component.rb
60
59
  - toys/.lib/toys/release/environment_utils.rb
61
60
  - toys/.lib/toys/release/performer.rb
61
+ - toys/.lib/toys/release/pipeline.rb
62
62
  - toys/.lib/toys/release/pull_request.rb
63
63
  - toys/.lib/toys/release/repo_settings.rb
64
64
  - toys/.lib/toys/release/repository.rb
@@ -69,11 +69,10 @@ files:
69
69
  - toys/.lib/toys/release/version_rb_file.rb
70
70
  - toys/.toys.rb
71
71
  - toys/_onclosed.rb
72
- - toys/_onopen.rb
73
72
  - toys/_onpush.rb
74
73
  - toys/create-labels.rb
74
+ - toys/gen-config.rb
75
75
  - toys/gen-gh-pages.rb
76
- - toys/gen-settings.rb
77
76
  - toys/gen-workflows.rb
78
77
  - toys/perform.rb
79
78
  - toys/request.rb
@@ -82,10 +81,10 @@ homepage: https://github.com/dazuma/toys
82
81
  licenses:
83
82
  - MIT
84
83
  metadata:
85
- changelog_uri: https://dazuma.github.io/toys/gems/toys-release/v0.1.1/file.CHANGELOG.html
84
+ changelog_uri: https://dazuma.github.io/toys/gems/toys-release/v0.3.0/file.CHANGELOG.html
86
85
  source_code_uri: https://github.com/dazuma/toys/tree/main/toys-release
87
86
  bug_tracker_uri: https://github.com/dazuma/toys/issues
88
- documentation_uri: https://dazuma.github.io/toys/gems/toys-release/v0.1.1
87
+ documentation_uri: https://dazuma.github.io/toys/gems/toys-release/v0.3.0
89
88
  rdoc_options: []
90
89
  require_paths:
91
90
  - lib
@@ -1,30 +0,0 @@
1
- name: "[release hook] Check commit messages"
2
-
3
- on:
4
- pull_request_target:
5
- types: [opened, edited, synchronize, reopened]
6
-
7
- jobs:
8
- release-check-commits:
9
- if: ${{ github.repository == '<%= @settings.repo_path %>' }}
10
- env:
11
- ruby_version: "3.4"
12
- runs-on: ubuntu-latest
13
- steps:
14
- - name: Install Ruby ${{ env.ruby_version }}
15
- uses: ruby/setup-ruby@v1
16
- with:
17
- ruby-version: ${{ env.ruby_version }}
18
- - name: Checkout repo
19
- uses: actions/checkout@v5
20
- with:
21
- ref: refs/pull/${{ github.event.pull_request.number }}/merge
22
- - name: Install Toys
23
- run: "gem install --no-document toys"
24
- - name: Check commit messages
25
- env:
26
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27
- run: |
28
- toys release _onopen --verbose \
29
- "--event-path=${{ github.event_path }}" \
30
- < /dev/null
data/toys/_onopen.rb DELETED
@@ -1,158 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- desc "Check a pull request"
4
-
5
- long_desc \
6
- "This tool is called by a GitHub Actions workflow when any pull request" \
7
- " is opened or synchronized. It checks the commit messages and/or pull" \
8
- " request title (as appropriate) for conventional commit style."
9
-
10
- flag :event_path, "--event-path=VAL" do
11
- default ::ENV["GITHUB_EVENT_PATH"]
12
- desc "Path to the pull request event JSON file"
13
- end
14
-
15
- include :exec
16
- include :terminal, styled: true
17
-
18
- def run
19
- setup
20
- lint_commit_messages if @utils.commit_lint_active?
21
- end
22
-
23
- def setup
24
- ::Dir.chdir(context_directory)
25
-
26
- require "json"
27
- require "toys/release/environment_utils"
28
- require "toys/release/pull_request"
29
- require "toys/release/repo_settings"
30
- require "toys/release/repository"
31
-
32
- @utils = Toys::Release::EnvironmentUtils.new(self)
33
- @settings = Toys::Release::RepoSettings.load_from_environment(@utils)
34
- @repository = Toys::Release::Repository.new(@utils, @settings)
35
-
36
- @utils.error("GitHub event path missing") unless event_path
37
- pr_resource = ::JSON.parse(::File.read(event_path))["pull_request"]
38
- @pull_request = Toys::Release::PullRequest.new(@repository, pr_resource)
39
- end
40
-
41
- def lint_commit_messages
42
- errors = []
43
- shas = find_shas
44
- if shas.size == 1 || !@settings.commit_lint_merge.intersection(["merge", "rebase"]).empty?
45
- lint_sha_messages(shas, errors)
46
- end
47
- if shas.size > 1 && @settings.commit_lint_merge.include?("squash")
48
- lint_pr_message(errors)
49
- end
50
- if errors.empty?
51
- puts "No conventional commit format problems found.", :green, :bold
52
- else
53
- report_lint_errors(errors)
54
- if @settings.commit_lint_fail_checks?
55
- @utils.error("Failing due to conventional commit format problems")
56
- end
57
- end
58
- end
59
-
60
- def find_shas
61
- @repository.git_unshallow("origin", branch: @pull_request.head_sha)
62
- log = capture(["git", "log", "#{@pull_request.base_sha}..#{@pull_request.head_sha}", "--format=%H"], e: true)
63
- shas = log.split("\n").reverse
64
- shas.find_all do |sha|
65
- parents = capture(["git", "show", "-s", "--pretty=%p", sha], e: true).strip.split
66
- @utils.log("Omitting merge commit #{sha}") if parents.size > 1
67
- parents.size == 1
68
- end
69
- end
70
-
71
- def lint_sha_messages(shas, errors)
72
- shas.each do |sha|
73
- @utils.log("Checking commit #{sha} ...")
74
- message = capture(["git", "log", "#{sha}^..#{sha}", "--format=%B"], e: true).strip
75
- lint_message(message) do |err|
76
- @utils.warning("Commit #{sha}: #{err}")
77
- suggestion = "Please consider amending the commit message."
78
- if @settings.commit_lint_merge == ["squash"]
79
- suggestion += " Alternately, because this pull request will be squashed when merged, you" \
80
- " can add multiple commits, and instead make sure the pull request _title_" \
81
- " conforms to the Conventional Commit format."
82
- end
83
- err =
84
- [
85
- "The message for commit #{sha} does not conform to the Conventional Commit format.",
86
- "",
87
- "```",
88
- ] + message.split("\n") + [
89
- "```",
90
- "",
91
- err,
92
- suggestion,
93
- ]
94
- errors << err
95
- end
96
- end
97
- end
98
-
99
- def lint_pr_message(errors)
100
- @utils.log("Checking Pull request title ...")
101
- lint_message(@pull_request.title) do |err|
102
- @utils.warning("PR title: #{err}")
103
- header = "The pull request title does not conform to the Conventional Commit format."
104
- header +=
105
- if @settings.commit_lint_merge == ["squash"]
106
- " (The title will be used as the merge commit message when this pull request is merged.)"
107
- else
108
- " (The title may be used as the merge commit message if this pull request is squashed" \
109
- " when merged.)"
110
- end
111
- errors << [
112
- header,
113
- "",
114
- "```",
115
- @pull_request.title,
116
- "```",
117
- "",
118
- err,
119
- ]
120
- end
121
- end
122
-
123
- def lint_message(message)
124
- lines = message.split("\n")
125
- matches = /^([\w-]+)(?:\(([^()]+)\))?!?:\s(.+)$/.match(lines.first)
126
- unless matches
127
- yield "The first line should follow the form `<type>: <description>`."
128
- return
129
- end
130
- allowed_types = @settings.commit_lint_allowed_types
131
- if allowed_types && !allowed_types.include?(matches[1].downcase)
132
- yield "The type `#{matches[1]}` is not allowed by this repository." \
133
- " Please use one of the types: `#{allowed_types.inspect}`."
134
- end
135
- if lines.size > 1 && !lines[1].empty?
136
- yield "You may not use multiple conventional commit formatted lines." \
137
- " If you want to include a body or footers in your commit message," \
138
- " they must be separated from the main message by a blank line." \
139
- " If you are making multiple semantic changes, please use separate" \
140
- " commits/pull requets."
141
- end
142
- end
143
-
144
- def report_lint_errors(errors)
145
- header = <<~STR
146
- Please use [Conventional Commit](https://conventionalcommits.org/) format \
147
- for commit messages and pull request titles. The automated linter found \
148
- the following problems in this pull request:
149
- STR
150
- lines = [header]
151
- errors.each do |error_lines|
152
- lines << "" << " * #{error_lines.first}"
153
- error_lines[1..].each do |err_line|
154
- lines << (err_line.empty? ? "" : " #{err_line}")
155
- end
156
- end
157
- @pull_request.add_comment(lines.join("\n"))
158
- end
data/toys/gen-settings.rb DELETED
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- desc "Generate initial settings file"
4
-
5
- long_desc \
6
- "This tool generates an initial settings file for this repo." \
7
- " You will generally need to make additional edits to this file after" \
8
- " initial generation."
9
-
10
- required_arg :repo do
11
- desc "GitHub repo owner and name (e.g. dazuma/toys)"
12
- end
13
-
14
- flag :yes, "--yes", "-y" do
15
- desc "Automatically answer yes to all confirmations"
16
- end
17
-
18
- include :exec
19
- include :terminal, styled: true
20
-
21
- def run
22
- file_path = ::File.join(context_directory, ".toys", ".data", "releases.yml")
23
- if ::File.readable?(file_path)
24
- puts "Cannot overwrite existing file: #{file_path}", :red, :bold
25
- exit(1)
26
- end
27
- return unless yes || confirm("Create file #{file_path}? ", default: true)
28
- ::File.open(file_path, "w") do |file|
29
- write_settings(file)
30
- end
31
- puts("Wrote initial settings file: #{file_path}.", :green, :bold)
32
- end
33
-
34
- def write_settings(file)
35
- file.puts("repo: #{repo}")
36
- file.puts("# Insert additional repo-level settings here.")
37
- file.puts
38
- file.puts("gems:")
39
- ::Dir.glob("**/*.gemspec").each do |gemspec|
40
- gem_name = ::File.basename(gemspec, ".gemspec")
41
- file.puts(" - name: #{gem_name}")
42
- dir = ::File.dirname(gemspec)
43
- file.puts(" directory: #{dir}") if dir != gem_name
44
- file.puts(" # Insert additional gem-level settings here.")
45
- end
46
- end