gemvault 0.2.0 → 0.2.3
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/.rubocop.yml +1 -0
- data/.rubycritic.yml +15 -0
- data/CHANGELOG.md +31 -0
- data/CLAUDE.md +81 -16
- data/Dockerfile.test +56 -17
- data/Rakefile +27 -14
- data/_claude/archives/issue-13-root-cause.md +197 -0
- data/docs/Rakefile.vault_example +76 -0
- data/issues.rec +351 -15
- data/lib/gemvault/cli/commands/new.rb +16 -8
- data/lib/gemvault/cli/destination.rb +29 -0
- data/lib/gemvault/vault.rb +5 -0
- data/lib/gemvault/vault_destination.rb +70 -0
- data/lib/gemvault/version.rb +1 -1
- metadata +12 -8
- data/LICENSE +0 -21
- /data/{ASSESSMENT.md → _claude/archives/ASSESSMENT.md} +0 -0
- /data/{MACROPLAN.md → _claude/archives/MACROPLAN.md} +0 -0
- /data/{docs/superpowers → _claude/archives}/plans/2026-04-16-container-integration-tests.md +0 -0
- /data/{docs → _claude/archives}/tarvault-findings.md +0 -0
- /data/{docs → _claude/archives}/tarvault.md +0 -0
data/issues.rec
CHANGED
|
@@ -57,9 +57,9 @@ Description: Installing bundler-source-vault 0.1.2
|
|
|
57
57
|
+ from /Users/davidgillis/.rbenv/versions/4.0.1/lib/ruby/site_ruby/4.0.0/rubygems.rb:304:in 'Gem.activate_and_load_bin_path'
|
|
58
58
|
+ from /Users/davidgillis/.rbenv/versions/4.0.1/bin/bundle:25:in '<main>'
|
|
59
59
|
+ /Users/davidgillis/.rbenv/versions/4.0.1/lib/ruby/gems/4.0.0/gems/bundler-4.0.8/lib/bundler/source_list.rb:59:in 'Bundler::SourceList#add_plugin_source': undefined method 'new' for nil (NoMethodError)
|
|
60
|
-
+
|
|
60
|
+
+
|
|
61
61
|
+ add_source_to_list Plugin.source(source).new(options), @plugin_sources
|
|
62
|
-
+
|
|
62
|
+
+
|
|
63
63
|
+ RESOLUTION: replicated by spec/integration/bundle_install_spec.rb ("path-installed
|
|
64
64
|
+ bundler plugin's source directory has been renamed"): Bundler's plugin index pins
|
|
65
65
|
+ the absolute path, and `gemvault doctor` clears it and reinstalls. Installing the
|
|
@@ -86,7 +86,7 @@ Description: Steps to replicate:
|
|
|
86
86
|
+ ```
|
|
87
87
|
+
|
|
88
88
|
+ Where vendored.gemv is the name of the old file, and there is still an entry in Gemfile.lock
|
|
89
|
-
+
|
|
89
|
+
+
|
|
90
90
|
+ RESOLUTION: fixed on the tarvault branch; replicated by
|
|
91
91
|
+ spec/integration/bundle_install_spec.rb ("when the .gemv file is renamed and the
|
|
92
92
|
+ Gemfile updated to match"), passing.
|
|
@@ -101,7 +101,7 @@ Description: This vault is in vendor/vendored_gems.gmv, relative to the Gemfile
|
|
|
101
101
|
+ ```
|
|
102
102
|
+ Installing acme 1.0.1 from vault vendored_gems.gemv
|
|
103
103
|
+ ```
|
|
104
|
-
+
|
|
104
|
+
+
|
|
105
105
|
+ RESOLUTION: fixed on the tarvault branch; replicated by
|
|
106
106
|
+ spec/integration/bundle_install_spec.rb ("logs the relative path as written"),
|
|
107
107
|
+ passing.
|
|
@@ -122,7 +122,7 @@ Description: Anytime I run bundle install, I always see:
|
|
|
122
122
|
+ ```
|
|
123
123
|
+
|
|
124
124
|
+ This is unacceptable. these should only need to be installed once
|
|
125
|
-
+
|
|
125
|
+
+
|
|
126
126
|
+ ANALYSIS: upstream Bundler behavior. Bundler::Plugin.gemfile_install runs on
|
|
127
127
|
+ every `bundle install`/`bundle update` (bundler cli/install.rb:41), re-resolves
|
|
128
128
|
+ the inferred plugin definition remotely, and Source::Rubygems#install checks
|
|
@@ -143,7 +143,7 @@ Description: Consider the following:
|
|
|
143
143
|
+ ```
|
|
144
144
|
+
|
|
145
145
|
+ Notice an absolute path was passed to --source, yet it tried to resolve locally
|
|
146
|
-
+
|
|
146
|
+
+
|
|
147
147
|
+ RESOLUTION: fixed on the tarvault branch; replicated by
|
|
148
148
|
+ spec/integration/gem_install_spec.rb ("accepts a vault:// URI with an absolute
|
|
149
149
|
+ path" and the file:// variant), passing. URI stripping now lives in
|
|
@@ -158,7 +158,7 @@ Description: When adding a gem like 'ronin-db-0.2.1.patch1.gem', gemvault succes
|
|
|
158
158
|
+ gemvault add myvault.gemv ronin-db-0.2.1.patch1.gem # success
|
|
159
159
|
+ gem install --debug --verbose --clear-sources --source file://myvault.gemv ronin-db # failure
|
|
160
160
|
+ ```
|
|
161
|
-
+
|
|
161
|
+
+
|
|
162
162
|
+ RESOLUTION: RubyGems semantics, not a vault bug. A version containing letters
|
|
163
163
|
+ (0.2.1.patch1) is a prerelease everywhere in RubyGems, and `gem install`
|
|
164
164
|
+ excludes prereleases unless --pre is passed; with --pre the install from a
|
|
@@ -171,7 +171,7 @@ Id: 7
|
|
|
171
171
|
Updated: Sun, 19 Jul 2026 03:27:39 +0000
|
|
172
172
|
Name: Gemvault pollutes project dir with plugin files in .bundle
|
|
173
173
|
Description: Why is it not using the plugin that is already installed globally?
|
|
174
|
-
+
|
|
174
|
+
+
|
|
175
175
|
+ ANALYSIS: two parts. (1) Global `bundle plugin install bundler-source-vault`
|
|
176
176
|
+ crashed outright (issue #10's bug also hit the global root); that is fixed and
|
|
177
177
|
+ covered by spec/integration/plugin_install_spec.rb ("when run outside any
|
|
@@ -192,7 +192,7 @@ Description: Consider the following:
|
|
|
192
192
|
+ ```
|
|
193
193
|
+
|
|
194
194
|
+ Notice an absolute path was passed to --source, yet it tried to resolve locally
|
|
195
|
-
+
|
|
195
|
+
+
|
|
196
196
|
+ RESOLUTION: duplicate of #5; see its resolution.
|
|
197
197
|
Status: closed
|
|
198
198
|
|
|
@@ -200,7 +200,7 @@ Id: 9
|
|
|
200
200
|
Updated: Sun, 19 Jul 2026 03:27:39 +0000
|
|
201
201
|
Name: Gemvault commands should also be able to accept a uri
|
|
202
202
|
Description: e.g. gemvault list vault:///Users/davidgillis/repos/vault/rubylib/myvault.gemv
|
|
203
|
-
+
|
|
203
|
+
+
|
|
204
204
|
+ RESOLUTION: implemented. Gemvault::VaultPath resolves vault:// and file://
|
|
205
205
|
+ locators (absolute and two-slash relative forms) and every CLI command that
|
|
206
206
|
+ opens a vault goes through it, as does the RubyGems source. Covered by
|
|
@@ -617,7 +617,7 @@ Description:
|
|
|
617
617
|
+ https://github.com/ruby/rubygems/search?q=cannot+load+such+file+--+bundler%2Fplugin%2Fvault_source&type=Issues
|
|
618
618
|
+
|
|
619
619
|
+ If there aren't any reports for this error yet, please fill in the new issue form located at https://github.com/ruby/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md. Make sure to copy and paste the full output of this command under the "What happened instead?" section.
|
|
620
|
-
+
|
|
620
|
+
+
|
|
621
621
|
+ RESOLUTION: two root causes, both fixed. (1) `bundle plugin install` switches
|
|
622
622
|
+ GEM_HOME to the plugin root mid-process, and RubyGems' spec stub cache is
|
|
623
623
|
+ populated during resolution, before gemvault is installed there; the shim's
|
|
@@ -637,14 +637,14 @@ Id: 11
|
|
|
637
637
|
Updated: Sun, 19 Jul 2026 03:56:57 +0000
|
|
638
638
|
Name: CI tests aren't running
|
|
639
639
|
Description: CI tests should be running on all platforms
|
|
640
|
-
+
|
|
640
|
+
+
|
|
641
641
|
+ ANALYSIS: .github/workflows/ci.yml exists (unit tests, specs, rubocop on
|
|
642
642
|
+ push/PR to master). Two likely reasons it cannot go green: (1) `rake rubocop`
|
|
643
643
|
+ exits nonzero on the pre-existing Gemspec/RequiredRubyVersion offenses
|
|
644
644
|
+ (required_ruby_version ">= 3.4.8" vs TargetRubyVersion 4.0 in .rubocop.yml) --
|
|
645
645
|
+ pick one and align; (2) `rake spec` builds/uses a podman image, so the runner
|
|
646
646
|
+ needs podman available. Not replicable as a podman rspec spec (CI infra).
|
|
647
|
-
+
|
|
647
|
+
+
|
|
648
648
|
+ RESOLUTION: three blockers fixed. (1) TargetRubyVersion aligned to 3.4.8, the
|
|
649
649
|
+ gemspec floor, clearing the Gemspec/RequiredRubyVersion offenses; whole
|
|
650
650
|
+ tracked tree is rubocop-clean. (2) The integration job invoked
|
|
@@ -663,14 +663,14 @@ Updated: Sun, 19 Jul 2026 03:27:39 +0000
|
|
|
663
663
|
Name: bundle exec fails after successful bundle install with path vendor
|
|
664
664
|
Description: Reported 2026-07-19 (reversal-store): bundle install succeeds, then
|
|
665
665
|
+ any `bundle exec` fails while parsing the Gemfile:
|
|
666
|
-
+
|
|
666
|
+
+
|
|
667
667
|
+ ```
|
|
668
668
|
+ [!] There was an error parsing `Gemfile`: Could not find 'bundler' (>= 2.0)
|
|
669
669
|
+ among 101 total gem(s)
|
|
670
670
|
+ Checked in 'GEM_PATH=/workspace/vendor/ruby/4.0.0' at:
|
|
671
671
|
+ /workspace/.bundle/plugin/specifications/gemvault-0.1.5.gemspec
|
|
672
672
|
+ ```
|
|
673
|
-
+
|
|
673
|
+
+
|
|
674
674
|
+ RESOLUTION: gemvault declared bundler as a runtime dependency. Under
|
|
675
675
|
+ `bundle exec` with path vendor, GEM_PATH is restricted to the app bundle, and
|
|
676
676
|
+ on rubies where bundler is a regular (non-default) gem its spec is invisible,
|
|
@@ -681,3 +681,339 @@ Description: Reported 2026-07-19 (reversal-store): bundle install succeeds, then
|
|
|
681
681
|
+ reinstalling bundler as a regular gem and deleting its default-gem spec stub;
|
|
682
682
|
+ also covers the system-installed (`gem install gemvault`) flow. Both passing.
|
|
683
683
|
Status: closed
|
|
684
|
+
|
|
685
|
+
Id: 13
|
|
686
|
+
Updated: Sun, 26 Jul 2026 20:33:33 -0400
|
|
687
|
+
Name: bundle install fails, nothing seems to fix it
|
|
688
|
+
Description: bundle install does not complete successfully (ruby 4.0.1 &jruby 10.1.0.0). Tried doing all of these:
|
|
689
|
+
+ 1. gemvault doctor (below, completes successfully, but another bundle install fails)
|
|
690
|
+
+ 2. rm -rf .bundle/plugin && bundle install
|
|
691
|
+
+ 3. rm -f Gemfile.lock && bundle install
|
|
692
|
+
+ 4. 2 & 3 combined before bundle install
|
|
693
|
+
+
|
|
694
|
+
+ ```
|
|
695
|
+
+ jruby -S gemvault doctor
|
|
696
|
+
+ Uninstalled plugin bundler-source-vault
|
|
697
|
+
+ Fetching gem metadata from https://rubygems.org/.......
|
|
698
|
+
+ Resolving dependencies...
|
|
699
|
+
+ Installing bundler-source-vault 0.2.0
|
|
700
|
+
+ Installed plugin bundler-source-vault
|
|
701
|
+
+ Bundle complete! 15 Gemfile dependencies, 50 gems now installed.
|
|
702
|
+
+ Bundled gems are installed into `./vendor`
|
|
703
|
+
+ ❯ bundle install
|
|
704
|
+
+ Fetching gem metadata from https://rubygems.org/.......
|
|
705
|
+
+ Resolving dependencies...
|
|
706
|
+
+ Installing bundler-source-vault 0.2.0
|
|
707
|
+
+
|
|
708
|
+
+ [!] There was an error parsing `Gemfile`: cannot load such file -- bundler/plugin/vault_source. Bundler cannot continue.
|
|
709
|
+
+
|
|
710
|
+
+ # from /Users/davidgillis/repos/reversal-store/Gemfile:19
|
|
711
|
+
+ # -------------------------------------------
|
|
712
|
+
+ #
|
|
713
|
+
+ > source "vendor/vendored.gemv", type: :vault do
|
|
714
|
+
+ # gem 'jarpack', "~> 0.2.1"
|
|
715
|
+
+ # -------------------------------------------
|
|
716
|
+
+ ```
|
|
717
|
+
+
|
|
718
|
+
+ RESOLUTION: the plugin root never held gemvault, and the shim's require had no
|
|
719
|
+
+ way to reach the copy that did exist. Bundler's Source::Rubygems#install
|
|
720
|
+
+ short-circuits on `installed?(spec) && !force`, so a plugin dependency already
|
|
721
|
+
+ present on the ambient GEM_PATH is never downloaded into the plugin root --
|
|
722
|
+
+ which is every machine where `gem install gemvault` has run. That stays hidden
|
|
723
|
+
+ until the app bundle is populated: from the second `bundle install` onward
|
|
724
|
+
+ Bundler restricts GEM_PATH to the bundle, the ambient gemvault falls out of
|
|
725
|
+
+ scope, and nothing is left to resolve. Hence the reported permanence: step 2-4
|
|
726
|
+
+ all rebuild the same incomplete plugin root. shim/plugins.rb now locates
|
|
727
|
+
+ gemvault's lib across every root that can hold it, including the ones Bundler
|
|
728
|
+
+ masked (Bundler.original_env GEM_HOME/GEM_PATH), and puts it on $LOAD_PATH
|
|
729
|
+
+ instead of relying on gem activation. Using $LOAD_PATH also fixes a second
|
|
730
|
+
+ failure found while reproducing this -- `Could not find 'command_kit' (~> 0.6)`
|
|
731
|
+
+ when gemvault does land in the plugin root -- because activation demands the
|
|
732
|
+
+ full runtime dependency set while vault_source.rb reaches the rest of gemvault
|
|
733
|
+
+ through require_relative alone.
|
|
734
|
+
+
|
|
735
|
+
+ The integration suite could not have caught this. Dockerfile.test installed
|
|
736
|
+
+ gemvault AND bundler-source-vault system-wide, so `require
|
|
737
|
+
+ "bundler/plugin/vault_source"` resolved from the ambient GEM_HOME no matter
|
|
738
|
+
+ what the plugin root contained, and the ruby base image's
|
|
739
|
+
+ BUNDLE_APP_CONFIG=/usr/local/bundle moved Bundler::Plugin.root out of the
|
|
740
|
+
+ project so no spec ever exercised a project-local .bundle/plugin. The shim is
|
|
741
|
+
+ no longer installed system-wide (specs resolve it from the local gem index),
|
|
742
|
+
+ BUNDLE_APP_CONFIG is unset in the container, and gemvault stays installed
|
|
743
|
+
+ system-wide on purpose because that is the trigger. Removing the mask turned 13
|
|
744
|
+
+ previously green specs red; all now pass against the tree's shim rather than an
|
|
745
|
+
+ ambient copy. Replicated by spec/integration/plugin_root_deps_spec.rb (repeated
|
|
746
|
+
+ bundle install, and bundle exec under a restricted GEM_PATH).
|
|
747
|
+
Status: closed
|
|
748
|
+
|
|
749
|
+
Id: 14
|
|
750
|
+
Updated: Wed, 29 Jul 2026 16:41:11 -0400
|
|
751
|
+
Name: gemvault doctor fails when bundler/inline is used
|
|
752
|
+
Description: Loudly fails with 2 errors, one of which is "can't find gemfile"
|
|
753
|
+
Status: open
|
|
754
|
+
|
|
755
|
+
Id: 15
|
|
756
|
+
Updated: Wed, 29 Jul 2026 17:39:23 -0400
|
|
757
|
+
Name: gemvault new fails on path/to/gemvault.gemv
|
|
758
|
+
Description: I did it in /tmp, maybe that's why?
|
|
759
|
+
+
|
|
760
|
+
+ RESOLUTION: /tmp was a red herring -- the trigger is the missing parent
|
|
761
|
+
+ directory. `gemvault new path/to/gemvault.gemv` reached Tempfile.create with a
|
|
762
|
+
+ nonexistent dirname and died with a raw Errno::ENOENT and a 25-line Ruby
|
|
763
|
+
+ backtrace; with path/to already present the same command always worked.
|
|
764
|
+
+
|
|
765
|
+
+ A vault is one file, so `gemvault new vendor/vendored.gemv` in a tree that has
|
|
766
|
+
+ no vendor yet reads as an ordinary request rather than a mistake: the missing
|
|
767
|
+
+ directories are now created, and the shallowest one created is reported
|
|
768
|
+
+ ("Created directory vendor") so nothing appears out of nowhere. What cannot be
|
|
769
|
+
+ papered over is raised as VaultDestination::Error and printed as one line with
|
|
770
|
+
+ exit 1 -- a parent that is a file, or one that cannot be created (EACCES).
|
|
771
|
+
+ SystemCallError from the vault write itself is caught the same way, so no path
|
|
772
|
+
+ through `gemvault new` ends in a backtrace.
|
|
773
|
+
+
|
|
774
|
+
+ Gemvault::VaultDestination owns the .gemv suffix defaulting, the occupied-path
|
|
775
|
+
+ check and the parent creation; the command stays thin. Replicated first by
|
|
776
|
+
+ spec/integration/cli/commands/new_spec.rb (real subprocess, real vault, real
|
|
777
|
+
+ exit code -- 5 of its 9 examples failed against the old code, including one
|
|
778
|
+
+ asserting the absence of Errno::ENOENT), with unit cover in
|
|
779
|
+
+ spec/gemvault/vault_destination_spec.rb and spec/gemvault/cli/commands/new_spec.rb.
|
|
780
|
+
Status: closed
|
|
781
|
+
|
|
782
|
+
Id: 16
|
|
783
|
+
Updated: Wed, 29 Jul 2026 18:25:48 -0400
|
|
784
|
+
Name: Add jruby-ci workflow
|
|
785
|
+
Description: It should be already set up on the jruby-support branch. It just needs to be picked from it. DO NOT use the other code in that - it is very outdated
|
|
786
|
+
Status: open
|
|
787
|
+
|
|
788
|
+
Id: 17
|
|
789
|
+
Updated: Thu, 30 Jul 2026 00:07:42 +0000
|
|
790
|
+
Name: Integration CI job reddens on transient podman/crun failures
|
|
791
|
+
Description: Both `integration` jobs failed on master (run 30496142063) and on PR #17 with:
|
|
792
|
+
+
|
|
793
|
+
+ ```
|
|
794
|
+
+ error running container: from /usr/bin/crun creating container for
|
|
795
|
+
+ [/bin/sh -c dnf -y install ...]: unknown version specified
|
|
796
|
+
+ ```
|
|
797
|
+
+
|
|
798
|
+
+ Nothing had changed between the last green run and the first red one: same runner
|
|
799
|
+
+ image 20260720.247.2, same pre-installed podman, same fedora:44 blob and config
|
|
800
|
+
+ digests, same SOURCE_DIGEST build arg, and the only commit in between touched
|
|
801
|
+
+ issues.rec text. Rerunning the identical commit went green.
|
|
802
|
+
+
|
|
803
|
+
+ `rake spec:build` had no retry, so one momentary container-runtime failure reddens
|
|
804
|
+
+ the whole run -- and because the matrix cancels the sibling leg, a flake reads as a
|
|
805
|
+
+ real break in the suite CLAUDE.md calls the first line of defense for CLI bugs.
|
|
806
|
+
+
|
|
807
|
+
+ RESOLUTION: the image lifecycle moved out of the Rakefile into ContainerImage
|
|
808
|
+
+ (spec/support/container_image.rb), which retries a failed build ATTEMPTS (3) times
|
|
809
|
+
+ and announces each retry. Nothing in the exit status separates a transient runtime
|
|
810
|
+
+ failure from a real Dockerfile error, so every failure is retried; a genuinely broken
|
|
811
|
+
+ Dockerfile still fails, just after 3 tries, and fails fast because it never reaches
|
|
812
|
+
+ the network. Commands run through an injected Shell so the retry behaviour is
|
|
813
|
+
+ specified without podman (spec/container_image_spec.rb, spec/shell_spec.rb), and the
|
|
814
|
+
+ loop was also confirmed against real podman with a Dockerfile that exits nonzero.
|
|
815
|
+
+
|
|
816
|
+
+ RESOLUTION: the `jruby` job is picked into .github/workflows/ci.yml; none of the
|
|
817
|
+
+ branch's Sequel/jdbc-sqlite3 code came with it. Master needs none of it -- the
|
|
818
|
+
+ tarball format uses only rubygems' own tar tooling, so gemvault already runs on
|
|
819
|
+
+ JRuby. Three of the branch job's details did not survive the pick: JAVA_OPTS
|
|
820
|
+
+ --enable-native-access existed to silence a jdbc-sqlite3 warning under Java 25
|
|
821
|
+
+ (no JDBC driver here, and the job pins Java 21), BUNDLE_FROZEN existed for a
|
|
822
|
+
+ committed MRI-resolved lock (Gemfile.lock is gitignored on master), and the
|
|
823
|
+
+ branch's matrix/podman edits to the MRI jobs are the outdated part.
|
|
824
|
+
+
|
|
825
|
+
+ Two things the branch job would have hit on master, both found by running it:
|
|
826
|
+
+ (1) `bundle install` died on the sqlite3 C extension, which cannot build on the
|
|
827
|
+
+ JVM. sqlite3 is a dev-only dependency for the legacy Dbvault read path, so the
|
|
828
|
+
+ Gemfile now scopes it `platform: %i[ruby windows]`; nothing under test/ touches
|
|
829
|
+
+ sqlite3, which is why the job runs `rake test` only and leaves the sqlite3-backed
|
|
830
|
+
+ specs to the MRI jobs. (2) `bundle install` then exhausted JRuby's default 500MB
|
|
831
|
+
+ heap during resolution -- inherent to the Gemfile, not to sqlite3 -- so the job
|
|
832
|
+
+ sets JRUBY_OPTS=-J-Xmx2048m, the remedy JRuby's own error message prescribes.
|
|
833
|
+
+
|
|
834
|
+
+ Verified locally against JRuby 10.1.0.0 on Java 25 (installed for this; the box
|
|
835
|
+
+ had none, and no install-jruby script existed -- one is now at
|
|
836
|
+
+ ~/.local/bin/install-jruby): bundle install clean with sqlite3 absent, rake test
|
|
837
|
+
+ 113 tests / 231 assertions / 0 failures. MRI unaffected: sqlite3 still resolves,
|
|
838
|
+
+ rake test 113/0, spec:core 130 examples/0 failures, rubocop 111 files clean.
|
|
839
|
+
Status: closed
|
|
840
|
+
|
|
841
|
+
Id: 18
|
|
842
|
+
Updated: Thu, 30 Jul 2026 01:06:09 +0000
|
|
843
|
+
Name: Integration CI broken by runner image podman 5 / crun 1.14 mismatch
|
|
844
|
+
Description: Every `integration` job fails at the Dockerfile's dnf layer with:
|
|
845
|
+
+
|
|
846
|
+
+ ```
|
|
847
|
+
+ error running container: from /usr/bin/crun creating container for
|
|
848
|
+
+ [/bin/sh -c dnf -y install ...]: unknown version specified
|
|
849
|
+
+ ```
|
|
850
|
+
+
|
|
851
|
+
+ This looked like issue #17's flake and is not. Correlating the runner image
|
|
852
|
+
+ against the outcome settles it:
|
|
853
|
+
+
|
|
854
|
+
+ | runner image | podman | outcome |
|
|
855
|
+
+ |---------------------|--------|-------------|
|
|
856
|
+
+ | 20260720.247 (old) | 4.9.3 | pass |
|
|
857
|
+
+ | 20260726.254 (new) | 5.8.4 | crun error |
|
|
858
|
+
+
|
|
859
|
+
+ Every genuine failure is on 20260726.254; every job on 20260720.247 either passed
|
|
860
|
+
+ or was cancelled by fail-fast (which is what made two of them look like failures).
|
|
861
|
+
+ GitHub rolls the image out gradually, so jobs land on either one -- hence reruns
|
|
862
|
+
+ sometimes helping and sometimes not, and hence integration CI going permanently
|
|
863
|
+
+ red as the rollout completes.
|
|
864
|
+
+
|
|
865
|
+
+ The new image bumped podman 4.9.3 -> 5.8.4 and left Ubuntu 24.04's crun 1.14 in
|
|
866
|
+
+ place. podman 5 writes an OCI config declaring ociVersion 1.2.0; crun 1.14
|
|
867
|
+
+ rejects any version not prefixed "1.0" with exactly "unknown version
|
|
868
|
+
+ specified". A dev box running podman 5.8.4 with crun 1.28 builds and runs the
|
|
869
|
+
+ same image fine, which is the control.
|
|
870
|
+
+
|
|
871
|
+
+ Nothing about this is intermittent, so #17's retry cannot help: three attempts
|
|
872
|
+
+ on the same runner fail three times.
|
|
873
|
+
+
|
|
874
|
+
+ RESOLUTION: the integration job installs a pinned crun 1.28 (newer than any
|
|
875
|
+
+ noble package) and names it in GEMVAULT_PODMAN_RUNTIME; Podman.command inserts
|
|
876
|
+
+ `--runtime` ahead of the subcommand when that variable is set, so both
|
|
877
|
+
+ ContainerImage's build and ContainerHelper's container runs go through it. Unset
|
|
878
|
+
+ -- every dev machine, and any runner whose podman and crun agree -- podman
|
|
879
|
+
+ chooses as before. The job also prints podman, crun and the chosen runtime, so
|
|
880
|
+
+ the next mismatch names itself instead of being mistaken for a flake, and
|
|
881
|
+
+ fail-fast is off because one leg cancelling the other hid which had broken.
|
|
882
|
+
+
|
|
883
|
+
+ Verified locally both ways: with the variable set to a downloaded crun 1.28,
|
|
884
|
+
+ spec:build plus 135 integration examples pass; with it unset, the same. A
|
|
885
|
+
+ config-file override (`[engine.runtimes]`) was tried first and did not take --
|
|
886
|
+
+ podman kept /usr/bin/crun -- which is why this uses the explicit flag.
|
|
887
|
+
Status: closed
|
|
888
|
+
|
|
889
|
+
Id: 19
|
|
890
|
+
Updated: Fri, 31 Jul 2026 09:18:45 -0400
|
|
891
|
+
Name: Deps in Dockerfile.test are not dynamically inferred
|
|
892
|
+
Description: Bundler version, command kit version, and all other deps that are being installed need to be inferred from this project via bundler info, and should be passed in as ENV variables. Hardcoding is not acceptable
|
|
893
|
+
Status: open
|
|
894
|
+
|
|
895
|
+
Id: 20
|
|
896
|
+
Updated: Fri, 31 Jul 2026 13:42:28 -0400
|
|
897
|
+
Name: Received the following error during bundle install:
|
|
898
|
+
Description: [dev@rstore]/workspace% bundle install
|
|
899
|
+
+ Bundler 4.0.14 is running, but your lockfile was generated with 4.0.17. Installing Bundler 4.0.17 and restarting using that version.
|
|
900
|
+
+ Source locally installed gems is ignoring #<Bundler::StubSpecification name=io-event version=1.19.4 platform=ruby> because it is missing extensions
|
|
901
|
+
+ Fetching gem metadata from https://rubygems.org/.
|
|
902
|
+
+ Source rubygems repository https://rubygems.org/ is ignoring #<Bundler::StubSpecification name=io-event version=1.19.4 platform=ruby> because it is missing extensions
|
|
903
|
+
+ Installing bundler 4.0.17
|
|
904
|
+
+ Ignoring io-event-1.19.4 because its extensions are not built. Try: gem pristine io-event --version 1.19.4
|
|
905
|
+
+ Fetching gem metadata from https://rubygems.org/.......
|
|
906
|
+
+ Source rubygems repository https://rubygems.org/, cached gems or installed locally is ignoring #<Bundler::StubSpecification name=io-event version=1.19.4 platform=ruby> because it is missing extensions
|
|
907
|
+
+ Resolving dependencies...
|
|
908
|
+
+ Fetching json 2.21.2
|
|
909
|
+
+ Installing json 2.21.2 with native extensions
|
|
910
|
+
+ Fetching gemvault 0.2.2
|
|
911
|
+
+ Installing gemvault 0.2.2
|
|
912
|
+
+ Fetching bundler-source-vault 0.2.2
|
|
913
|
+
+ Installing bundler-source-vault 0.2.2
|
|
914
|
+
+ The following plugin paths don't exist: /Users/davidgillis/.rbenv/versions/4.0.1/lib/ruby/gems/4.0.0/gems/bundler-source-vault-0.2.1/..
|
|
915
|
+
+
|
|
916
|
+
+ This can happen if the plugin was installed with a different version of Ruby that has since been uninstalled.
|
|
917
|
+
+
|
|
918
|
+
+ If you would like to reinstall the plugin, run:
|
|
919
|
+
+
|
|
920
|
+
+ bundler plugin uninstall bundler-source-vault && bundler plugin install bundler-source-vault
|
|
921
|
+
+
|
|
922
|
+
+ Continuing without installing plugin bundler-source-vault.
|
|
923
|
+
+ /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/source_list.rb:59:in 'Bundler::SourceList#add_plugin_source': undefined method 'new' for nil (NoMethodError)
|
|
924
|
+
+
|
|
925
|
+
+ add_source_to_list Plugin.source(source).new(options), @plugin_sources
|
|
926
|
+
+ ^^^^
|
|
927
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:135:in 'Bundler::Dsl#source'
|
|
928
|
+
+ from /workspace/Gemfile:20:in 'block in Bundler::Dsl#eval_gemfile'
|
|
929
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:49:in 'BasicObject#instance_eval'
|
|
930
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:49:in 'block in Bundler::Dsl#eval_gemfile'
|
|
931
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:330:in 'Bundler::Dsl#with_gemfile'
|
|
932
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:47:in 'Bundler::Dsl#eval_gemfile'
|
|
933
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:13:in 'Bundler::Dsl.evaluate'
|
|
934
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/definition.rb:40:in 'Bundler::Definition.build'
|
|
935
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler.rb:235:in 'Bundler.definition'
|
|
936
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/env.rb:36:in 'Bundler::Env.report'
|
|
937
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/friendly_errors.rb:71:in 'Bundler::FriendlyErrors.request_issue_report_for'
|
|
938
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/friendly_errors.rb:50:in 'Bundler::FriendlyErrors.log_error'
|
|
939
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/friendly_errors.rb:124:in 'Bundler.with_friendly_errors'
|
|
940
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/exe/bundle:20:in '<top (required)>'
|
|
941
|
+
+ from /usr/local/share/ruby/site_ruby/rubygems.rb:305:in 'Kernel#load'
|
|
942
|
+
+ from /usr/local/share/ruby/site_ruby/rubygems.rb:305:in 'Gem.activate_and_load_bin_path'
|
|
943
|
+
+ from /usr/local/bin/bundle:25:in '<main>'
|
|
944
|
+
+ /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/source_list.rb:59:in 'Bundler::SourceList#add_plugin_source': undefined method 'new' for nil (NoMethodError)
|
|
945
|
+
+
|
|
946
|
+
+ add_source_to_list Plugin.source(source).new(options), @plugin_sources
|
|
947
|
+
+ ^^^^
|
|
948
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:135:in 'Bundler::Dsl#source'
|
|
949
|
+
+ from /workspace/Gemfile:20:in 'block in Bundler::Dsl#eval_gemfile'
|
|
950
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:49:in 'BasicObject#instance_eval'
|
|
951
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:49:in 'block in Bundler::Dsl#eval_gemfile'
|
|
952
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:330:in 'Bundler::Dsl#with_gemfile'
|
|
953
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:47:in 'Bundler::Dsl#eval_gemfile'
|
|
954
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/dsl.rb:13:in 'Bundler::Dsl.evaluate'
|
|
955
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/definition.rb:40:in 'Bundler::Definition.build'
|
|
956
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler.rb:235:in 'Bundler.definition'
|
|
957
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/cli/install.rb:45:in 'Bundler::CLI::Install#run'
|
|
958
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/cli.rb:296:in 'block in Bundler::CLI#install'
|
|
959
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/settings.rb:145:in 'Bundler::Settings#temporary'
|
|
960
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/cli.rb:295:in 'Bundler::CLI#install'
|
|
961
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/vendor/thor/lib/thor/command.rb:28:in 'Bundler::Thor::Command#run'
|
|
962
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in 'Bundler::Thor::Invocation#invoke_command'
|
|
963
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/vendor/thor/lib/thor.rb:538:in 'Bundler::Thor.dispatch'
|
|
964
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/cli.rb:35:in 'Bundler::CLI.dispatch'
|
|
965
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/vendor/thor/lib/thor/base.rb:584:in 'Bundler::Thor::Base::ClassMethods#start'
|
|
966
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/cli.rb:29:in 'Bundler::CLI.start'
|
|
967
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/exe/bundle:28:in 'block in <top (required)>'
|
|
968
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/lib/bundler/friendly_errors.rb:118:in 'Bundler.with_friendly_errors'
|
|
969
|
+
+ from /workspace/vendor/ruby/4.0.0/gems/bundler-4.0.17/exe/bundle:20:in '<top (required)>'
|
|
970
|
+
+ from /usr/local/share/ruby/site_ruby/rubygems.rb:305:in 'Kernel#load'
|
|
971
|
+
+ from /usr/local/share/ruby/site_ruby/rubygems.rb:305:in 'Gem.activate_and_load_bin_path'
|
|
972
|
+
+ from /usr/local/bin/bundle:25:in '<main>'
|
|
973
|
+
+
|
|
974
|
+
+ Though I will add that gemvault doctor followed by bundle install fixed the issue
|
|
975
|
+
Status: open
|
|
976
|
+
|
|
977
|
+
Id: 21
|
|
978
|
+
Updated: Fri, 31 Jul 2026 13:54:09 -0400
|
|
979
|
+
Name: bundle info fails when gem is in vault
|
|
980
|
+
Description: bundle info jarpack
|
|
981
|
+
+ Source locally installed gems is ignoring #<Bundler::StubSpecification name=json version=2.21.2 platform=ruby> because it is missing extensions
|
|
982
|
+
+ Could not find gem 'jarpack'.
|
|
983
|
+
+ Did you mean 'jarpack'?
|
|
984
|
+
+
|
|
985
|
+
+
|
|
986
|
+
+ bundle info jarpack
|
|
987
|
+
Status: open
|
|
988
|
+
|
|
989
|
+
Id: 22
|
|
990
|
+
Updated: Mon, 10 Aug 2026 10:03:35 -0400
|
|
991
|
+
Name: Add github actions disclaimer/instructions
|
|
992
|
+
Description: bundler-cache: true on the ruby/setup-ruby action will not work correctly:
|
|
993
|
+
+
|
|
994
|
+
+ - uses: ruby/setup-ruby@v1
|
|
995
|
+
+ with:
|
|
996
|
+
+ ruby-version: ${{ matrix.ruby }}
|
|
997
|
+
+ # bundler-cache runs `bundle lock`, which cannot parse the vault source until
|
|
998
|
+
+ # `bundle install` has fetched its plugin; install and cache manually instead.
|
|
999
|
+
+ bundler-cache: false
|
|
1000
|
+
+ - name: Cache gems
|
|
1001
|
+
+ uses: actions/cache@v6
|
|
1002
|
+
+ with:
|
|
1003
|
+
+ path: |
|
|
1004
|
+
+ vendor/bundle
|
|
1005
|
+
+ .bundle/plugin
|
|
1006
|
+
+ key: ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ hashFiles('Gemfile', '*.gemspec', 'vendor/vendored.gemv') }}
|
|
1007
|
+
+ restore-keys: |
|
|
1008
|
+
+ ${{ runner.os }}-gems-${{ matrix.ruby }}-
|
|
1009
|
+
+
|
|
1010
|
+
+ - name: Install gems
|
|
1011
|
+
+ run: | # confine gems to vendor/bundle so the cache never shadows vendor/vendored.gemv
|
|
1012
|
+
+ bundle config set --local path vendor/bundle
|
|
1013
|
+
+ bundle install --jobs 4 --retry 3
|
|
1014
|
+
Updated: Mon, 10 Aug 2026 10:14:51 -0400
|
|
1015
|
+
Name: Gemvault spams warnings on bundle install
|
|
1016
|
+
Description: /workspace/.bundle/plugin/gems/bundler-source-vault-0.2.2/gemvault_load_path.rb:31: warning: already initialized constant BundlerSourceVault::GemvaultLoadPath::GEM
|
|
1017
|
+
+ /workspace/.bundle/plugin/gems/bundler-source-vault-0.2.2/gemvault_load_path.rb:32: warning: already initialized constant BundlerSourceVault::GemvaultLoadPath::SHIM
|
|
1018
|
+
+ /workspace/.bundle/plugin/gems/bundler-source-vault-0.2.2/gemvault_load_path.rb:33: warning: already initialized constant BundlerSourceVault::GemvaultLoadPath::VAULT_SOURCE
|
|
1019
|
+
Status: open
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
require "pathname"
|
|
2
1
|
require_relative "../command"
|
|
2
|
+
require_relative "../destination"
|
|
3
|
+
require_relative "../../vault_destination"
|
|
3
4
|
|
|
4
5
|
module Gemvault
|
|
5
6
|
class CLI
|
|
@@ -13,16 +14,23 @@ module Gemvault
|
|
|
13
14
|
desc: "Vault name (auto-appends .gemv)"
|
|
14
15
|
|
|
15
16
|
def run(name)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
begin
|
|
18
|
+
destination = build_destination(name)
|
|
19
|
+
destination.refuse_existing
|
|
20
|
+
destination.create_parents
|
|
21
|
+
Vault.create(destination.path)
|
|
22
|
+
puts "Created #{destination.path}"
|
|
23
|
+
rescue VaultDestination::Error, Vault::Error, SystemCallError => e
|
|
24
|
+
print_error(e.message)
|
|
20
25
|
exit(1)
|
|
21
26
|
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
def build_destination(name)
|
|
32
|
+
vault_destination = VaultDestination.new(name)
|
|
33
|
+
Destination.new(vault_destination, stdout:)
|
|
26
34
|
end
|
|
27
35
|
end
|
|
28
36
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require "forwardable"
|
|
2
|
+
|
|
3
|
+
module Gemvault
|
|
4
|
+
class CLI
|
|
5
|
+
##
|
|
6
|
+
# A VaultDestination as the CLI presents it: the same operations, with the
|
|
7
|
+
# directories they grow narrated on +stdout+ so nothing appears on disk
|
|
8
|
+
# unannounced. What the destination refuses still surfaces as
|
|
9
|
+
# <tt>VaultDestination::Error</tt> for the command to report.
|
|
10
|
+
class Destination
|
|
11
|
+
extend Forwardable
|
|
12
|
+
|
|
13
|
+
def_delegators :@destination, :path, :refuse_existing
|
|
14
|
+
|
|
15
|
+
def initialize(destination, stdout:)
|
|
16
|
+
@destination = destination
|
|
17
|
+
@stdout = stdout
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Creates the destination's missing parent directories, reporting the
|
|
21
|
+
# shallowest one created so the user learns where the tree grew.
|
|
22
|
+
def create_parents
|
|
23
|
+
missing = @destination.missing_directory
|
|
24
|
+
@destination.create_parents
|
|
25
|
+
@stdout.puts "Created directory #{missing}" if missing
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/gemvault/vault.rb
CHANGED
|
@@ -30,6 +30,11 @@ module Gemvault
|
|
|
30
30
|
:spec_from_blob, :with_gem_file, :size, :close, :closed?,
|
|
31
31
|
:path, :format_version
|
|
32
32
|
|
|
33
|
+
# Creates an empty vault file at +path+, leaving it closed.
|
|
34
|
+
def self.create(path)
|
|
35
|
+
new(path, create: true).close
|
|
36
|
+
end
|
|
37
|
+
|
|
33
38
|
def self.assert_readable!(version:, path:)
|
|
34
39
|
return if version.between?(MIN_READABLE_FORMAT, CURRENT_FORMAT)
|
|
35
40
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require "pathname"
|
|
2
|
+
|
|
3
|
+
module Gemvault
|
|
4
|
+
##
|
|
5
|
+
# Where a new vault is about to be written: the <tt>.gemv</tt> path itself,
|
|
6
|
+
# and the directories that have to exist before anything can be written to it.
|
|
7
|
+
#
|
|
8
|
+
# A vault is one file, so <tt>gemvault new vendor/vendored.gemv</tt> in a tree
|
|
9
|
+
# that has no <tt>vendor</tt> yet reads as an ordinary request rather than a
|
|
10
|
+
# mistake, and the missing directories are created. What cannot be papered
|
|
11
|
+
# over -- something already occupying the path, a parent that is a file, a
|
|
12
|
+
# parent that cannot be created -- is raised as Error, so the CLI reports one
|
|
13
|
+
# line instead of a Ruby backtrace.
|
|
14
|
+
class VaultDestination
|
|
15
|
+
SUFFIX = ".gemv".freeze
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
# Raised when the path cannot hold a new vault.
|
|
19
|
+
class Error < StandardError; end
|
|
20
|
+
|
|
21
|
+
# The vault's path, with SUFFIX appended if the name lacked it.
|
|
22
|
+
attr_reader :path
|
|
23
|
+
|
|
24
|
+
def initialize(name)
|
|
25
|
+
locator = suffixed(name.to_s)
|
|
26
|
+
@path = Pathname(locator)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Raises Error when something already occupies the vault's path.
|
|
30
|
+
def refuse_existing
|
|
31
|
+
raise Error, "#{@path} already exists" if @path.exist?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# :call-seq:
|
|
35
|
+
# missing_directory -> Pathname or nil
|
|
36
|
+
#
|
|
37
|
+
# The shallowest directory create_parents would have to make -- creating it
|
|
38
|
+
# brings every deeper one with it -- or +nil+ when the parent already
|
|
39
|
+
# exists.
|
|
40
|
+
def missing_directory
|
|
41
|
+
@path.dirname.ascend.reject(&:exist?).last
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Creates the vault's missing parent directories.
|
|
45
|
+
def create_parents
|
|
46
|
+
parent = @path.dirname
|
|
47
|
+
return if parent.directory?
|
|
48
|
+
|
|
49
|
+
raise Error, "#{parent} is not a directory" if parent.exist?
|
|
50
|
+
|
|
51
|
+
make(parent)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def suffixed(locator)
|
|
57
|
+
return locator if locator.end_with?(SUFFIX)
|
|
58
|
+
|
|
59
|
+
"#{locator}#{SUFFIX}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def make(parent)
|
|
63
|
+
begin
|
|
64
|
+
parent.mkpath
|
|
65
|
+
rescue SystemCallError => e
|
|
66
|
+
raise Error, "cannot create directory #{parent}: #{e.message}"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/gemvault/version.rb
CHANGED