wwtd 0.1.2

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.
Files changed (6) hide show
  1. data.tar.gz.sig +0 -0
  2. data/bin/wwtd +5 -0
  3. data/lib/wwtd.rb +186 -0
  4. data/lib/wwtd/version.rb +3 -0
  5. metadata +101 -0
  6. metadata.gz.sig +0 -0
Binary file
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << File.expand_path("../../lib", __FILE__)
3
+ require "rubygems" if RUBY_VERSION < "1.9"
4
+ require "wwtd"
5
+ exit WWTD.run(ARGV)
@@ -0,0 +1,186 @@
1
+ require "wwtd/version"
2
+ require "optparse"
3
+ require "yaml"
4
+ require "shellwords"
5
+ require "parallel"
6
+ require "tempfile"
7
+
8
+ module WWTD
9
+ CONFIG = ".travis.yml"
10
+ DEFAULT_GEMFILE = "Gemfile"
11
+ COMBINATORS = ["rvm", "gemfile", "env"]
12
+ UNDERSTOOD = ["rvm", "gemfile", "matrix", "script", "bundler_args"]
13
+
14
+ class << self
15
+ def run(argv)
16
+ options = parse_options(argv)
17
+
18
+ # Read actual .travis.yml
19
+ config = (File.exist?(CONFIG) ? YAML.load_file(CONFIG) : {})
20
+ config.delete("source_key") # we don't need that we already have the source
21
+ ignored = config.keys - UNDERSTOOD
22
+ puts "Ignoring: #{ignored.sort.join(", ")}" unless ignored.empty?
23
+
24
+ # Execute tests
25
+ matrix = matrix(config)
26
+ results = nil
27
+ Tempfile.open "wwtd" do |lock|
28
+ results = Parallel.map(matrix.each_with_index, :in_processes => options[:parallel].to_i) do |config, i|
29
+ ENV["TEST_ENV_NUMBER"] = (i == 0 ? "" : (i + 1).to_s) if options[:parallel]
30
+
31
+ config_info = config_info(matrix, config)
32
+ puts "#{yellow("START")} #{config_info}"
33
+
34
+ result = run_config(config, lock)
35
+ info = "#{result ? green("SUCCESS") : red("FAILURE")} #{config_info}"
36
+ puts info
37
+
38
+ [result, info]
39
+ end
40
+ end
41
+
42
+ # Summary
43
+ if matrix.size > 1
44
+ puts "\nResults:"
45
+ puts results.map(&:last)
46
+ end
47
+
48
+ results.all?(&:first) ? 0 : 1
49
+ end
50
+
51
+ private
52
+
53
+ def config_info(matrix, config)
54
+ config = config.select { |k,v| matrix.map { |c| c[k] }.uniq.size > 1 }.sort
55
+ "#{config.map { |k,v| "#{k}: #{truncate(v, 30)}" }.join(", ")}"
56
+ end
57
+
58
+ def tint(color, string)
59
+ if $stdout.tty?
60
+ "\e[#{color}m#{string}\e[0m"
61
+ else
62
+ string
63
+ end
64
+ end
65
+
66
+ def red(string)
67
+ tint(31, string)
68
+ end
69
+
70
+ def green(string)
71
+ tint(32, string)
72
+ end
73
+
74
+ def yellow(string)
75
+ tint(33, string)
76
+ end
77
+
78
+ def matrix(config)
79
+ components = COMBINATORS.map do |multiplier|
80
+ next unless values = config[multiplier]
81
+ Array(values).map { |v| {multiplier => v} }
82
+ end.compact
83
+
84
+ components = components.inject([{}]) { |all, v| all.product(v).map! { |values| merge_hashes(values) } }
85
+ if config["matrix"] && config["matrix"]["exclude"]
86
+ components -= config.delete("matrix").delete("exclude")
87
+ end
88
+ components.map! { |c| config.merge(c) }
89
+ end
90
+
91
+ def truncate(value, number)
92
+ value = value.to_s # accidental numbers like 'rvm: 2.0'
93
+ if value.size > number
94
+ "#{value[0...27]}..."
95
+ else
96
+ value
97
+ end
98
+ end
99
+
100
+ def clone(object)
101
+ Marshal.load(Marshal.dump(object))
102
+ end
103
+
104
+ def merge_hashes(array)
105
+ array.inject({}) { |all, v| all.merge!(v); all }
106
+ end
107
+
108
+ def run_config(config, lock)
109
+ if gemfile = config["gemfile"]
110
+ ENV["BUNDLE_GEMFILE"] = gemfile
111
+ end
112
+ wants_bundle = gemfile || File.exist?(DEFAULT_GEMFILE)
113
+
114
+ Shellwords.split(config["env"] || "").each do |part|
115
+ name, value = part.split("=", 2)
116
+ ENV[name] = value
117
+ end
118
+
119
+ with_clean_env do
120
+ rvm = "rvm #{config["rvm"]} do " if config["rvm"]
121
+
122
+ if wants_bundle
123
+ flock(lock) do
124
+ default_bundler_args = "--deployment" if File.exist?("#{gemfile || DEFAULT_GEMFILE}.lock")
125
+ bundle_command = "#{rvm}bundle install #{config["bundler_args"] || default_bundler_args}"
126
+ return false unless sh "#{bundle_command.strip} --quiet --path #{Dir.pwd}/vendor/bundle"
127
+ end
128
+ end
129
+
130
+ default_command = (wants_bundle ? "bundle exec rake" : "rake")
131
+ command = config["script"] || default_command
132
+ command = "#{rvm}#{command}"
133
+
134
+ sh(command)
135
+ end
136
+ end
137
+
138
+ def flock(file)
139
+ File.open(file.path) do |f|
140
+ begin
141
+ f.flock(File::LOCK_EX)
142
+ yield
143
+ ensure
144
+ f.flock(File::LOCK_UN)
145
+ end
146
+ end
147
+ end
148
+
149
+ # http://grosser.it/2010/12/11/sh-without-rake/
150
+ def sh(cmd)
151
+ puts cmd
152
+ IO.popen(cmd) do |pipe|
153
+ while str = pipe.gets
154
+ puts str
155
+ end
156
+ end
157
+ $?.success?
158
+ end
159
+
160
+ def with_clean_env(&block)
161
+ if defined?(Bundler)
162
+ Bundler.with_clean_env(&block)
163
+ else
164
+ yield
165
+ end
166
+ end
167
+
168
+ def parse_options(argv)
169
+ options = {}
170
+ OptionParser.new do |opts|
171
+ opts.banner = <<-BANNER.gsub(/^ {10}/, "")
172
+ WWTD: Travis simulator - faster + no more waiting for build emails
173
+
174
+ Usage:
175
+ wwtd
176
+
177
+ Options:
178
+ BANNER
179
+ opts.on("-p", "--parallel [PROCESSES]", Integer, "Run in parallel") { |c| options[:parallel] = c || Parallel.processor_count }
180
+ opts.on("-h", "--help", "Show this.") { puts opts; exit }
181
+ opts.on("-v", "--version", "Show Version"){ puts WWTD::VERSION; exit}
182
+ end.parse!(argv)
183
+ options
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,3 @@
1
+ module WWTD
2
+ VERSION = "0.1.2"
3
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wwtd
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 2
10
+ version: 0.1.2
11
+ platform: ruby
12
+ authors:
13
+ - Michael Grosser
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain:
17
+ - |
18
+ -----BEGIN CERTIFICATE-----
19
+ MIIDMjCCAhqgAwIBAgIBADANBgkqhkiG9w0BAQUFADA/MRAwDgYDVQQDDAdtaWNo
20
+ YWVsMRcwFQYKCZImiZPyLGQBGRYHZ3Jvc3NlcjESMBAGCgmSJomT8ixkARkWAml0
21
+ MB4XDTEzMDIwMzE4MTMxMVoXDTE0MDIwMzE4MTMxMVowPzEQMA4GA1UEAwwHbWlj
22
+ aGFlbDEXMBUGCgmSJomT8ixkARkWB2dyb3NzZXIxEjAQBgoJkiaJk/IsZAEZFgJp
23
+ dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMorXo/hgbUq97+kII9H
24
+ MsQcLdC/7wQ1ZP2OshVHPkeP0qH8MBHGg6eYisOX2ubNagF9YTCZWnhrdKrwpLOO
25
+ cPLaZbjUjljJ3cQR3B8Yn1veV5IhG86QseTBjymzJWsLpqJ1UZGpfB9tXcsFtuxO
26
+ 6vHvcIHdzvc/OUkICttLbH+1qb6rsHUceqh+JrH4GrsJ5H4hAfIdyS2XMK7YRKbh
27
+ h+IBu6dFWJJByzFsYmV1PDXln3UBmgAt65cmCu4qPfThioCGDzbSJrGDGLmw/pFX
28
+ FPpVCm1zgYSb1v6Qnf3cgXa2f2wYGm17+zAVyIDpwryFru9yF/jJxE38z/DRsd9R
29
+ /88CAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUsiNnXHtKeMYYcr4yJVmQ
30
+ WONL+IwwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQAlyN7kKo/NQCQ0
31
+ AOzZLZ3WAePvStkCFIJ53tsv5Kyo4pMAllv+BgPzzBt7qi605mFSL6zBd9uLou+W
32
+ Co3s48p1dy7CjjAfVQdmVNHF3MwXtfC2OEyvSQPi4xKR8iba8wa3xp9LVo1PuLpw
33
+ /6DsrChWw74HfsJN6qJOK684hJeT8lBYAUfiC3wD0owoPSg+XtyAAddisR+KV5Y1
34
+ NmVHuLtQcNTZy+gRht3ahJRMuC6QyLmkTsf+6MaenwAMkAgHdswGsJztOnNnBa3F
35
+ y0kCSWmK6D+x/SbfS6r7Ke07MRqziJdB9GuE1+0cIRuFh8EQ+LN6HXCKM5pon/GU
36
+ ycwMXfl0
37
+ -----END CERTIFICATE-----
38
+
39
+ date: 2013-09-01 00:00:00 Z
40
+ dependencies:
41
+ - !ruby/object:Gem::Dependency
42
+ name: parallel
43
+ prerelease: false
44
+ type: :runtime
45
+ requirement: &id001 !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ hash: 3
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ version_requirements: *id001
55
+ description:
56
+ email: michael@grosser.it
57
+ executables:
58
+ - wwtd
59
+ extensions: []
60
+
61
+ extra_rdoc_files: []
62
+
63
+ files:
64
+ - bin/wwtd
65
+ - lib/wwtd.rb
66
+ - lib/wwtd/version.rb
67
+ homepage: http://github.com/grosser/wwtd
68
+ licenses:
69
+ - MIT
70
+ post_install_message:
71
+ rdoc_options: []
72
+
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ hash: 3
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ requirements: []
94
+
95
+ rubyforge_project:
96
+ rubygems_version: 1.8.25
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Travis simulator so you do not need to wait for the build
100
+ test_files: []
101
+
Binary file