gran 0.1.0 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 565f612153803ad8451b299b172a4880bd9f98149c279773344a5e56043ea3ec
4
- data.tar.gz: 027ff3712bde1dae0fa350fb2842efba6a4e120194d29823345629109b7fb9bb
3
+ metadata.gz: 5ca48cfaefe9ad306ea4df075602e8a86e06517a3f170b2733e464b417fdc928
4
+ data.tar.gz: 88b4f8d7027278c9e1bb6fd860edd92311ab3b68d0f02b30362579fc819e43e1
5
5
  SHA512:
6
- metadata.gz: 813be36fdbb481c4d18ef6c9677865ae15d9c8c17296a841ccbda231ee293c99ac2115b7637900cd55f9244db01b479ded46b405461e0f4d78d7b29e9b7594bd
7
- data.tar.gz: 732312e0d45347ecb4bd9893a84f67d50be0a39567607b6176ed4cf337204430bc0a0dd184d7efb4789fdfe8bc49a183ee16a54abdbb4b9f1dfef3e210312557
6
+ metadata.gz: 22c850b8eaa92af1debc66a73b79d5e1c59dafbe3477fa0f0ad9f03309b3647339959587d84fe7244638ab3bb7105868db0f62afb49cf553529f9ddc8ac77d1f
7
+ data.tar.gz: f0e9fdb5ac431a95354446344322e4bf11c055e4ee19d355bd47e802080060be91e5555c4b0a1e2ca50aa590686db15279d1967b952822c40999864ae7b50e72
data/CHANGELOG.md CHANGED
@@ -1,4 +1,7 @@
1
- ## [Unreleased]
1
+ ## [0.1.1] - 2025-10-19
2
+
3
+ - update release scripts
4
+ - fix linting
2
5
 
3
6
  ## [0.1.0] - 2024-09-29
4
7
 
data/lib/gran/pathtree.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require "pathname"
2
- require "set"
3
2
  require_relative "loggable"
4
3
 
5
4
  module Gran
@@ -456,7 +455,7 @@ module Gran
456
455
  result = []
457
456
 
458
457
  traverse_preorder do |level, node|
459
- q = from_root ? node.pathname : Pathname(segment) +
458
+ q = from_root ? node.pathname : Pathname(segment) /
460
459
  node.pathname.relative_path_from(pathname)
461
460
  result << node if q.to_s.include?(sub_str)
462
461
  end
data/lib/gran/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gran
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
@@ -0,0 +1,338 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "pathname"
5
+ require "optparse"
6
+ require "fileutils"
7
+
8
+ # Release automation script for gran gem
9
+ class GranReleaseManager
10
+ GRAN_DIR = Pathname.new(__dir__).parent
11
+
12
+ VALID_COMMANDS = %w[prepare publish all].freeze
13
+ VALID_VERSION_TYPES = %w[major minor patch].freeze
14
+
15
+ attr_reader :command, :version_type, :dry_run, :yes, :specific_version
16
+
17
+ def initialize(args)
18
+ @dry_run = false
19
+ @yes = false
20
+ @specific_version = nil
21
+ parse_options(args)
22
+ validate_args
23
+ end
24
+
25
+ def run
26
+ puts "\n=== Gran Release Manager ==="
27
+ puts "Command: #{command}"
28
+ puts "Version: #{version_type || specific_version}"
29
+ puts "Dry-run: #{dry_run}"
30
+ puts "============================\n\n"
31
+
32
+ case command
33
+ when "prepare"
34
+ prepare_release
35
+ when "publish"
36
+ publish_release
37
+ when "all"
38
+ prepare_release
39
+ publish_release
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def parse_options(args)
46
+ OptionParser.new do |opts|
47
+ opts.banner = "Usage: release.rb [options] COMMAND [VERSION]"
48
+ opts.separator ""
49
+ opts.separator "COMMAND: #{VALID_COMMANDS.join(", ")}"
50
+ opts.separator "VERSION: #{VALID_VERSION_TYPES.join(", ")} or specific version (e.g., 0.2.0)"
51
+ opts.separator ""
52
+ opts.separator "Options:"
53
+
54
+ opts.on("-n", "--dry-run", "Show what would happen without doing it") do
55
+ @dry_run = true
56
+ end
57
+
58
+ opts.on("-y", "--yes", "Skip confirmation prompts") do
59
+ @yes = true
60
+ end
61
+
62
+ opts.on("-h", "--help", "Show this help message") do
63
+ puts opts
64
+ exit 0
65
+ end
66
+ end.parse!(args)
67
+
68
+ @command = args[0]
69
+
70
+ # Parse version argument
71
+ if args[1]
72
+ if VALID_VERSION_TYPES.include?(args[1])
73
+ @version_type = args[1]
74
+ elsif args[1].match?(/^\d+\.\d+\.\d+$/)
75
+ @specific_version = args[1]
76
+ else
77
+ puts "ERROR: Invalid version '#{args[1]}'. Must be #{VALID_VERSION_TYPES.join(", ")} or a version number (e.g., 0.2.0)"
78
+ exit 1
79
+ end
80
+ end
81
+ end
82
+
83
+ def validate_args
84
+ unless VALID_COMMANDS.include?(command)
85
+ puts "ERROR: Invalid command '#{command}'. Must be one of: #{VALID_COMMANDS.join(", ")}"
86
+ exit 1
87
+ end
88
+
89
+ if command != "publish" && version_type.nil? && specific_version.nil?
90
+ puts "ERROR: VERSION argument required for '#{command}' command"
91
+ exit 1
92
+ end
93
+ end
94
+
95
+ def prepare_release
96
+ puts "\n📦 Preparing gran for release...\n"
97
+ with_dir(GRAN_DIR) do
98
+ run_safety_checks
99
+ new_version = bump_version(GRAN_DIR / "lib/gran/version.rb")
100
+ update_changelog(new_version)
101
+ build_gem
102
+ create_git_commit_and_tag(new_version)
103
+ success("Gran prepared for release: v#{new_version}")
104
+ end
105
+ end
106
+
107
+ def publish_release
108
+ puts "\n🚀 Publishing gran to RubyGems...\n"
109
+ with_dir(GRAN_DIR) do
110
+ push_to_github
111
+ publish_gem
112
+ success("Gran published!")
113
+ end
114
+ end
115
+
116
+ # Safety Checks
117
+ def run_safety_checks
118
+ step("Running safety checks")
119
+ check_git_status
120
+ check_on_main_branch
121
+ run_tests
122
+ run_linter
123
+ end
124
+
125
+ def check_git_status
126
+ output = `git status --porcelain`.strip
127
+ unless output.empty?
128
+ error("Working directory is not clean. Commit or stash changes first.")
129
+ end
130
+ end
131
+
132
+ def check_on_main_branch
133
+ branch = `git rev-parse --abbrev-ref HEAD`.strip
134
+ unless branch == "main"
135
+ unless confirm("You are on branch '#{branch}', not 'main'. Continue anyway?")
136
+ error("Aborted. Switch to main branch or use --yes to override.")
137
+ end
138
+ end
139
+ end
140
+
141
+ def run_tests
142
+ step("Running tests")
143
+ unless system("bundle exec rake test > /dev/null 2>&1")
144
+ error("Tests failed! Fix tests before releasing.")
145
+ end
146
+ end
147
+
148
+ def run_linter
149
+ step("Running linter")
150
+ unless system("bundle exec rake standard > /dev/null 2>&1")
151
+ error("Linter failed! Fix linting issues before releasing.")
152
+ end
153
+ end
154
+
155
+ # Version Management
156
+ def bump_version(version_file)
157
+ current_version = extract_version(version_file)
158
+ new_version = calculate_new_version(current_version)
159
+
160
+ puts "Current version: #{current_version}"
161
+ puts "New version: #{new_version}"
162
+
163
+ unless confirm("Bump version to #{new_version}?")
164
+ error("Aborted by user")
165
+ end
166
+
167
+ update_version_file(version_file, current_version, new_version)
168
+ new_version
169
+ end
170
+
171
+ def extract_version(version_file)
172
+ content = File.read(version_file)
173
+ if content =~ /VERSION\s*=\s*"([\d.]+)"/
174
+ $1
175
+ else
176
+ error("Could not find VERSION in #{version_file}")
177
+ end
178
+ end
179
+
180
+ def calculate_new_version(current)
181
+ return specific_version if specific_version
182
+
183
+ parts = current.split(".").map(&:to_i)
184
+ case version_type
185
+ when "major"
186
+ "#{parts[0] + 1}.0.0"
187
+ when "minor"
188
+ "#{parts[0]}.#{parts[1] + 1}.0"
189
+ when "patch"
190
+ "#{parts[0]}.#{parts[1]}.#{parts[2] + 1}"
191
+ end
192
+ end
193
+
194
+ def update_version_file(version_file, old_version, new_version)
195
+ content = File.read(version_file)
196
+ content.gsub!(/VERSION\s*=\s*"#{Regexp.escape(old_version)}"/,
197
+ "VERSION = \"#{new_version}\"")
198
+
199
+ if dry_run
200
+ puts "[DRY-RUN] Would update #{version_file.basename} to #{new_version}"
201
+ else
202
+ File.write(version_file, content)
203
+ puts "✓ Updated #{version_file.basename}"
204
+ end
205
+ end
206
+
207
+ # Changelog
208
+ def update_changelog(version)
209
+ step("Updating CHANGELOG")
210
+ puts "⚠️ Please update the CHANGELOG manually with changes for v#{version}"
211
+ puts "Press Enter when done..."
212
+ $stdin.gets unless yes
213
+ end
214
+
215
+ # Gem Operations
216
+ def build_gem
217
+ step("Building gran gem")
218
+
219
+ if dry_run
220
+ puts "[DRY-RUN] Would run: gem build gran.gemspec"
221
+ else
222
+ unless system("gem build gran.gemspec")
223
+ error("Failed to build gem")
224
+ end
225
+ puts "✓ Gem built successfully"
226
+ end
227
+ end
228
+
229
+ def publish_gem
230
+ gem_file = Dir.glob("gran-*.gem").max_by { |f| File.mtime(f) }
231
+
232
+ unless gem_file
233
+ error("No gem file found to publish")
234
+ end
235
+
236
+ step("Publishing #{gem_file}")
237
+
238
+ unless confirm("Push #{gem_file} to RubyGems.org?")
239
+ error("Aborted by user")
240
+ end
241
+
242
+ if dry_run
243
+ puts "[DRY-RUN] Would run: gem push #{gem_file}"
244
+ else
245
+ unless system("gem push #{gem_file}")
246
+ error("Failed to publish gem")
247
+ end
248
+ puts "✓ Gem published successfully"
249
+ end
250
+ end
251
+
252
+ # Git Operations
253
+ def create_git_commit_and_tag(version)
254
+ tag_name = "gran-v#{version}"
255
+ commit_message = "Release gran v#{version}"
256
+
257
+ step("Creating git commit and tag")
258
+
259
+ if dry_run
260
+ puts "[DRY-RUN] Would run:"
261
+ puts " git add ."
262
+ puts " git commit -m '#{commit_message}'"
263
+ puts " git tag -a #{tag_name} -m '#{commit_message}'"
264
+ else
265
+ system("git add .")
266
+ unless system("git commit -m '#{commit_message}'")
267
+ error("Failed to create commit")
268
+ end
269
+ unless system("git tag -a #{tag_name} -m '#{commit_message}'")
270
+ error("Failed to create tag")
271
+ end
272
+ puts "✓ Created commit and tag: #{tag_name}"
273
+ end
274
+ end
275
+
276
+ def push_to_github
277
+ step("Pushing to GitHub")
278
+
279
+ unless confirm("Push commits and tags to GitHub?")
280
+ error("Aborted by user")
281
+ end
282
+
283
+ if dry_run
284
+ puts "[DRY-RUN] Would run:"
285
+ puts " git push origin main"
286
+ puts " git push origin --tags"
287
+ else
288
+ unless system("git push origin main")
289
+ error("Failed to push commits")
290
+ end
291
+ unless system("git push origin --tags")
292
+ error("Failed to push tags")
293
+ end
294
+ puts "✓ Pushed to GitHub"
295
+ end
296
+ end
297
+
298
+ # Helpers
299
+ def with_dir(dir)
300
+ original_dir = Dir.pwd
301
+ Dir.chdir(dir)
302
+ yield
303
+ ensure
304
+ Dir.chdir(original_dir)
305
+ end
306
+
307
+ def confirm(message)
308
+ return true if yes
309
+ print "#{message} (y/N): "
310
+ response = $stdin.gets.strip.downcase
311
+ response == "y" || response == "yes"
312
+ end
313
+
314
+ def step(message)
315
+ puts "\n→ #{message}..."
316
+ end
317
+
318
+ def success(message)
319
+ puts "\n✓ #{message}\n"
320
+ end
321
+
322
+ def error(message)
323
+ puts "\n✗ ERROR: #{message}\n"
324
+ exit 1
325
+ end
326
+ end
327
+
328
+ # Run the script
329
+ if __FILE__ == $0
330
+ if ARGV.empty?
331
+ puts "Usage: release.rb [options] COMMAND [VERSION]"
332
+ puts "Run with --help for more information"
333
+ exit 1
334
+ end
335
+
336
+ manager = GranReleaseManager.new(ARGV)
337
+ manager.run
338
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gran
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anders Rillbert
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-17 00:00:00.000000000 Z
11
+ date: 2025-10-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Provides classes for creatting and transforming trees of PathName nodes
14
14
  email:
@@ -28,6 +28,7 @@ files:
28
28
  - lib/gran/pathtree.rb
29
29
  - lib/gran/tree_transformer.rb
30
30
  - lib/gran/version.rb
31
+ - scripts/release.rb
31
32
  homepage: https://github.com/rillbert/giblish/tree/main/gran
32
33
  licenses:
33
34
  - MIT