geoffrey 0.1.0 → 0.1.1
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.
- data/Gemfile.lock +1 -1
- data/README.md +3 -0
- data/bin/geoffrey +1 -0
- data/lib/geoffrey.rb +1 -2
- data/lib/geoffrey/cli.rb +24 -4
- data/lib/geoffrey/file_helper.rb +14 -0
- data/lib/geoffrey/package.rb +62 -16
- data/lib/geoffrey/template.rb +39 -0
- data/lib/geoffrey/version.rb +1 -1
- data/spec/cli_spec.rb +20 -2
- data/spec/package_spec.rb +31 -3
- data/spec/static/template1.json +4 -0
- data/spec/static/template1.rb +2 -0
- data/spec/static/template2.json +9 -0
- data/spec/template_spec.rb +37 -0
- data/spec/templates/simbl.rb +1 -0
- data/templates/burn.json +4 -0
- metadata +10 -3
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -40,6 +40,9 @@ provided recipes, and install them.
|
|
40
40
|
>> Moving file to /Applications
|
41
41
|
>> Install successful
|
42
42
|
|
43
|
+
$ geoffrey seach jabber
|
44
|
+
>> Adium: Adium is a free instant messaging application for Mac OS X that can connect to AIM, MSN, Jabber, Yahoo, and more.
|
45
|
+
|
43
46
|
API
|
44
47
|
===
|
45
48
|
|
data/bin/geoffrey
CHANGED
data/lib/geoffrey.rb
CHANGED
data/lib/geoffrey/cli.rb
CHANGED
@@ -19,19 +19,39 @@ module Geoffrey
|
|
19
19
|
method_options :verbose => :boolean
|
20
20
|
def install(name)
|
21
21
|
if file = file_for_template(name)
|
22
|
-
@package = Geoffrey::
|
22
|
+
@package = Geoffrey::Template.new(file).package
|
23
23
|
@package.verbose(true) if options[:verbose]
|
24
|
-
@package.
|
25
|
-
@package.download_and_decompress
|
26
|
-
@package.install
|
24
|
+
@package.process
|
27
25
|
else
|
28
26
|
puts "Template not found"
|
29
27
|
exit 1
|
30
28
|
end
|
31
29
|
end
|
32
30
|
|
31
|
+
desc "search [pattern]", "search for templates"
|
32
|
+
def search(pattern)
|
33
|
+
fitting_packages = packages.select{ |pack| pack.fits?(pattern) }
|
34
|
+
if fitting_packages && !fitting_packages.empty?
|
35
|
+
fitting_packages.each do |pack|
|
36
|
+
line = pack.name
|
37
|
+
line << ": #{pack.description}" if pack.description && pack.description != ""
|
38
|
+
puts line
|
39
|
+
end
|
40
|
+
else
|
41
|
+
puts "No templates available fit that description"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
33
45
|
private
|
34
46
|
|
47
|
+
def packages
|
48
|
+
@packages ||= begin
|
49
|
+
list_of_templates.map do |template_file|
|
50
|
+
Geoffrey::Template.new(template_file).package
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
35
55
|
#--
|
36
56
|
# TODO Might be useful for the future to have multiple dirs for templates.
|
37
57
|
def templates_dir
|
data/lib/geoffrey/package.rb
CHANGED
@@ -4,6 +4,13 @@ require 'open-uri'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'progressbar'
|
6
6
|
require 'geoffrey/reporter'
|
7
|
+
require 'geoffrey/file_helper'
|
8
|
+
|
9
|
+
class String
|
10
|
+
def escape_path
|
11
|
+
self.gsub(' ','\ ')
|
12
|
+
end
|
13
|
+
end
|
7
14
|
|
8
15
|
module Geoffrey
|
9
16
|
|
@@ -14,14 +21,16 @@ module Geoffrey
|
|
14
21
|
class Package
|
15
22
|
|
16
23
|
include Geoffrey::Reporter
|
24
|
+
include Geoffrey::FileHelper
|
17
25
|
|
18
|
-
attr_accessor :url, :description, :options, :format, :filename,
|
26
|
+
attr_accessor :url, :description, :options, :format, :filename,
|
27
|
+
:dir, :file, :guessed_name
|
19
28
|
|
20
29
|
def initialize
|
21
30
|
@options = {}
|
22
31
|
end
|
23
32
|
|
24
|
-
[:url,:
|
33
|
+
[:url,:description].each do |attrib|
|
25
34
|
class_eval <<-GEOF
|
26
35
|
def #{attrib}(val=nil)
|
27
36
|
val.nil? ? @#{attrib} : @#{attrib} = val
|
@@ -29,6 +38,40 @@ module Geoffrey
|
|
29
38
|
GEOF
|
30
39
|
end
|
31
40
|
|
41
|
+
# We will do some kind of symbolize_keys, but manually so we don't have to
|
42
|
+
# use activesupport just for this. Pretty much blatantly copied from it :P.
|
43
|
+
def options(val=nil)
|
44
|
+
if !val.nil? && val.is_a?(Hash)
|
45
|
+
@options = {}
|
46
|
+
val.each do |k,v|
|
47
|
+
@options[k.to_sym] = v
|
48
|
+
end
|
49
|
+
end
|
50
|
+
@options
|
51
|
+
end
|
52
|
+
|
53
|
+
def name(val=nil)
|
54
|
+
if val.nil? && @name.nil? && (!@url.nil? || !@guessed_name.nil?)
|
55
|
+
@name = remove_extension(@guessed_name||get_filename)
|
56
|
+
elsif !val.nil?
|
57
|
+
@name = val
|
58
|
+
end
|
59
|
+
@name
|
60
|
+
end
|
61
|
+
|
62
|
+
# Dumb method to get its already defined name, to avoid some precocious
|
63
|
+
# naming
|
64
|
+
def get_name
|
65
|
+
@name
|
66
|
+
end
|
67
|
+
|
68
|
+
# The idea is to put together everything that has to be done after you've
|
69
|
+
# initialized the proper attributes.
|
70
|
+
def process
|
71
|
+
download_and_decompress
|
72
|
+
install
|
73
|
+
end
|
74
|
+
|
32
75
|
# Uses the url provided to download the file.
|
33
76
|
# Checks the options first to see if it shouldn't be done.
|
34
77
|
def download_and_decompress
|
@@ -55,12 +98,18 @@ module Geoffrey
|
|
55
98
|
FileUtils.mkdir_p dir
|
56
99
|
rescue Exception => e
|
57
100
|
echo "Can't find file #{@url}"
|
101
|
+
debug "raised an exception #{e}"
|
102
|
+
|
58
103
|
raise NotFoundError
|
59
104
|
end
|
60
105
|
|
61
106
|
decompress
|
62
107
|
end
|
63
108
|
|
109
|
+
def fits?(pattern)
|
110
|
+
description.to_s.downcase.match(pattern) || name.to_s.downcase.match(pattern)
|
111
|
+
end
|
112
|
+
|
64
113
|
# Does the actual installing of the package
|
65
114
|
# For .pkg files it executes installer.
|
66
115
|
# For .app files it just moves it to /Applications
|
@@ -155,7 +204,7 @@ module Geoffrey
|
|
155
204
|
def get_filename
|
156
205
|
@filename = @options[:filename]
|
157
206
|
@filename ||= begin
|
158
|
-
|
207
|
+
extract_filename(@url) if @url && @url != ""
|
159
208
|
end
|
160
209
|
end
|
161
210
|
|
@@ -187,39 +236,36 @@ module Geoffrey
|
|
187
236
|
raise DecompressionError unless $?.success?
|
188
237
|
|
189
238
|
debug "Files after decompression:"
|
190
|
-
debug `ls -la #{dir}`
|
239
|
+
debug `ls -la #{dir.escape_path}`
|
191
240
|
end
|
192
241
|
|
193
242
|
# Mount the dmg file, copy contents to tmpdir, unmount, remove dmg
|
194
|
-
#--
|
195
|
-
# TODO change system calls with FileUtils maybe?
|
196
243
|
def extract_from_dmg
|
197
|
-
|
198
|
-
|
244
|
+
FileUtils.mv file.path, "#{dir}.dmg"
|
245
|
+
|
246
|
+
str = execute("hdiutil attach #{dir.escape_path}.dmg 2> /dev/null", :verbose => true)
|
247
|
+
|
199
248
|
if $?.success?
|
200
249
|
info = str.split("\t")
|
201
250
|
|
202
|
-
dmg_dir =
|
251
|
+
dmg_dir = info.last.chomp
|
203
252
|
debug "the dmg has been mounted here: #{dmg_dir}"
|
204
253
|
|
205
254
|
device = info.first.strip.split("/").last
|
206
255
|
debug "the attached device is: #{device}"
|
207
256
|
|
208
257
|
debug "These are the files inside the dmg:"
|
209
|
-
debug `ls -la #{dmg_dir}`
|
258
|
+
debug `ls -la #{dmg_dir.escape_path}`
|
210
259
|
|
211
|
-
|
260
|
+
FileUtils.cp_r Dir.glob("#{dmg_dir}/**"), dir
|
212
261
|
|
213
262
|
debug "Now these in the target"
|
214
|
-
debug `ls -la #{dir}`
|
263
|
+
debug `ls -la #{dir.escape_path}.dmg`
|
215
264
|
|
216
265
|
execute("hdiutil detach #{device}")
|
217
|
-
|
266
|
+
FileUtils.rm_f "#{dir}.dmg"
|
218
267
|
end
|
219
268
|
end
|
220
269
|
|
221
|
-
def escape_whitespaces(path)
|
222
|
-
path.gsub(' ','\ ')
|
223
|
-
end
|
224
270
|
end
|
225
271
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'geoffrey/package'
|
5
|
+
require 'geoffrey/file_helper'
|
6
|
+
|
7
|
+
module Geoffrey
|
8
|
+
class Template
|
9
|
+
include Geoffrey::FileHelper
|
10
|
+
|
11
|
+
attr_accessor :package, :file
|
12
|
+
|
13
|
+
def initialize(file)
|
14
|
+
@file = file
|
15
|
+
@package = Geoffrey::Package.new
|
16
|
+
set_name_from_file
|
17
|
+
case File.extname(file)
|
18
|
+
when '.rb'
|
19
|
+
package.instance_eval open(file).read
|
20
|
+
when '.json'
|
21
|
+
load_attributes_from_json
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def set_name_from_file
|
28
|
+
package.guessed_name = remove_extension(extract_filename(file))
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_attributes_from_json
|
32
|
+
attribs = JSON(open(file).read)
|
33
|
+
["url","name","description","options"].each do |attr|
|
34
|
+
package.send(:"#{attr}", attribs[attr])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
data/lib/geoffrey/version.rb
CHANGED
data/spec/cli_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
require 'geoffrey/template'
|
3
4
|
require 'geoffrey/cli'
|
4
5
|
|
5
6
|
describe Geoffrey::CLI do
|
@@ -9,7 +10,7 @@ describe Geoffrey::CLI do
|
|
9
10
|
@app.stubs(:templates_dir).returns(File.dirname(__FILE__) + '/templates')
|
10
11
|
end
|
11
12
|
|
12
|
-
context 'list' do
|
13
|
+
context 'list command' do
|
13
14
|
|
14
15
|
it "prints a list of templates" do
|
15
16
|
output = capturing_output { @app.list }
|
@@ -31,7 +32,24 @@ describe Geoffrey::CLI do
|
|
31
32
|
|
32
33
|
end
|
33
34
|
|
34
|
-
context
|
35
|
+
context "search command" do
|
36
|
+
|
37
|
+
# Since we can search by description, it also tests all templates are
|
38
|
+
# loaded and eval'd.
|
39
|
+
it "allows searching by description" do
|
40
|
+
output = capturing_output { @app.search("awesome") }
|
41
|
+
output.should include("growl")
|
42
|
+
output.should include("This package should do awesome stuff")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "prints an error if no pattern fit" do
|
46
|
+
output = capturing_output { @app.search("gorringoringngnng") }
|
47
|
+
output.should include("No templates available")
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
context "install command" do
|
35
53
|
|
36
54
|
# Can't really test something's installed for real, so we just expect
|
37
55
|
# that it will call the proper methods on the Geoffrey::Package object.
|
data/spec/package_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'geoffrey/package'
|
|
4
4
|
describe Geoffrey::Package do
|
5
5
|
|
6
6
|
it "receives different options" do
|
7
|
-
[:url, :name, :description
|
7
|
+
[:url, :name, :description].each do |opt|
|
8
8
|
package = Geoffrey::Package.new
|
9
9
|
package.send(opt, 'foo')
|
10
10
|
package.send(opt).should == 'foo'
|
@@ -23,6 +23,36 @@ describe Geoffrey::Package do
|
|
23
23
|
package.options.should == {:yes => "no"}
|
24
24
|
end
|
25
25
|
|
26
|
+
context "smart naming" do
|
27
|
+
|
28
|
+
it "gets its name from its url if no name specified" do
|
29
|
+
package = Geoffrey::Package.new
|
30
|
+
package.url "http://www.co.co/adium.zip"
|
31
|
+
package.name.should == "adium"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "gets its name from its name :)" do
|
35
|
+
package = Geoffrey::Package.new
|
36
|
+
package.name "adium"
|
37
|
+
package.name.should == "adium"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context "knows if a package matches a pattern" do
|
43
|
+
|
44
|
+
it "really does" do
|
45
|
+
package = Geoffrey::Package.new
|
46
|
+
package.name "mrsimo"
|
47
|
+
package.description "He is a really nice person"
|
48
|
+
package.fits?("mrsimo").should be_true
|
49
|
+
package.fits?("really").should be_true
|
50
|
+
package.fits?("konoha").should be_false
|
51
|
+
package.fits?(/rea..y/).should be_true
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
26
56
|
context "package installation" do
|
27
57
|
|
28
58
|
# No idea how to test this
|
@@ -119,8 +149,6 @@ describe Geoffrey::Package do
|
|
119
149
|
|
120
150
|
# Testing with a dmg that has a whitespace as a name because testing dmg's
|
121
151
|
# is too slow, so we do it all in one.
|
122
|
-
#--
|
123
|
-
# TODO this test fails :( but it does work in real examples.
|
124
152
|
it "also supports .dmg files" do
|
125
153
|
package = Geoffrey::Package.new
|
126
154
|
package.url(File.dirname(__FILE__) + "/static/test 1.dmg")
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'geoffrey/template'
|
3
|
+
require 'geoffrey/package'
|
4
|
+
|
5
|
+
describe Geoffrey::Template do
|
6
|
+
|
7
|
+
it "knows how to load .rb files" do
|
8
|
+
template = Geoffrey::Template.new(File.dirname(__FILE__) + "/static/template1.rb")
|
9
|
+
template.package.should be_an_instance_of(Geoffrey::Package)
|
10
|
+
template.package.url.should == "foo.com"
|
11
|
+
template.package.description.should == "bar"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "knows how to load .json files" do
|
15
|
+
template = Geoffrey::Template.new(File.dirname(__FILE__) + "/static/template1.json")
|
16
|
+
template.package.should be_an_instance_of(Geoffrey::Package)
|
17
|
+
template.package.url.should == "foo.com"
|
18
|
+
template.package.description.should == "bar"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "smartly changes its name from the file if no name specified inside" do
|
22
|
+
template1 = Geoffrey::Template.new(File.dirname(__FILE__) + "/static/template1.json")
|
23
|
+
template2 = Geoffrey::Template.new(File.dirname(__FILE__) + "/static/template2.json")
|
24
|
+
template1.package.name.should == "template1"
|
25
|
+
template2.package.name.should == "fixed_name"
|
26
|
+
end
|
27
|
+
|
28
|
+
context "packages" do
|
29
|
+
|
30
|
+
it "symbolizes keys of the options parameter" do
|
31
|
+
template = Geoffrey::Template.new(File.dirname(__FILE__) + "/static/template2.json")
|
32
|
+
template.package.options.should == {:sudo => true}
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/spec/templates/simbl.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
url "http://other.url"
|
data/templates/burn.json
ADDED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Albert Llop
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-09-
|
17
|
+
date: 2010-09-14 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -165,9 +165,11 @@ files:
|
|
165
165
|
- geoffrey.gemspec
|
166
166
|
- lib/geoffrey.rb
|
167
167
|
- lib/geoffrey/cli.rb
|
168
|
+
- lib/geoffrey/file_helper.rb
|
168
169
|
- lib/geoffrey/package.rb
|
169
170
|
- lib/geoffrey/plist.rb
|
170
171
|
- lib/geoffrey/reporter.rb
|
172
|
+
- lib/geoffrey/template.rb
|
171
173
|
- lib/geoffrey/version.rb
|
172
174
|
- spec/cli_spec.rb
|
173
175
|
- spec/geoffrey_spec.rb
|
@@ -177,6 +179,9 @@ files:
|
|
177
179
|
- spec/spec.opts
|
178
180
|
- spec/spec_helper.rb
|
179
181
|
- spec/static/example.plist
|
182
|
+
- spec/static/template1.json
|
183
|
+
- spec/static/template1.rb
|
184
|
+
- spec/static/template2.json
|
180
185
|
- spec/static/test 1.dmg
|
181
186
|
- spec/static/test.error.dmg
|
182
187
|
- spec/static/test.error.gz
|
@@ -189,9 +194,11 @@ files:
|
|
189
194
|
- spec/static/test.txt.gz.123
|
190
195
|
- spec/static/test.txt.zip
|
191
196
|
- spec/support/helpers.rb
|
197
|
+
- spec/template_spec.rb
|
192
198
|
- spec/templates/growl.rb
|
193
199
|
- spec/templates/simbl.rb
|
194
200
|
- templates/adium.rb
|
201
|
+
- templates/burn.json
|
195
202
|
- templates/growl.rb
|
196
203
|
- templates/skype.rb
|
197
204
|
- templates/unrarx.rb
|