ruby-builder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bbfbf93eb01e5fc0a4170f57451ab628033f635e6976cb19ebb2af3301f681ce
4
+ data.tar.gz: 5f9ded2af75388d5de86a14aaa31a4f883534a5b769959e15d0445c5e7891b74
5
+ SHA512:
6
+ metadata.gz: 8f694c98244f687fe64a359632749cae74d81a5f2df4f55bf0cb517c705f1531b206409a085f408563f9cba136bdee9706a5d421f0c61aa954adef369681ca67
7
+ data.tar.gz: 402467ddcacef0c1c9768827c79a93f98a29bb8bae9aabd49f9fef635f66d2024a7cdc1d0c2e2948d92359468e41b91feb386a352db876edc1851efbce65aaba
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /Gemfile.lock
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # CHANGELOG
2
+ ## v0.1.0
3
+
4
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in ruby-builder.gemspec
6
+ gemspec
7
+
8
+ gem 'pry'
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Takashi Kokubun
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # ruby-builder
2
+
3
+ Build ruby binaries per revision under rbenv directory
4
+
5
+ ## Installation
6
+
7
+ Install it yourself as:
8
+
9
+ ```bash
10
+ $ gem install ruby-builder
11
+ ```
12
+
13
+ ## Usage
14
+ ### Single revision build
15
+
16
+ ```
17
+ $ rbenv versions
18
+ system
19
+ * 2.5.0 (set by /home/k0kubun/.rbenv/version)
20
+ $ ruby-builder revision r62436 -d ~/src/github.com/ruby/ruby
21
+ I, [2018-02-17T15:00:17.674440 #8189] INFO -- : Parsing revisions at '/home/k0kubun/src/github.com/ruby/ruby'...
22
+ I, [2018-02-17T15:00:17.677752 #8189] INFO -- : Starting to build r62436 (1 revisions) from '/home/k0kubun/src/github.com/ruby/ruby'
23
+ I, [2018-02-17T15:00:17.683382 #8189] INFO -- : + git checkout d8d19683b62cc8e9254e651acd89a6cdfa3a0f54
24
+ ...(snip)...
25
+ I, [2018-02-17T15:00:17.716479 #8189] INFO -- : + /home/k0kubun/src/github.com/ruby/ruby/configure --disable-install-doc --prefix\=/home/k0kubun/.rbenv/versions/r62436
26
+ ...(snip)...
27
+ I, [2018-02-17T15:00:41.168594 #8189] INFO -- : + make -j8
28
+ ...(snip)...
29
+ I, [2018-02-17T15:01:33.717682 #8189] INFO -- : + make install
30
+ ...(snip)...
31
+ I, [2018-02-17T15:05:39.939284 #23243] INFO -- : Succeeded to install r62436 (1/1) to '/home/k0kubun/.rbenv/versions/r62436'
32
+ I, [2018-02-17T15:05:39.939364 #23243] INFO -- : + git -C /home/k0kubun/src/github.com/ruby/ruby checkout trunk
33
+ Previous HEAD position was d8d19683b6... fix regexp literal warning.
34
+ Switched to branch 'trunk'
35
+ $ rbenv versions
36
+ system
37
+ * 2.5.0 (set by /home/k0kubun/.rbenv/version)
38
+ r62436
39
+ $ rbenv shell r62436
40
+ $ ruby -v
41
+ ruby 2.6.0dev (2018-02-16 trunk 62436) [x86_64-linux]
42
+ ```
43
+
44
+ ### Multiple revisions build
45
+
46
+ ```
47
+ $ rbenv versions
48
+ system
49
+ * 2.5.0 (set by /home/k0kubun/.rbenv/version)
50
+ r62436
51
+ $ ruby-builder revision r62436..r62445 -d ~/src/github.com/ruby/ruby
52
+ I, [2018-02-17T15:09:12.852817 #5338] INFO -- : Parsing revisions at '/home/k0kubun/src/github.com/ruby/ruby'...
53
+ I, [2018-02-17T15:09:14.889281 #5338] INFO -- : Starting to build r62436..r62445 (3 revisions) from '/home/k0kubun/src/github.com/ruby/ruby'
54
+ I, [2018-02-17T15:09:14.894662 #5338] INFO -- : Skipped to install r62436 (1/3): already installed
55
+ I, [2018-02-17T15:09:14.894731 #5338] INFO -- : + git checkout 21249d849bb70217e0780b12d5f398826bd3b8d3
56
+ ...(snip)...
57
+ I, [2018-02-17T15:09:14.928467 #5338] INFO -- : + /home/k0kubun/src/github.com/ruby/ruby/configure --disable-install-doc --prefix\=/home/k0kubun/.rbenv/versions/r62437
58
+ ...(snip)...
59
+ I, [2018-02-17T15:09:34.250019 #5338] INFO -- : + make -j8
60
+ ...(snip)...
61
+ I, [2018-02-17T15:10:19.496940 #5338] INFO -- : + make install
62
+ ...(snip)...
63
+ I, [2018-02-17T15:10:22.204407 #5338] INFO -- : Succeeded to install r62437 (2/3) to '/home/k0kubun/.rbenv/versions/r62437'
64
+ I, [2018-02-17T15:10:22.204513 #5338] INFO -- : + git checkout def3714be2436413c85811005e3166ccf5633554
65
+ ...(snip)...
66
+ I, [2018-02-17T15:10:22.236696 #5338] INFO -- : + /home/k0kubun/src/github.com/ruby/ruby/configure --disable-install-doc --prefix\=/home/k0kubun/.rbenv/versions/r62445
67
+ ...(snip)...
68
+ I, [2018-02-17T15:10:42.356260 #5338] INFO -- : + make -j8
69
+ ...(snip)...
70
+ I, [2018-02-17T15:11:03.875723 #5338] INFO -- : + make install
71
+ ...(snip)...
72
+ I, [2018-02-17T15:11:05.625496 #5338] INFO -- : Succeeded to install r62445 (3/3) to '/home/k0kubun/.rbenv/versions/r62445'
73
+ I, [2018-02-17T15:11:05.625576 #5338] INFO -- : + git -C /home/k0kubun/src/github.com/ruby/ruby checkout trunk
74
+ Switched to branch 'trunk'
75
+ $ rbenv versions
76
+ system
77
+ * 2.5.0 (set by /home/k0kubun/.rbenv/version)
78
+ r62436
79
+ r62437
80
+ r62445
81
+ ```
82
+
83
+ ## License
84
+
85
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ruby/builder"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/ruby-builder ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path('../lib', __dir__)
4
+ require 'ruby/builder'
5
+
6
+ Ruby::Builder::CLI.start(ARGV)
@@ -0,0 +1,2 @@
1
+ require 'ruby/builder/cli'
2
+ require 'ruby/builder/version'
@@ -0,0 +1,74 @@
1
+ require 'logger'
2
+ require 'thor'
3
+ require 'ruby/builder/rbenv'
4
+ require 'ruby/builder/revision_parser'
5
+ require 'ruby/builder/ruby_builder'
6
+
7
+ module Ruby
8
+ module Builder
9
+ class CLI < Thor
10
+ class_option :source_directory, type: :string, aliases: %w[-d]
11
+
12
+ desc 'revision rXXXXX..rXXXXX', 'Build ruby binaries per revision'
13
+ def revision(spec)
14
+ source_dir = File.expand_path(options.fetch(:source_directory, Dir.pwd))
15
+
16
+ logger.info "Parsing revisions at '#{source_dir}'..."
17
+ revisions = RevisionParser.new(source_dir).parse(spec)
18
+
19
+ if revisions.empty?
20
+ logger.error "No revisions found for '#{spec}' in: #{source_dir}"
21
+ exit 1
22
+ end
23
+
24
+ logger.info "Starting to build #{spec} (#{revisions.size} revisions) from '#{source_dir}'"
25
+ Dir.mktmpdir("ruby-builder-") do |build_dir|
26
+ preserve_revision(source_dir) do
27
+ build_revisions(revisions, source_dir: source_dir, build_dir: build_dir)
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def build_revisions(revisions, source_dir:, build_dir:)
35
+ revisions.each_with_index do |revision, i|
36
+ if Rbenv.installed?(revision.name)
37
+ logger.info "Skipped to install #{revision.name} (#{i + 1}/#{revisions.size}): already installed"
38
+ next
39
+ end
40
+
41
+ install_dir = Rbenv.directory(revision.name)
42
+ begin
43
+ RubyBuilder.build(revision, source_dir: source_dir, build_dir: build_dir, install_dir: install_dir)
44
+ rescue BuildFailure => e
45
+ logger.error "Failed to install #{revision.name} (#{i + 1}/#{revisions.size}): #{e.class}: #{e.message}"
46
+ else
47
+ logger.info "Succeeded to install #{revision.name} (#{i + 1}/#{revisions.size}) to '#{install_dir}'"
48
+ end
49
+ end
50
+ end
51
+
52
+ def preserve_revision(source_dir, &block)
53
+ command = ['git', '-C', source_dir, 'rev-parse', '--abbrev-ref', 'HEAD']
54
+ orig_rev = IO.popen(command, &:read).rstrip
55
+ unless $?.success?
56
+ abort "Failed to execute '#{command.shelljoin}'"
57
+ end
58
+ block.call
59
+ ensure
60
+ if orig_rev
61
+ checkout_cmd = ['git', '-C', source_dir, 'checkout', orig_rev].shelljoin
62
+ logger.info("+ #{checkout_cmd}")
63
+ unless system(checkout_cmd)
64
+ abort "Failed to execute '#{checkout_cmd}'"
65
+ end
66
+ end
67
+ end
68
+
69
+ def logger
70
+ @logger ||= Logger.new(STDOUT)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,29 @@
1
+ require 'ruby/builder/revision'
2
+
3
+ module Ruby
4
+ module Builder
5
+ class << Rbenv = Module.new
6
+ # @param [String] version
7
+ def installed?(version)
8
+ File.directory?(directory(version))
9
+ end
10
+
11
+ # @param [String] version
12
+ def directory(version)
13
+ File.join(rbenv_root, 'versions', version)
14
+ end
15
+
16
+ private
17
+
18
+ def rbenv_root
19
+ return @rbenv_root if defined?(@rbenv_root)
20
+
21
+ @rbenv_root = IO.popen(['rbenv', 'root'], &:read).rstrip
22
+ unless $?.success?
23
+ abort "Failed to execute (exit status: #{$?}): rbenv root"
24
+ end
25
+ @rbenv_root
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ require 'immutable-struct'
2
+
3
+ module Ruby
4
+ module Builder
5
+ # @param [Integer] svn
6
+ # @param [String] git
7
+ Revision = ImmutableStruct.new(:svn, :git) do
8
+ def name
9
+ "r#{svn}"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,54 @@
1
+ require 'ruby/builder/revision'
2
+ require 'shellwords'
3
+
4
+ module Ruby
5
+ module Builder
6
+ class RevisionParser
7
+ # @param [String] source_dir
8
+ def initialize(source_dir)
9
+ @source_dir = source_dir
10
+ end
11
+
12
+ # @param [String] spec
13
+ def parse(spec)
14
+ unless match = spec.match(/\Ar(?<beg_rev>\d+)(\.\.r(?<end_rev>\d+))?\z/)
15
+ abort "Invalid revision specification '#{spec}': Doesn't match 'rXXXXX' or 'rXXXXX..rXXXXX'"
16
+ end
17
+
18
+ beg_rev = Integer(match[:beg_rev])
19
+ end_rev = Integer(match[:end_rev] || beg_rev)
20
+ if end_rev < beg_rev
21
+ abort "Invalid revision specification '#{spec}': #{beg_rev} is larger than #{end_rev}"
22
+ end
23
+
24
+ # Note: ruby-builder currently supports only trunk revisions
25
+ trunk_revs = (beg_rev..end_rev).select { |rev| trunk_revision?(rev) }
26
+ trunk_revs.map! do |rev|
27
+ build_revision(rev)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # @param [Integer] rev
34
+ def trunk_revision?(rev)
35
+ command = ['git', '-C', @source_dir, 'log', '--grep', "/trunk@#{rev} ", '-1']
36
+ result = IO.popen(command, &:read)
37
+ unless $?.success?
38
+ abort "Failed to execute (exit status: #{$?.exitstatus}): #{command.shelljoin}"
39
+ end
40
+ !result.empty?
41
+ end
42
+
43
+ # @param [Integer] rev
44
+ def build_revision(rev)
45
+ command = ['git', '-C', @source_dir, 'log', '--grep', "/trunk@#{rev} ", '--format=format:%H', '-1']
46
+ git_revision = IO.popen(command, &:read)
47
+ unless $?.success?
48
+ abort "Failed to execute (exit status: #{$?.exitstatus}): #{command.shelljoin}"
49
+ end
50
+ Revision.new(svn: rev, git: git_revision)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,42 @@
1
+ require 'logger'
2
+ require 'shellwords'
3
+ require 'tmpdir'
4
+
5
+ module Ruby
6
+ module Builder
7
+ BuildFailure = Class.new(StandardError)
8
+
9
+ class << RubyBuilder = Module.new
10
+ # @param [Ruby::Builder::Revision] revision
11
+ # @param [String] source_dir
12
+ # @param [String] build_dir
13
+ # @param [String] install_dir
14
+ def build(revision, source_dir:, build_dir:, install_dir:)
15
+ execute('git', 'checkout', revision.git, dir: source_dir)
16
+ unless File.executable?(File.join(source_dir, 'configure'))
17
+ execute('autoreconf', dir: source_dir)
18
+ end
19
+ execute(File.join(source_dir, 'configure'), '--disable-install-doc', "--prefix=#{install_dir}", dir: build_dir)
20
+ execute('make', "-j#{Etc.nprocessors}", dir: build_dir)
21
+ execute('make', 'install', dir: build_dir)
22
+ end
23
+
24
+ private
25
+
26
+ # @param [Array<String>] command
27
+ # @param [String] dir
28
+ def execute(*command, dir:)
29
+ Dir.chdir(dir) do
30
+ logger.info("+ #{command.shelljoin}")
31
+ unless system(command.shelljoin)
32
+ raise BuildFailure.new("Failed to execute '#{command.shelljoin}' at '#{dir}' (exit status: #{$?.exitstatus})")
33
+ end
34
+ end
35
+ end
36
+
37
+ def logger
38
+ @logger ||= Logger.new(STDOUT)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,5 @@
1
+ module Ruby
2
+ module Builder
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ruby/builder/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'ruby-builder'
8
+ spec.version = Ruby::Builder::VERSION
9
+ spec.authors = ['Takashi Kokubun']
10
+ spec.email = ['takashikkbn@gmail.com']
11
+
12
+ spec.summary = %q{Build ruby binaries per revision under rbenv directory}
13
+ spec.description = %q{Build ruby binaries per revision under rbenv directory}
14
+ spec.homepage = 'https://github.com/benchmark-driver/ruby-builder'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+ spec.required_ruby_version = '>= 2.1.0'
24
+
25
+ spec.add_dependency 'thor'
26
+ spec.add_dependency 'immutable-struct'
27
+ spec.add_development_dependency 'bundler'
28
+ spec.add_development_dependency 'rake'
29
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Takashi Kokubun
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-02-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: immutable-struct
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Build ruby binaries per revision under rbenv directory
70
+ email:
71
+ - takashikkbn@gmail.com
72
+ executables:
73
+ - ruby-builder
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - CHANGELOG.md
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/console
84
+ - bin/setup
85
+ - exe/ruby-builder
86
+ - lib/ruby/builder.rb
87
+ - lib/ruby/builder/cli.rb
88
+ - lib/ruby/builder/rbenv.rb
89
+ - lib/ruby/builder/revision.rb
90
+ - lib/ruby/builder/revision_parser.rb
91
+ - lib/ruby/builder/ruby_builder.rb
92
+ - lib/ruby/builder/version.rb
93
+ - ruby-builder.gemspec
94
+ homepage: https://github.com/benchmark-driver/ruby-builder
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 2.1.0
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.7.5
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Build ruby binaries per revision under rbenv directory
118
+ test_files: []