evm 0.6.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +278 -0
- data/bin/evm +12 -0
- data/lib/evm.rb +7 -28
- data/lib/evm/builder.rb +18 -17
- data/lib/evm/cli.rb +43 -18
- data/lib/evm/command.rb +2 -1
- data/lib/evm/command/bin.rb +2 -2
- data/lib/evm/command/config.rb +19 -0
- data/lib/evm/command/disuse.rb +15 -0
- data/lib/evm/command/install.rb +3 -1
- data/lib/evm/command/list.rb +1 -1
- data/lib/evm/command/uninstall.rb +3 -1
- data/lib/evm/command/use.rb +3 -1
- data/lib/evm/config.rb +43 -0
- data/lib/evm/git.rb +1 -1
- data/lib/evm/package.rb +26 -11
- data/lib/evm/remote_file.rb +9 -55
- data/lib/evm/tar_file.rb +1 -1
- data/spec/evm/builder_spec.rb +209 -0
- data/spec/evm/cli_spec.rb +53 -0
- data/spec/evm/command/bin_spec.rb +32 -0
- data/spec/evm/command/config_spec.rb +34 -0
- data/spec/evm/command/disuse_spec.rb +19 -0
- data/spec/evm/command/install_spec.rb +103 -0
- data/spec/evm/command/list_spec.rb +36 -0
- data/spec/evm/command/uninstall_spec.rb +35 -0
- data/spec/evm/command/use_spec.rb +32 -0
- data/spec/evm/config_spec.rb +36 -0
- data/spec/evm/evm_spec.rb +11 -0
- data/spec/evm/git_spec.rb +39 -0
- data/spec/evm/os_spec.rb +47 -0
- data/spec/evm/package_spec.rb +274 -0
- data/spec/evm/recipe_spec.rb +47 -0
- data/spec/evm/remote_file_spec.rb +47 -0
- data/spec/evm/system_spec.rb +36 -0
- data/spec/evm/tar_file_spec.rb +21 -0
- data/spec/spec_helper.rb +13 -0
- metadata +29 -17
- data/lib/evm/exception.rb +0 -4
- data/lib/evm/progress_bar.rb +0 -37
- data/recipes/emacs-23.4-bin.rb +0 -7
- data/recipes/emacs-23.4.rb +0 -27
- data/recipes/emacs-24.1-bin.rb +0 -7
- data/recipes/emacs-24.1.rb +0 -24
- data/recipes/emacs-24.2-bin.rb +0 -7
- data/recipes/emacs-24.2.rb +0 -24
- data/recipes/emacs-24.3-bin.rb +0 -7
- data/recipes/emacs-24.3.rb +0 -24
- data/recipes/emacs-24.4-bin.rb +0 -7
- data/recipes/emacs-24.4.rb +0 -24
- data/recipes/emacs-git-snapshot.rb +0 -25
data/lib/evm/command.rb
CHANGED
data/lib/evm/command/bin.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Evm
|
2
|
+
module Command
|
3
|
+
class Config
|
4
|
+
def initialize(argv, options = {})
|
5
|
+
type, value = argv
|
6
|
+
|
7
|
+
unless Evm::CONFIG_TYPES.include?(type.to_sym)
|
8
|
+
raise Evm::Exception, "Invalid config type: #{type}"
|
9
|
+
end
|
10
|
+
|
11
|
+
if value
|
12
|
+
Evm.config[type] = value
|
13
|
+
end
|
14
|
+
|
15
|
+
STDOUT.puts(Evm.config[type])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/evm/command/install.rb
CHANGED
data/lib/evm/command/list.rb
CHANGED
data/lib/evm/command/use.rb
CHANGED
data/lib/evm/config.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Evm
|
4
|
+
class Config
|
5
|
+
def initialize(config_file, defaults = {})
|
6
|
+
@config_file = config_file
|
7
|
+
@defaults = defaults
|
8
|
+
end
|
9
|
+
|
10
|
+
def [](type)
|
11
|
+
config[type.to_s] || begin
|
12
|
+
default = @defaults.find { |key, value| key.to_s == type.to_s }
|
13
|
+
default[1] if default
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def []=(type, value)
|
18
|
+
write(config.merge(type.to_s => value))
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def config
|
25
|
+
if File.exist?(@config_file)
|
26
|
+
contents = File.read(@config_file)
|
27
|
+
if contents.empty?
|
28
|
+
{}
|
29
|
+
else
|
30
|
+
JSON.parse(contents)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
{}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def write(config = {})
|
38
|
+
File.open(@config_file, 'w') do |file|
|
39
|
+
file.write(config.to_json)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/evm/git.rb
CHANGED
data/lib/evm/package.rb
CHANGED
@@ -2,8 +2,9 @@ module Evm
|
|
2
2
|
class Package
|
3
3
|
attr_reader :name
|
4
4
|
|
5
|
-
def initialize(name)
|
5
|
+
def initialize(name, options = {})
|
6
6
|
@name = name
|
7
|
+
@file = options[:file] || File
|
7
8
|
end
|
8
9
|
|
9
10
|
def current?
|
@@ -23,9 +24,24 @@ module Evm
|
|
23
24
|
end
|
24
25
|
|
25
26
|
def use!
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
delete_shims!
|
28
|
+
[Evm::EMACS_PATH, Evm::EVM_EMACS_PATH].each do |bin_path|
|
29
|
+
@file.open(bin_path, 'w') do |file|
|
30
|
+
file.puts("#!/bin/bash\nexec \"#{bin}\" \"$@\"")
|
31
|
+
end
|
32
|
+
@file.chmod(0755, bin_path)
|
33
|
+
end
|
34
|
+
Evm.config[:current] = name
|
35
|
+
end
|
36
|
+
|
37
|
+
def disuse!
|
38
|
+
delete_shims!
|
39
|
+
Evm.config[:current] = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete_shims!
|
43
|
+
[Evm::EMACS_PATH, Evm::EVM_EMACS_PATH].each do |bin_path|
|
44
|
+
@file.delete(bin_path) if @file.exists?(bin_path)
|
29
45
|
end
|
30
46
|
end
|
31
47
|
|
@@ -60,20 +76,17 @@ module Evm
|
|
60
76
|
end
|
61
77
|
|
62
78
|
def path
|
63
|
-
File.join(Evm
|
79
|
+
File.join(Evm.config[:path], @name)
|
64
80
|
end
|
65
81
|
|
66
82
|
def tmp_path
|
67
|
-
File.join(Evm
|
83
|
+
File.join(Evm.config[:path], 'tmp')
|
68
84
|
end
|
69
85
|
|
70
86
|
class << self
|
71
87
|
def current
|
72
|
-
if
|
73
|
-
|
74
|
-
if (match = Regexp.new("#{Evm::LOCAL_PATH}/?(?<current>[^/]+)/.+").match(current_bin_path))
|
75
|
-
find match[:current]
|
76
|
-
end
|
88
|
+
if (name = Evm.config[:current])
|
89
|
+
find(name)
|
77
90
|
end
|
78
91
|
end
|
79
92
|
|
@@ -93,5 +106,7 @@ module Evm
|
|
93
106
|
end
|
94
107
|
end
|
95
108
|
end
|
109
|
+
|
110
|
+
private :delete_shims!
|
96
111
|
end
|
97
112
|
end
|
data/lib/evm/remote_file.rb
CHANGED
@@ -1,64 +1,18 @@
|
|
1
|
-
require 'uri'
|
2
|
-
require 'thread'
|
3
|
-
require 'net/http'
|
4
|
-
require 'openssl'
|
1
|
+
require 'open-uri'
|
5
2
|
|
6
3
|
module Evm
|
7
4
|
class RemoteFile
|
8
|
-
def initialize(url)
|
5
|
+
def initialize(url, options = {})
|
9
6
|
@url = url
|
7
|
+
@options = options
|
8
|
+
@file = options[:file] ||= File
|
9
|
+
@uri = options[:uri] ||= URI
|
10
10
|
end
|
11
11
|
|
12
|
-
def download(path
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
thread = Thread.new do
|
18
|
-
this = Thread.current
|
19
|
-
body = this[:body] = []
|
20
|
-
|
21
|
-
request @url do |response|
|
22
|
-
length = this[:length] = response['Content-Length'].to_i
|
23
|
-
|
24
|
-
response.read_body do |fragment|
|
25
|
-
body << fragment
|
26
|
-
|
27
|
-
this[:done] = (this[:done] || 0) + fragment.length
|
28
|
-
this[:progress] = this[:done].quo(length) * 100
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
file.write(body.join)
|
33
|
-
end
|
34
|
-
|
35
|
-
until thread.join(1)
|
36
|
-
yield thread[:progress]
|
37
|
-
end
|
38
|
-
|
39
|
-
file.close
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def request(url, &block)
|
45
|
-
uri = URI.parse(url)
|
46
|
-
|
47
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
48
|
-
if uri.scheme == 'https'
|
49
|
-
http.use_ssl = true
|
50
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
51
|
-
end
|
52
|
-
http.request_get(uri.path) do |response|
|
53
|
-
case response
|
54
|
-
when Net::HTTPSuccess
|
55
|
-
block.call(response)
|
56
|
-
when Net::HTTPRedirection
|
57
|
-
request response['location'] do |response|
|
58
|
-
block.call(response)
|
59
|
-
end
|
60
|
-
else
|
61
|
-
response.error!
|
12
|
+
def download(path)
|
13
|
+
unless @file.exist?(path)
|
14
|
+
@file.open(path, 'w') do |file|
|
15
|
+
file.write(@uri.parse(@url).read)
|
62
16
|
end
|
63
17
|
end
|
64
18
|
end
|
data/lib/evm/tar_file.rb
CHANGED
@@ -0,0 +1,209 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Evm::Builder do
|
4
|
+
describe Evm::Builder::Dsl do
|
5
|
+
before do
|
6
|
+
@tar_gz_url = 'http://domain.com/foo.tar.gz'
|
7
|
+
@git_url = 'git://domain.com/emacs.git'
|
8
|
+
|
9
|
+
@dsl = Evm::Builder::Dsl.new
|
10
|
+
allow(@dsl).to receive(:path).and_return('/path/to')
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#tar_gz' do
|
14
|
+
it 'should download and extract tar' do
|
15
|
+
tar_file_path = '/tmp/evm/tmp/name.tar.gz'
|
16
|
+
|
17
|
+
remote_file = double('remote_file')
|
18
|
+
expect(remote_file).to receive(:download).with(tar_file_path)
|
19
|
+
|
20
|
+
expect(Evm::RemoteFile).to receive(:new).with(@tar_gz_url).and_return(remote_file)
|
21
|
+
|
22
|
+
tar_file = double('tar_file')
|
23
|
+
expect(tar_file).to receive(:extract).with('/tmp/evm/tmp', 'name')
|
24
|
+
|
25
|
+
expect(Evm::TarFile).to receive(:new).with(tar_file_path).and_return(tar_file)
|
26
|
+
|
27
|
+
expect(FileUtils).to receive(:mkdir).with('/tmp/evm/tmp/name')
|
28
|
+
|
29
|
+
@dsl.recipe 'name' do
|
30
|
+
@dsl.tar_gz(@tar_gz_url)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#git' do
|
36
|
+
before do
|
37
|
+
@git_repo = double('git_repo')
|
38
|
+
allow(@git_repo).to receive(:exist?).and_return(true)
|
39
|
+
allow(@git_repo).to receive(:clone)
|
40
|
+
allow(@git_repo).to receive(:pull)
|
41
|
+
|
42
|
+
allow(Evm::Git).to receive(:new).and_return(@git_repo)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should pull if exist' do
|
46
|
+
allow(@git_repo).to receive(:exist?).and_return(true)
|
47
|
+
expect(@git_repo).to receive(:pull)
|
48
|
+
|
49
|
+
@dsl.recipe 'name' do
|
50
|
+
@dsl.git(@git_url)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should clone if not exist' do
|
55
|
+
allow(@git_repo).to receive(:exist?).and_return(false)
|
56
|
+
expect(@git_repo).to receive(:clone).with(@git_url)
|
57
|
+
|
58
|
+
@dsl.recipe 'name' do
|
59
|
+
@dsl.git(@git_url)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#osx' do
|
65
|
+
it 'should yield if osx' do
|
66
|
+
allow(Evm::Os).to receive(:osx?).and_return(true)
|
67
|
+
|
68
|
+
expect { |block|
|
69
|
+
@dsl.osx(&block)
|
70
|
+
}.to yield_control
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should not yield if not osx' do
|
74
|
+
allow(Evm::Os).to receive(:osx?).and_return(false)
|
75
|
+
|
76
|
+
expect { |block|
|
77
|
+
@dsl.osx(&block)
|
78
|
+
}.not_to yield_control
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#linux' do
|
83
|
+
it 'should yield if linux' do
|
84
|
+
allow(Evm::Os).to receive(:linux?).and_return(true)
|
85
|
+
|
86
|
+
expect { |block|
|
87
|
+
@dsl.linux(&block)
|
88
|
+
}.to yield_control
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should not yield if not linux' do
|
92
|
+
allow(Evm::Os).to receive(:linux?).and_return(false)
|
93
|
+
|
94
|
+
expect { |block|
|
95
|
+
@dsl.linux(&block)
|
96
|
+
}.not_to yield_control
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#option' do
|
101
|
+
it 'should add option without value' do
|
102
|
+
@dsl.option '--foo'
|
103
|
+
expect(@dsl.instance_variable_get('@options')).to eq(['--foo'])
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should add option with value' do
|
107
|
+
@dsl.option '--foo', 'bar'
|
108
|
+
expect(@dsl.instance_variable_get('@options')).to eq(['--foo', 'bar'])
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should add multiple options' do
|
112
|
+
@dsl.option '--foo'
|
113
|
+
@dsl.option '--foo', 'bar'
|
114
|
+
@dsl.option '--bar', 'baz'
|
115
|
+
@dsl.option '--qux'
|
116
|
+
expect(@dsl.instance_variable_get('@options')).to eq(['--foo', '--foo', 'bar', '--bar', 'baz', '--qux'])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#install' do
|
121
|
+
it 'should yield' do
|
122
|
+
expect { |block|
|
123
|
+
@dsl.install(&block)
|
124
|
+
}.to yield_control
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#autogen' do
|
129
|
+
it 'should run make command with target' do
|
130
|
+
expect(@dsl).to receive(:run_command).with('./autogen.sh')
|
131
|
+
@dsl.autogen
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#configure' do
|
136
|
+
it 'should configure when no options' do
|
137
|
+
expect(@dsl).to receive(:run_command).with('./configure')
|
138
|
+
@dsl.configure
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should configure when single option' do
|
142
|
+
expect(@dsl).to receive(:run_command).with('./configure', '--foo', 'bar')
|
143
|
+
@dsl.option '--foo', 'bar'
|
144
|
+
@dsl.configure
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should configure when multiple options' do
|
148
|
+
expect(@dsl).to receive(:run_command).with('./configure', '--foo', 'bar', '--baz')
|
149
|
+
@dsl.option '--foo', 'bar'
|
150
|
+
@dsl.option '--baz'
|
151
|
+
@dsl.configure
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '#make' do
|
156
|
+
it 'should run make command with target' do
|
157
|
+
expect(@dsl).to receive(:run_command).with('make', 'foo')
|
158
|
+
@dsl.make('foo')
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#build_path' do
|
163
|
+
it 'should return package build path' do
|
164
|
+
@dsl.recipe 'name' do
|
165
|
+
expect(@dsl.build_path).to eq('/tmp/evm/tmp/name')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe '#builds_path' do
|
171
|
+
it 'should return package builds path' do
|
172
|
+
@dsl.recipe 'name' do
|
173
|
+
expect(@dsl.builds_path).to eq('/tmp/evm/tmp')
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe '#installation_path' do
|
179
|
+
it 'should return package installation path' do
|
180
|
+
@dsl.recipe 'name' do
|
181
|
+
expect(@dsl.installation_path).to eq('/tmp/evm/name')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe '#installations_path' do
|
187
|
+
it 'should return package installations path' do
|
188
|
+
@dsl.recipe 'name' do
|
189
|
+
expect(@dsl.installations_path).to eq('/tmp/evm')
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe '#platform_name' do
|
195
|
+
it 'should platform name' do
|
196
|
+
allow(Evm::Os).to receive(:platform_name).and_return(:foo)
|
197
|
+
|
198
|
+
expect(@dsl.platform_name).to eq(:foo)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe '#copy' do
|
203
|
+
it 'copies all files recursively and preserves file attributes' do
|
204
|
+
expect(@dsl).to receive(:run_command).with('cp -a from to')
|
205
|
+
@dsl.copy 'from', 'to'
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|