evm 0.6.1 → 0.9.0
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/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
|