From 96070b2bb5f600ab3c75d385cb60af6851c1c785 Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Sat, 7 Dec 2013 15:09:12 +0100 Subject: [PATCH 1/7] Vendorize gems for distribution. This adds a vendor directory, whose Makefile knows how to vendorize all the gems from the `:dist` bundler group, and write a `setup.rb` file to update the `$LOAD_PATH` to include each gem. The `vendor/gems` target is marked `PHONY` to avoid it being included in `make all` and therefore happening on an end user's machine, however it is a dependency of `make dist` so the vendorized gems will be included in the distribution. Automake doesn't support installing directories, so we use the `install-data-hook` target to copy the gems directory to the right place (prefix/share/gitsh/gems). --- .gitignore | 1 + Gemfile | 4 +++- Makefile.am | 2 +- configure.ac | 4 +++- src/Makefile.am | 3 ++- src/gitsh.in | 1 + vendor/Makefile.am | 17 +++++++++++++++++ vendor/vendorize | 25 +++++++++++++++++++++++++ 8 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 vendor/Makefile.am create mode 100755 vendor/vendorize diff --git a/.gitignore b/.gitignore index e0f3d0d3..e914a174 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ depcomp src/gitsh lib/gitsh/version.rb gitsh-*.tar.gz +vendor/gems # Sub-repositories for release gh-pages diff --git a/Gemfile b/Gemfile index dcfd9652..ee9efb4d 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,9 @@ source 'https://rubygems.org' ruby '2.0.0' -gem 'parslet' +group :dist do + gem 'parslet' +end group :test do gem 'rspec' diff --git a/Makefile.am b/Makefile.am index d9c2b25c..27998073 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ AUTOMAKE_OPTIONS = foreign -SUBDIRS = src man lib/gitsh +SUBDIRS = src man lib/gitsh vendor EXTRA_DIST = LICENSE README.md .PHONY: release \ diff --git a/configure.ac b/configure.ac index 63863566..f50d8307 100644 --- a/configure.ac +++ b/configure.ac @@ -27,11 +27,13 @@ AX_PROG_RUBY_VERSION( rubydir=$datadir/$PACKAGE/ruby pkgrubydir=$rubydir/$PACKAGE libfiles="$(cd `dirname $0`/lib/gitsh; echo *.rb)" +gemsetuppath=$datadir/$PACKAGE/gems/setup.rb AC_SUBST([RUBY]) AC_SUBST([rubydir]) AC_SUBST([pkgrubydir]) AC_SUBST([libfiles]) +AC_SUBST([gemsetuppath]) -AC_CONFIG_FILES([Makefile src/Makefile lib/gitsh/Makefile man/Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile lib/gitsh/Makefile man/Makefile vendor/Makefile]) AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am index 3b4916d1..58753c82 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,8 @@ EXTRA_DIST = gitsh.in edit = sed \ -e 's|@RUBY[@]|$(RUBY)|g' \ - -e 's|@rubydir[@]|$(rubydir)|g' + -e 's|@rubydir[@]|$(rubydir)|g' \ + -e 's|@gemsetuppath[@]|$(gemsetuppath)|g' gitsh: Makefile gitsh.in $(edit) $(srcdir)/$@.in > $@ diff --git a/src/gitsh.in b/src/gitsh.in index 2fc12e7d..b45b3b0b 100644 --- a/src/gitsh.in +++ b/src/gitsh.in @@ -2,6 +2,7 @@ $LOAD_PATH.unshift('@rubydir@') +require '@gemsetuppath@' require 'gitsh/cli' begin diff --git a/vendor/Makefile.am b/vendor/Makefile.am new file mode 100644 index 00000000..4f66a168 --- /dev/null +++ b/vendor/Makefile.am @@ -0,0 +1,17 @@ +EXTRA_DIST = gems vendorize + +.PHONY: gems + +dist-hook: gems + +install-data-hook: + cp -R $(abs_srcdir)/gems $(DEST_DIR)$(pkgdatadir) + +uninstall-local: + rm -rf $(DEST_DIR)$(pkgdatadir)/gems + +gems: + $(srcdir)/vendorize + +maintainer-clean-local: + -rm -rf gems diff --git a/vendor/vendorize b/vendor/vendorize new file mode 100755 index 00000000..002e46c6 --- /dev/null +++ b/vendor/vendorize @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby + +require 'bundler' + +TARGET_PATH = File.expand_path('../gems', __FILE__) +SETUP_PATH = File.join(TARGET_PATH, 'setup.rb') + +FileUtils.mkdir(TARGET_PATH) + +File.open(SETUP_PATH, 'w') do |setup_file| + Bundler.definition.specs_for([:dist]).each do |gem| + if gem.name != 'bundler' + system( + '/usr/bin/env', 'gem', 'unpack', + '--target', TARGET_PATH, + '--version', gem.version.to_s, + gem.name + ) + + setup_file << "$LOAD_PATH.unshift(File.expand_path(%s, __FILE__))\n" % [ + "../#{gem.name}-#{gem.version}/lib".inspect + ] + end + end +end From dc6e21bf616f061566971389040dbf569dfddad2 Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Sat, 7 Dec 2013 16:00:51 +0100 Subject: [PATCH 2/7] We don't care if vendor/gems already exists. --- vendor/vendorize | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/vendorize b/vendor/vendorize index 002e46c6..666b11d3 100755 --- a/vendor/vendorize +++ b/vendor/vendorize @@ -5,7 +5,7 @@ require 'bundler' TARGET_PATH = File.expand_path('../gems', __FILE__) SETUP_PATH = File.join(TARGET_PATH, 'setup.rb') -FileUtils.mkdir(TARGET_PATH) +FileUtils.mkdir_p(TARGET_PATH) File.open(SETUP_PATH, 'w') do |setup_file| Bundler.definition.specs_for([:dist]).each do |gem| From 21043495e32fee5e9951146c8ce0777ea6f9720c Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Sat, 7 Dec 2013 16:01:48 +0100 Subject: [PATCH 3/7] Improve vendorized install. Installing via `nobase_dist_pkgdata_DATA` instead of using custom hooks. This has a few advantages: * `install-sh` takes care of the permissions for us. * We don't need to manually uninstall. * It's consistent with `lib/gitsh/Makefile.am` The big discovery here was `nobase_` which preserves subdirectory information, so the gems' files don't all end up directly in $pkgdatadir. --- configure.ac | 2 ++ vendor/Makefile.am | 9 ++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index f50d8307..ca3ce2f5 100644 --- a/configure.ac +++ b/configure.ac @@ -27,12 +27,14 @@ AX_PROG_RUBY_VERSION( rubydir=$datadir/$PACKAGE/ruby pkgrubydir=$rubydir/$PACKAGE libfiles="$(cd `dirname $0`/lib/gitsh; echo *.rb)" +vendorfiles="$(cd `dirname $0`/vendor; echo `find gems -type f`)" gemsetuppath=$datadir/$PACKAGE/gems/setup.rb AC_SUBST([RUBY]) AC_SUBST([rubydir]) AC_SUBST([pkgrubydir]) AC_SUBST([libfiles]) +AC_SUBST([vendorfiles]) AC_SUBST([gemsetuppath]) AC_CONFIG_FILES([Makefile src/Makefile lib/gitsh/Makefile man/Makefile vendor/Makefile]) diff --git a/vendor/Makefile.am b/vendor/Makefile.am index 4f66a168..23df2b8e 100644 --- a/vendor/Makefile.am +++ b/vendor/Makefile.am @@ -1,15 +1,10 @@ -EXTRA_DIST = gems vendorize +nobase_dist_pkgdata_DATA = $(vendorfiles) +EXTRA_DIST = vendorize .PHONY: gems dist-hook: gems -install-data-hook: - cp -R $(abs_srcdir)/gems $(DEST_DIR)$(pkgdatadir) - -uninstall-local: - rm -rf $(DEST_DIR)$(pkgdatadir)/gems - gems: $(srcdir)/vendorize From 5cb94c5e7e3dc1488cd42dc383cb5933aab6d300 Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Sat, 7 Dec 2013 16:12:27 +0100 Subject: [PATCH 4/7] Get distcheck passing again. * The vendorize script needs to work relative to the current working directory in order to support VPATH builds. * We need to remove `vendor/gems` as part of `make distclean`, since this is created by `make dist` --- vendor/Makefile.am | 2 +- vendor/vendorize | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/Makefile.am b/vendor/Makefile.am index 23df2b8e..d1bf65c6 100644 --- a/vendor/Makefile.am +++ b/vendor/Makefile.am @@ -8,5 +8,5 @@ dist-hook: gems gems: $(srcdir)/vendorize -maintainer-clean-local: +distclean-local: -rm -rf gems diff --git a/vendor/vendorize b/vendor/vendorize index 666b11d3..a05e1166 100755 --- a/vendor/vendorize +++ b/vendor/vendorize @@ -2,7 +2,7 @@ require 'bundler' -TARGET_PATH = File.expand_path('../gems', __FILE__) +TARGET_PATH = './gems' SETUP_PATH = File.join(TARGET_PATH, 'setup.rb') FileUtils.mkdir_p(TARGET_PATH) From 08d50170623580382a25e968df797e254843e1f3 Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Sat, 7 Dec 2013 17:02:56 +0100 Subject: [PATCH 5/7] Fix vendorize process. The improvements in 6f72fdd introduced a bug: If `vendor/gems` wasn't present when `./configure` was run, then `$vendorfile` was empty, and so `make dist` would vendorize and distribute the gems, but `make install` wouldn't install them. This change makes sure the vendorized gems are present in the configure script, and will vendorize them if needed. The vendorized gems are included in the distribution, so when installing from the tarball this is a no-op. --- configure.ac | 7 +++++++ vendor/Makefile.am | 7 ------- vendor/vendorize | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index ca3ce2f5..9eee8895 100644 --- a/configure.ac +++ b/configure.ac @@ -24,6 +24,13 @@ AX_PROG_RUBY_VERSION( AC_MSG_ERROR(Ruby 2.0 or later is required to install gitsh) ) +vendorize="$srcdir/vendor/vendorize vendor/gems" +AC_CHECK_FILE( + [vendor/gems], + [], + [$vendorize || AC_MSG_ERROR([Vendorizing gems failed. Make sure you can run "vendor/vendorize vendor/gems"])] +) + rubydir=$datadir/$PACKAGE/ruby pkgrubydir=$rubydir/$PACKAGE libfiles="$(cd `dirname $0`/lib/gitsh; echo *.rb)" diff --git a/vendor/Makefile.am b/vendor/Makefile.am index d1bf65c6..2b0feb61 100644 --- a/vendor/Makefile.am +++ b/vendor/Makefile.am @@ -1,12 +1,5 @@ nobase_dist_pkgdata_DATA = $(vendorfiles) EXTRA_DIST = vendorize -.PHONY: gems - -dist-hook: gems - -gems: - $(srcdir)/vendorize - distclean-local: -rm -rf gems diff --git a/vendor/vendorize b/vendor/vendorize index a05e1166..532ff09c 100755 --- a/vendor/vendorize +++ b/vendor/vendorize @@ -2,7 +2,12 @@ require 'bundler' -TARGET_PATH = './gems' +unless ARGV.length == 1 + $stderr.puts "usage: vendorize path-to-gems" + exit 64 +end + +TARGET_PATH = ARGV.first SETUP_PATH = File.join(TARGET_PATH, 'setup.rb') FileUtils.mkdir_p(TARGET_PATH) From 6eaa6c467d141dd2f3ae1bf90012349fa4c15313 Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Wed, 11 Dec 2013 08:27:32 +0100 Subject: [PATCH 6/7] Re-vendorize if Gemfile.lock has changed. This is sort of reinventing make's functionality, but we need to vendorize at configure time so that we have a full list of the vendorized files to pass on to automake. --- configure.ac | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 9eee8895..6d11dbc2 100644 --- a/configure.ac +++ b/configure.ac @@ -24,12 +24,11 @@ AX_PROG_RUBY_VERSION( AC_MSG_ERROR(Ruby 2.0 or later is required to install gitsh) ) -vendorize="$srcdir/vendor/vendorize vendor/gems" -AC_CHECK_FILE( - [vendor/gems], - [], - [$vendorize || AC_MSG_ERROR([Vendorizing gems failed. Make sure you can run "vendor/vendorize vendor/gems"])] -) +newer=`ls -t $srcdir/Gemfile.lock $srcdir/vendor/gems/setup.rb 2>/dev/null | (read n; echo $n)` +if test "$newer" == "$srcdir/Gemfile.lock"; then + rm -rf vendor/gems + $srcdir/vendor/vendorize vendor/gems || AC_MSG_ERROR([Vendorizing gems failed]) +fi rubydir=$datadir/$PACKAGE/ruby pkgrubydir=$rubydir/$PACKAGE From 6b325d5d52e7fcdbe772c7dc54ef8b1b4174de2f Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Fri, 13 Dec 2013 08:34:49 +0100 Subject: [PATCH 7/7] Improve code style * Prefer $() to `` * Quote expansions --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 6d11dbc2..a75a6f29 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,7 @@ AX_PROG_RUBY_VERSION( AC_MSG_ERROR(Ruby 2.0 or later is required to install gitsh) ) -newer=`ls -t $srcdir/Gemfile.lock $srcdir/vendor/gems/setup.rb 2>/dev/null | (read n; echo $n)` +newer=$(ls -t $srcdir/Gemfile.lock $srcdir/vendor/gems/setup.rb 2>/dev/null | (read n; echo $n)) if test "$newer" == "$srcdir/Gemfile.lock"; then rm -rf vendor/gems $srcdir/vendor/vendorize vendor/gems || AC_MSG_ERROR([Vendorizing gems failed]) @@ -32,8 +32,8 @@ fi rubydir=$datadir/$PACKAGE/ruby pkgrubydir=$rubydir/$PACKAGE -libfiles="$(cd `dirname $0`/lib/gitsh; echo *.rb)" -vendorfiles="$(cd `dirname $0`/vendor; echo `find gems -type f`)" +libfiles="$(cd "$(dirname "$0")/lib/gitsh"; echo *.rb)" +vendorfiles="$(cd "$(dirname "$0")/vendor"; echo $(find gems -type f))" gemsetuppath=$datadir/$PACKAGE/gems/setup.rb AC_SUBST([RUBY])