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.
@@ -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