foobar_templates 2.0.0 → 2.0.1.rc1
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.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +24 -0
- data/.github/workflows/ci.yml +27 -0
- data/README.md +2 -1
- data/Rakefile +151 -5
- data/lib/foobar_templates/version.rb +1 -1
- data/spec/foobar_templates_spec.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 247c1ea143d5bffcb645aa6ee4ce0793a8962869b100e268c424697d77b8b4c8
|
|
4
|
+
data.tar.gz: c6fe7ccc5771db07b24c61d8d640f3516f2b73308d1937334df69069139658cd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 78e4608ba4ec94b0a0271f7753ae5b65d79cbbe6dec0a36d42cce040bdbd78353ba872158abce356cb82c0e98e1198eedf28becdc4956d36be0b3750821151db
|
|
7
|
+
data.tar.gz: fb918a1c50461ed3bc66e0c3c54fc1f0ba50ae0f0bcd04d381810a7009563fbfaec5142e3c111329c2c1f69b44df31c30b17f447ea6de45c0afa26527cb05d76
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
name: Build gem
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: ruby/setup-ruby@v1
|
|
14
|
+
with:
|
|
15
|
+
ruby-version: '3.3'
|
|
16
|
+
bundler-cache: true
|
|
17
|
+
- name: Build gem
|
|
18
|
+
run: bundle exec rake build
|
|
19
|
+
- name: Upload gem artifact
|
|
20
|
+
uses: actions/upload-artifact@v4
|
|
21
|
+
with:
|
|
22
|
+
name: foobar_templates-gem
|
|
23
|
+
path: pkg/*.gem
|
|
24
|
+
if-no-files-found: error
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
name: Test (Ruby ${{ matrix.ruby }})
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
continue-on-error: ${{ matrix.experimental || false }}
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
ruby: ['3.0', '3.2', '3.3', '3.4', '4.0']
|
|
17
|
+
include:
|
|
18
|
+
- ruby: head
|
|
19
|
+
experimental: true
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- uses: ruby/setup-ruby@v1
|
|
23
|
+
with:
|
|
24
|
+
ruby-version: ${{ matrix.ruby }}
|
|
25
|
+
bundler-cache: true
|
|
26
|
+
- name: Run specs
|
|
27
|
+
run: bundle exec rake spec
|
data/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Foobar Templates: A Pain-Free Project Templator
|
|
2
|
-
[](https://badge.fury.io/rb/foobar_templates)
|
|
2
|
+
[](https://badge.fury.io/rb/foobar_templates)
|
|
3
3
|
|
|
4
4
|
Foobar Templates allow users to define project templates in the most native form to all technologist: Directory Structures, short commands, and helpful commands that make the tool's usage completely visible!
|
|
5
5
|
|
|
@@ -14,6 +14,7 @@ I highly recommend the `foobar` alias!
|
|
|
14
14
|
```bash
|
|
15
15
|
gem install foobar_templates
|
|
16
16
|
foobar_templates --install-public-templates
|
|
17
|
+
foobar_templates --setup-personal-templates
|
|
17
18
|
|
|
18
19
|
echo "alias foobar='foobar_templates'" >> ~/.bashrc
|
|
19
20
|
source ~/.bashrc
|
data/Rakefile
CHANGED
|
@@ -1,13 +1,119 @@
|
|
|
1
1
|
require 'rake'
|
|
2
|
+
require 'rubygems'
|
|
2
3
|
require 'rspec/core/rake_task'
|
|
3
4
|
|
|
4
5
|
GEM_NAME = "foobar_templates"
|
|
5
6
|
GEM_SPEC = "#{GEM_NAME}.gemspec"
|
|
7
|
+
VERSION_FILE = "lib/#{GEM_NAME}/version.rb"
|
|
8
|
+
|
|
9
|
+
module ReleaseHelper
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
# Prerelease syntax: `MAJOR.MINOR.PATCH.rcN` (e.g. `2.0.1.rc1`).
|
|
13
|
+
# Gem apparently doesn't support semver's `-` syntax =/
|
|
14
|
+
RC_RE = /\A(\d+)\.(\d+)\.(\d+)\.rc(\d+)\z/
|
|
15
|
+
REL_RE = /\A(\d+)\.(\d+)\.(\d+)\z/
|
|
16
|
+
|
|
17
|
+
def dry_run?
|
|
18
|
+
ENV['RELEASE_DRY_RUN'] == '1'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def current_version
|
|
22
|
+
src = File.read(VERSION_FILE)
|
|
23
|
+
m = src.match(/VERSION\s*=\s*"([^"]+)"/)
|
|
24
|
+
abort "Could not parse VERSION from #{VERSION_FILE}" unless m
|
|
25
|
+
m[1]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def next_version(v)
|
|
29
|
+
if (m = v.match(RC_RE))
|
|
30
|
+
maj, min, pat, rc = m.captures.map(&:to_i)
|
|
31
|
+
"#{maj}.#{min}.#{pat}.rc#{rc + 1}"
|
|
32
|
+
elsif (m = v.match(REL_RE))
|
|
33
|
+
maj, min, pat = m.captures.map(&:to_i)
|
|
34
|
+
"#{maj}.#{min}.#{pat + 1}.rc1"
|
|
35
|
+
else
|
|
36
|
+
abort "Unrecognized version format: #{v.inspect} (expected MAJOR.MINOR.PATCH or MAJOR.MINOR.PATCH.rcN)"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def write_version!(new_version)
|
|
41
|
+
src = File.read(VERSION_FILE)
|
|
42
|
+
updated = src.sub(/VERSION\s*=\s*"[^"]+"/, %(VERSION = "#{new_version}"))
|
|
43
|
+
File.write(VERSION_FILE, updated)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def confirm!(prompt, default: false)
|
|
47
|
+
suffix = default ? "[Y/n]" : "[y/N]"
|
|
48
|
+
print "#{prompt} #{suffix} "
|
|
49
|
+
answer = $stdin.gets&.strip
|
|
50
|
+
return default if answer.nil? || answer.empty?
|
|
51
|
+
%w[y yes].include?(answer.downcase)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def sh!(cmd)
|
|
55
|
+
puts "+ #{cmd}"
|
|
56
|
+
abort "command failed: #{cmd}" unless system(cmd)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def push!(cmd)
|
|
60
|
+
if dry_run?
|
|
61
|
+
puts "[DRY-RUN] would run: #{cmd}"
|
|
62
|
+
else
|
|
63
|
+
sh!(cmd)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def ensure_clean_git!
|
|
68
|
+
out = `git status --porcelain`
|
|
69
|
+
return if out.strip.empty?
|
|
70
|
+
abort "Working tree is dirty. Commit or stash changes before releasing.\n#{out}"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def ensure_on_default_branch!
|
|
74
|
+
branch = `git rev-parse --abbrev-ref HEAD`.strip
|
|
75
|
+
return if %w[main master].include?(branch)
|
|
76
|
+
return if confirm!("You are on branch '#{branch}', not main/master. Continue?", default: false)
|
|
77
|
+
abort "Aborted by user."
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def working_tree_changed?
|
|
81
|
+
!`git status --porcelain`.strip.empty?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Make sure this machine has push access to the gem repository
|
|
85
|
+
def preflight!
|
|
86
|
+
problems = []
|
|
87
|
+
|
|
88
|
+
cred_paths = [
|
|
89
|
+
File.expand_path("~/.gem/credentials"),
|
|
90
|
+
File.expand_path("~/.local/share/gem/credentials"),
|
|
91
|
+
]
|
|
92
|
+
cred_path = cred_paths.find { |p| File.exist?(p) }
|
|
93
|
+
if cred_path.nil?
|
|
94
|
+
problems << "No rubygems credentials found (looked in #{cred_paths.join(', ')}). Run `gem signin`."
|
|
95
|
+
elsif (File.stat(cred_path).mode & 0o077) != 0
|
|
96
|
+
problems << "Rubygems credentials at #{cred_path} are world/group-readable. Run: chmod 0600 #{cred_path}"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
unless problems.empty?
|
|
100
|
+
abort "Release preflight failed:\n - #{problems.join("\n - ")}"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
puts "Checking rubygems push access for #{GEM_NAME}..."
|
|
104
|
+
owners_out = `gem owner #{GEM_NAME} </dev/null 2>&1`
|
|
105
|
+
unless $?.success?
|
|
106
|
+
abort "Cannot query rubygems owners for #{GEM_NAME}:\n#{owners_out}\nRun `gem signin` and ensure your API key has push scope."
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
6
110
|
|
|
7
111
|
desc "Build #{GEM_NAME} gem"
|
|
8
112
|
task :build do
|
|
9
|
-
system "gem build #{GEM_SPEC}"
|
|
10
113
|
FileUtils.mkdir_p "pkg"
|
|
114
|
+
FileUtils.rm_f Dir.glob("pkg/#{GEM_NAME}-*.gem")
|
|
115
|
+
FileUtils.rm_f Dir.glob("#{GEM_NAME}-*.gem")
|
|
116
|
+
system "gem build #{GEM_SPEC}"
|
|
11
117
|
FileUtils.mv Dir.glob("#{GEM_NAME}-*.gem"), "pkg/"
|
|
12
118
|
end
|
|
13
119
|
|
|
@@ -16,10 +122,50 @@ task install: :build do
|
|
|
16
122
|
system "gem install pkg/#{Dir.children('pkg').sort.last}"
|
|
17
123
|
end
|
|
18
124
|
|
|
19
|
-
desc "
|
|
20
|
-
task release
|
|
21
|
-
|
|
22
|
-
|
|
125
|
+
desc "Interactive local release: confirm version, run specs, build, tag, push, and bump"
|
|
126
|
+
task :release do
|
|
127
|
+
include_helper = ReleaseHelper
|
|
128
|
+
|
|
129
|
+
include_helper.ensure_clean_git!
|
|
130
|
+
include_helper.ensure_on_default_branch!
|
|
131
|
+
include_helper.preflight!
|
|
132
|
+
|
|
133
|
+
version = include_helper.current_version
|
|
134
|
+
puts "Current version in #{VERSION_FILE}: #{version}"
|
|
135
|
+
unless include_helper.confirm!("Release version #{version}?", default: false)
|
|
136
|
+
puts "Aborted. Edit #{VERSION_FILE} to change the version, then re-run `rake release`."
|
|
137
|
+
exit 0
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
Rake::Task[:spec].invoke
|
|
141
|
+
Rake::Task[:build].invoke
|
|
142
|
+
|
|
143
|
+
gem_file = "pkg/#{GEM_NAME}-#{version}.gem"
|
|
144
|
+
abort "Built gem not found at #{gem_file}" unless File.exist?(gem_file)
|
|
145
|
+
|
|
146
|
+
if include_helper.working_tree_changed?
|
|
147
|
+
include_helper.sh! "git add #{VERSION_FILE}"
|
|
148
|
+
include_helper.sh! %(git commit -m "Release v#{version}")
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
tag = "v#{version}"
|
|
152
|
+
include_helper.sh! %(git tag -a #{tag} -m "Release #{tag}")
|
|
153
|
+
include_helper.push! "git push origin HEAD"
|
|
154
|
+
include_helper.push! "git push origin #{tag}"
|
|
155
|
+
include_helper.push! "gem push #{gem_file}"
|
|
156
|
+
|
|
157
|
+
next_v = include_helper.next_version(version)
|
|
158
|
+
include_helper.write_version!(next_v)
|
|
159
|
+
include_helper.sh! "git add #{VERSION_FILE}"
|
|
160
|
+
include_helper.sh! %(git commit -m "Bump to v#{next_v}")
|
|
161
|
+
include_helper.push! "git push origin HEAD"
|
|
162
|
+
|
|
163
|
+
puts ""
|
|
164
|
+
puts "=" * 60
|
|
165
|
+
puts "Released: #{tag}"
|
|
166
|
+
puts "Next development version: #{next_v}"
|
|
167
|
+
puts "Tag: https://github.com/TheNotary/#{GEM_NAME}/releases/tag/#{tag}"
|
|
168
|
+
puts "=" * 60
|
|
23
169
|
end
|
|
24
170
|
|
|
25
171
|
desc "Run unit specs"
|
|
@@ -506,7 +506,7 @@ describe FoobarTemplates do
|
|
|
506
506
|
|
|
507
507
|
before :each do
|
|
508
508
|
# Default: no remote — skip network calls.
|
|
509
|
-
allow(FoobarTemplates).to receive(:remote_repo_exists?).and_return(false)
|
|
509
|
+
allow(FoobarTemplates::CLI::SetupPersonalTemplatesRepo).to receive(:remote_repo_exists?).and_return(false)
|
|
510
510
|
end
|
|
511
511
|
|
|
512
512
|
it "errors when repo_domain is not configured" do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foobar_templates
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.1.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- TheNotary
|
|
@@ -83,6 +83,8 @@ files:
|
|
|
83
83
|
- ".beader/issues/6-add-monorepo-discovery-and-generation-test-coverage.yaml"
|
|
84
84
|
- ".beader/issues/7-document-monorepo-template-configuration-and-selection.yaml"
|
|
85
85
|
- ".beader/meta.yaml"
|
|
86
|
+
- ".github/workflows/build.yml"
|
|
87
|
+
- ".github/workflows/ci.yml"
|
|
86
88
|
- ".gitignore"
|
|
87
89
|
- ".rspec"
|
|
88
90
|
- Gemfile
|
|
@@ -128,9 +130,9 @@ licenses:
|
|
|
128
130
|
- MIT
|
|
129
131
|
metadata:
|
|
130
132
|
bug_tracker_uri: https://github.com/TheNotary/foobar_templates/issues
|
|
131
|
-
changelog_uri: https://github.com/TheNotary/foobar_templates/releases/tag/v2.0.
|
|
133
|
+
changelog_uri: https://github.com/TheNotary/foobar_templates/releases/tag/v2.0.1.rc1
|
|
132
134
|
documentation_uri: https://github.com/TheNotary/foobar_templates
|
|
133
|
-
source_code_uri: https://github.com/TheNotary/foobar_templates/tree/v2.0.
|
|
135
|
+
source_code_uri: https://github.com/TheNotary/foobar_templates/tree/v2.0.1.rc1
|
|
134
136
|
rdoc_options: []
|
|
135
137
|
require_paths:
|
|
136
138
|
- lib
|