geoffrey 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- geoffrey (0.1.0)
4
+ geoffrey (0.1.1)
5
5
  plist4r
6
6
  progressbar
7
7
  thor
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
 
@@ -3,6 +3,7 @@
3
3
 
4
4
  require 'geoffrey'
5
5
  require 'geoffrey/package'
6
+ require 'geoffrey/template'
6
7
  require 'geoffrey/cli'
7
8
 
8
9
  Geoffrey::CLI.start
@@ -49,8 +49,7 @@ module Geoffrey
49
49
  def package(&block)
50
50
  package = Package.new
51
51
  package.instance_eval &block
52
- package.download_and_decompress
53
- package.install
52
+ package.process
54
53
  end
55
54
 
56
55
  # Help you configure an application editing its +.plist+ file.
@@ -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::Package.new
22
+ @package = Geoffrey::Template.new(file).package
23
23
  @package.verbose(true) if options[:verbose]
24
- @package.instance_eval File.read(file)
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
@@ -0,0 +1,14 @@
1
+ module Geoffrey
2
+ module FileHelper
3
+
4
+ def extract_filename(url)
5
+ url.split("/").last
6
+ File.basename(url).split("?").first
7
+ end
8
+
9
+ def remove_extension(name)
10
+ name.split(".").first
11
+ end
12
+
13
+ end
14
+ end
@@ -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, :dir, :file
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,:name,:description,:options].each do |attrib|
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
- escape_whitespaces(File.basename(@url).split("?").first) if @url && @url != ""
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
- execute("mv #{file.path} #{dir}.dmg")
198
- str = execute("hdiutil attach #{dir}.dmg 2> /dev/null", :verbose => true)
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 = escape_whitespaces(info.last.chomp)
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
- execute("cp -r #{escape_whitespaces(dmg_dir)}/** #{dir}")
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
- execute("rm -f #{dir}.dmg")
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
@@ -1,3 +1,3 @@
1
1
  module Geoffrey
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -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 'install' do
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.
@@ -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, :options].each do |opt|
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,4 @@
1
+ {
2
+ "url" : "foo.com",
3
+ "description" : "bar"
4
+ }
@@ -0,0 +1,2 @@
1
+ url "foo.com"
2
+ description "bar"
@@ -0,0 +1,9 @@
1
+ {
2
+ "name" : "fixed_name",
3
+ "url" : "foo.com",
4
+ "description" : "bar",
5
+ "options" : {
6
+ "sudo" : true
7
+ }
8
+ }
9
+
@@ -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
@@ -0,0 +1 @@
1
+ url "http://other.url"
@@ -0,0 +1,4 @@
1
+ {
2
+ "url" : "http://downloads.sourceforge.net/project/burn-osx/Burn/2.4.1/Burn241u.zip?r=http%3A%2F%2Fburn-osx.sourceforge.net%2FPages%2FEnglish%2Fhome.html&ts=1284476617&use_mirror=ovh",
3
+ "description" : "Simple but advanced burning for Mac OS X"
4
+ }
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
9
- version: 0.1.0
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-10 00:00:00 +02:00
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