geoffrey 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :gemcutter
2
+
3
+ # Specify your gem's dependencies in geoffrey.gemspec
4
+ gemspec
@@ -0,0 +1,33 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ geoffrey (0.0.0)
5
+ plist4r
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ awesome_print (0.2.1)
11
+ haml (3.0.17)
12
+ libxml-ruby (1.1.4)
13
+ libxml4r (0.2.6)
14
+ libxml-ruby (>= 1.1.3)
15
+ mocha (0.9.8)
16
+ rake
17
+ plist4r (1.1.1)
18
+ haml
19
+ libxml-ruby
20
+ libxml4r
21
+ rake (0.8.7)
22
+ rspec (1.3.0)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ awesome_print
29
+ bundler (~> 1.0.0.rc.5)
30
+ geoffrey!
31
+ mocha (= 0.9.8)
32
+ plist4r
33
+ rspec (= 1.3.0)
@@ -0,0 +1,116 @@
1
+ geoffrey
2
+ ========
3
+
4
+ ## ALERT!
5
+
6
+ This is very early alpha code, use with precaution. It's a spinoff of myself willing to
7
+ improve my [dotfiles project](http://github.com/albertllop/dotfiles) a step further. All
8
+ code examples in this README come from it.
9
+
10
+ ## Introduction
11
+
12
+ Geoffrey's your little helper, that who just wants to makes your life easier.
13
+
14
+ It aims to help you create little scripts to setup your OSX the way you like.
15
+ If, like me, you use different computers at work, home, or even when travelling,
16
+ you'll know it's a pain in the ass to keep everything up to date.
17
+
18
+ Inspired in the numerous dotfiles projects, specially
19
+ [holman's](http://github.com/holman/dotfiles),
20
+ the intention is to bring customization to a bigger extend.
21
+
22
+ ## Installation
23
+
24
+ $ [sudo] gem install geoffrey
25
+
26
+ Geoffrey's Talents
27
+ ==================
28
+
29
+ Geoffrey has many talents, and thus you'll find he can help you in one of these areas:
30
+
31
+ ## Packages
32
+
33
+ If you ever used [Ciarán Walsh's](http://ciaranwal.sh) SIMBL plugins, you'll remember
34
+ what a pain it is to install them every time. Now you can do so with the next piece of code:
35
+
36
+ require 'geoffrey'
37
+ Geoffrey.package do
38
+ url 'http://www.culater.net/dl/files/SIMBL-0.9.7a.zip'
39
+ options :sudo => true, :unless => Proc.new{ File.exists?("/Library/LaunchAgents/net.culater.SIMBL.Agent.plist") }
40
+ end
41
+
42
+ Geoffrey will take care of downloading the zip file, and install whatever .pkg
43
+ file is in the zip. The possible options are:
44
+
45
+ * `:sudo` => in case it needs to be executed as sudo to install (it does if the installer would ever ask for your password)
46
+ * `:unless` => in order to make running this idempotent.
47
+ * `:file` => specify which of the files contained in the zip has to be installed. If it's not specified it uses the first .pkg it finds.
48
+
49
+ With that you'll have SIMBL installed and working. Now suppose you want to install a bundle.
50
+ You'd have to download a file, and move it to a directory. Geoffrey can help you a little,
51
+ basically downloading and uncompressing the zip, and you just have to define the install
52
+ method.
53
+
54
+ require 'geoffrey'
55
+ Geoffrey.package do
56
+ url "http://github.com/dabeeeenster/terminaltabswitching/raw/master/TerminalTabSwitching.bundle.zip"
57
+ options :file => "TerminalTabSwitching.bundle"
58
+
59
+ def install
60
+ plugins_dir = "#{ENV["HOME"]}/Library/Application Support/SIMBL/Plugins"
61
+ FileUtils.mkdir_p plugins_dir
62
+ FileUtils.mv file_to_install, plugins_dir, :force => true
63
+ end
64
+
65
+ end
66
+
67
+ `file_to_install` is provided by geoffrey poiting to the automatically downloaded/uncompressed file.
68
+
69
+ ## Application Configuration
70
+
71
+ Everything in OSX seems to work around `.plist` files. This takes a little bit of work to figure out,
72
+ but once you do, you can have your favourite apps the way you like. This is my script to get Terminal.app
73
+ up and running with Pro scheme, Menlo Font 14pt, and a size 520x100.
74
+
75
+ require 'geoffrey'
76
+
77
+ Geoffrey.plist do
78
+ file :terminal
79
+ affects "/Applications/Utilities/Terminal.app"
80
+
81
+ options["Default Window Settings"] = "Pro"
82
+ options["Startup Window Settings"] = "Pro"
83
+ options["HasMigratedDefaults"] = true
84
+ options["Window Settings"]["Pro"]["Font"] = "bplist00\xD4\x01\x02\x03\x04\x05\x06\x18\x19X$versionX$objectsY$archiverT$top\x12\x00\x01\x86\xA0\xA4\a\b\x11\x12U$null\xD4\t\n\v\f\r\x0E\x0F\x10V$classVNSNameVNSSizeXNSfFlags\x80\x03\x80\x02\#@,\x00\x00\x00\x00\x00\x00\x10\x10]Menlo-Regular\xD2\x13\x14\x15\x16Z$classnameX$classesVNSFont\xA2\x15\x17XNSObject_\x10\x0FNSKeyedArchiver\xD1\x1A\eTroot\x80\x01\b\x11\x1A#-27<BKRY`ikmvx\x86\x8B\x96\x9F\xA6\xA9\xB2\xC4\xC7\xCC\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x1C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xCE"
85
+ options["Window Settings"]["Pro"]["Font"].blob = true
86
+ options["Window Settings"]["Pro"]["columnCount"] = 520
87
+ options["Window Settings"]["Pro"]["rowCount"] = 100
88
+ end
89
+
90
+ * `file` => Geoffrey knows of a few files in your system you can specify with symbols. If you want to work with a different one, just write the full path.
91
+ * `affects` => When you close Terminal.app, it'll dump its otions into the plist. So you have to stop it, change the plist file, then reopen it. Geoffrey does this automatically if you tell him what must be rebooted.
92
+ * `options` => Its the plist has per se. Using the fantastic [plist4r](http://github.com/dreamcat4/plist4r) gem, you can modify it.
93
+
94
+ You might have seen something peculiar:
95
+
96
+ options["Window Settings"]["Pro"]["Font"].blob = true
97
+
98
+ Some values in plist files are of type "Data", which is just binary stuff. Plist4r handles
99
+ these as strings with a special flag.
100
+
101
+ The best way to know what to put in every value, is to just go to the file and take a
102
+ look. They all tend to make sense. For data values, however, you might have more work. The
103
+ way I do it is opening the file with Plist4r, and reading the value:
104
+
105
+ require 'plist4r'
106
+ plist = Plist4r.open("the/file.plist")
107
+ plist["whatever"]["option"] # => copy whatever it returns
108
+
109
+ Just make sure that when you set it in your geoffrey you put the flag blog true. Otherwise you might see some really weird system errors.
110
+
111
+ ## A few words
112
+
113
+ This is work done in my free hours, it's not yet finished. The code is dirty and mainly undocumented. It all started on #whyday,
114
+ but I'm so lazy that I've needed a lot of time to do just this.
115
+
116
+ Thanks!
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ desc "Execute specs"
5
+ task :spec do
6
+ puts `bundle exec rspec spec`
7
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
3
+ require 'geoffrey/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "geoffrey"
7
+ s.version = Geoffrey::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Albert Llop"]
10
+ s.email = ["mrsimo@gmail.com"]
11
+ s.summary = "Geoffrey is a little helper to aid in the installation of packages and configuration of various Mac OSX applications."
12
+ s.description = File.read(File.dirname(__FILE__) + "/README.md")
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+ s.rubyforge_project = "geoffrey"
16
+
17
+ s.add_development_dependency "bundler", "~> 1.0.0.rc.5"
18
+ s.add_development_dependency "rspec", "~> 1.3.0"
19
+ s.add_development_dependency "mocha", "~> 0.9.8"
20
+
21
+ s.add_dependency 'plist4r'
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.executables = `git ls-files`.split("\n").select{|f| f =~ /^bin/}
25
+ s.require_path = 'lib'
26
+ end
@@ -0,0 +1,23 @@
1
+ require 'geoffrey/package'
2
+ require 'geoffrey/plist'
3
+
4
+ module Geoffrey
5
+
6
+ class << self
7
+
8
+ def package(&block)
9
+ package = Package.new
10
+ package.instance_eval &block
11
+ package.download_and_decompress
12
+ package.install
13
+ end
14
+
15
+ def plist(&block)
16
+ plist = Plist.new
17
+ plist.instance_eval &block
18
+ plist.save
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,108 @@
1
+ require 'tmpdir'
2
+ require 'tempfile'
3
+ require 'open-uri'
4
+ require 'fileutils'
5
+
6
+ module Geoffrey
7
+ class Package
8
+ attr_accessor :url, :options, :format, :filename, :dir
9
+
10
+ def initialize
11
+ @options = {}
12
+ end
13
+
14
+ def url(val = nil)
15
+ @url = val if val
16
+ @url
17
+ end
18
+
19
+ def options(val = nil)
20
+ @options = val if val
21
+ @options
22
+ end
23
+
24
+ def download_and_decompress
25
+ return nil if shouldnt_install
26
+
27
+ @filename = @url.split("/").last
28
+ unless @url.nil?
29
+ get_format
30
+
31
+ file = Tempfile.new("geoffrey")
32
+ file.write open(@url).read
33
+ file.close
34
+
35
+ @dir = "#{Dir.tmpdir}/#{filename}"
36
+ FileUtils.rm_rf @dir if File.exist?(@dir)
37
+ FileUtils.mkdir_p @dir
38
+
39
+ decompress file, @dir
40
+
41
+ @dir
42
+ end
43
+ end
44
+
45
+ def install
46
+ return nil if shouldnt_install
47
+
48
+ command = case File.extname file_to_install
49
+ when ".pkg"
50
+ "installer -pkg #{file_to_install} -target /"
51
+ end
52
+ execute command
53
+ end
54
+
55
+ private
56
+
57
+ def shouldnt_install
58
+ @options[:unless] && @options[:unless].respond_to?(:call) && @options[:unless].call
59
+ end
60
+
61
+ def execute(command, options = {})
62
+ options = @options.merge(options)
63
+ command = "sudo #{command}" if options[:sudo]
64
+ puts "Executing: #{command}" if $verbose
65
+ system command
66
+ end
67
+
68
+ # If it was specified through options, then get that, otherwise
69
+ # get the first file with .pkg extension
70
+ def file_to_install
71
+ if @options[:file]
72
+ "#{@dir}/#{@options[:file]}"
73
+ else
74
+ files = Dir.glob("#{@dir}/**/*.pkg")
75
+ files.first
76
+ end
77
+ end
78
+
79
+ def get_format
80
+ @format = case File.extname @url
81
+ when '.zip' then :zip
82
+ when '.tar' then :tar
83
+ when '.tgz' then :tgz
84
+ when '.gz'
85
+ if @filename =~ /\.tar\.gz/
86
+ :tgz
87
+ else
88
+ :gz
89
+ end
90
+ end
91
+ end
92
+
93
+ def decompress(file,target)
94
+ command = case @format
95
+ when :zip
96
+ "unzip -o #{file.path} -d #{target} 1> /dev/null"
97
+ when :tar
98
+ "tar xf #{file.path} -C #{target}"
99
+ when :tgz
100
+ "tar xzf #{file.path} -C #{target}"
101
+ when :gz
102
+ "cp #{file.path} #{target}/#{filename}.gz; gunzip #{target}/*"
103
+ end
104
+ execute command, :sudo => false
105
+ end
106
+
107
+ end
108
+ end
@@ -0,0 +1,56 @@
1
+ require 'plist4r'
2
+
3
+ module Geoffrey
4
+ class Plist
5
+
6
+ FILES = {
7
+ :textmate => "#{ENV["HOME"]}/Library/Preferences/com.macromates.textmate.plist",
8
+ :terminal => "#{ENV["HOME"]}/Library/Preferences/com.apple.Terminal.plist"
9
+ }
10
+
11
+ attr_accessor :data, :file, :process
12
+
13
+ def file(file = nil)
14
+ if file
15
+ file = FILES[file] if Symbol === file
16
+ raise "File #{file} not found" if file.nil? || !File.exists?(file)
17
+ @data = Plist4r.open(file)
18
+ @file = file
19
+ end
20
+ @file
21
+ end
22
+
23
+ def affects(value)
24
+ @process = value
25
+ end
26
+
27
+ def options
28
+ data
29
+ end
30
+
31
+ def [](key)
32
+ data[key]
33
+ end
34
+
35
+ def []=(key,value)
36
+ data[key] = value
37
+ end
38
+
39
+ def save
40
+ kill
41
+ data.save
42
+ open
43
+ end
44
+
45
+ private
46
+
47
+ def kill
48
+ system "killall '#{@process}'" unless @process.nil?
49
+ end
50
+
51
+ def open
52
+ system "open '#{@process}'" unless @process.nil?
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,30 @@
1
+ module Geoffrey
2
+ class Template
3
+
4
+ attr_accessor :title, :description
5
+
6
+ def self.inherited(subclass)
7
+ @@subclasses ||= []
8
+ @@subclasses << subclass
9
+ end
10
+
11
+ class << self
12
+ def self.attr_rw(*attrs)
13
+ attrs.each do |attr|
14
+ class_eval %Q{
15
+ def #{attr}(val=nil)
16
+ val.nil? ? @#{attr} : @#{attr} = val
17
+ end
18
+ }
19
+ end
20
+ end
21
+
22
+ attr_rw :title, :description
23
+
24
+ def all
25
+ @@subclasses
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module Geoffrey
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'geoffrey/package'
3
+
4
+ describe Geoffrey::Package do
5
+ it "allows for the url to be specified" do
6
+ package = Geoffrey::Package.new
7
+ package.url 'http://localhost/crappy.zip'
8
+ package.url.should == 'http://localhost/crappy.zip'
9
+ end
10
+
11
+ it "allows for some options to be specified" do
12
+ package = Geoffrey::Package.new
13
+ package.options :yes => "no"
14
+ package.options.should == {:yes => "no"}
15
+ end
16
+
17
+ context "package installation" do
18
+
19
+ it "installs basic package stuff" do
20
+
21
+ end
22
+
23
+ it "doesnt install the thing if a :unless option is provided" do
24
+
25
+ end
26
+
27
+ it "inverse if passed a :if option" do
28
+
29
+ end
30
+
31
+ end
32
+
33
+ context 'package downloading/unzipping' do
34
+ # Things should be uncompressed into a temporary folder, and the
35
+ # method should return where it is.
36
+
37
+ it "smartly unzips the file if it's a zip" do
38
+ package = Geoffrey::Package.new
39
+ package.url(File.dirname(__FILE__) + "/static/test.txt.zip")
40
+ dir = package.download_and_decompress
41
+ files = Dir.glob("#{dir}/*")
42
+ files.size.should == 1
43
+ files.last.split("/").last.should == "test.txt"
44
+ end
45
+
46
+ it "smartly untars the tar if it's a tar" do
47
+ package = Geoffrey::Package.new
48
+ package.url(File.dirname(__FILE__) + "/static/test.tar.gz")
49
+ dir = package.download_and_decompress
50
+ files = Dir.glob("#{dir}/*")
51
+ files.size.should == 1
52
+ files.last.split("/").last.should == "test.txt"
53
+ end
54
+
55
+ # it "smartly ungzips if its a gzip" do
56
+ # package = Geoffrey::Package.new
57
+ # package.url(File.dirname(__FILE__) + "/static/test.txt.gz")
58
+ # dir = package.download_and_decompress
59
+ # files = Dir.glob("#{dir}/*")
60
+ # files.size.should == 1
61
+ # files.last.split("/").last.should == "test.txt"
62
+ # end
63
+ end
64
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+ require 'geoffrey/plist'
3
+
4
+ describe Geoffrey::Plist do
5
+
6
+ before(:each) do
7
+ # To be able to play with the file we copy it every time
8
+ @plist_file = Tempfile.new 'plist_spec'
9
+ @plist_file.write File.read(File.dirname(__FILE__) + "/static/example.plist")
10
+ @plist_file.close
11
+ end
12
+
13
+ it "raises an error if the file passed doesn't exist" do
14
+ lambda{ Geoffrey::Plist.new.file("it/surely/doesnt/exist") }.should raise_error
15
+ end
16
+
17
+ it "also accepts symbol values for already known values" do
18
+ plist = Geoffrey::Plist.new
19
+ plist.file :terminal
20
+ plist.file.should include("com.apple.Terminal.plist")
21
+ end
22
+
23
+ it "parses correct plist items" do
24
+ plist = Geoffrey::Plist.new
25
+ plist.file(@plist_file.path)
26
+ plist.data.class.should == Plist4r::Plist
27
+ end
28
+
29
+ it "knows that it has to close some appication before applying changes" do
30
+ plist = Geoffrey::Plist.new
31
+ plist.file(@plist_file.path)
32
+ plist.affects "/some/process"
33
+
34
+ # Since I don't know how to test this without starting and shutting down processes
35
+ # I'll just suppose that some internal functions are called
36
+ plist.expects(:system).twice
37
+ plist.save
38
+ end
39
+
40
+ context "plist modification" do
41
+ it "allows adding new plist item" do
42
+ plist = Geoffrey::Plist.new
43
+ plist.file(@plist_file.path)
44
+ plist['surely_a_new_key'] = "Hello"
45
+ plist.save
46
+
47
+ plist = Geoffrey::Plist.new
48
+ plist.file(@plist_file.path)
49
+ plist['surely_a_new_key'].should == "Hello"
50
+ end
51
+
52
+ it "allows modifying existing keys" do
53
+ plist = Geoffrey::Plist.new
54
+ plist.file(@plist_file.path)
55
+ existing_key = plist.data.keys.first
56
+ plist[existing_key] = "New value"
57
+ plist.save
58
+
59
+ plist = Geoffrey::Plist.new
60
+ plist.file(@plist_file.path)
61
+ plist[existing_key].should == "New value"
62
+ end
63
+
64
+ it "can also be accessed through options" do
65
+ plist = Geoffrey::Plist.new
66
+ plist.file(@plist_file.path)
67
+ plist.options['surely_a_new_key'] = "Hello"
68
+ plist.save
69
+
70
+ plist = Geoffrey::Plist.new
71
+ plist.file(@plist_file.path)
72
+ plist.options['surely_a_new_key'].should == "Hello"
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler.setup(:default,:test)
3
+ require 'geoffrey'
4
+ require 'tempfile'
5
+
6
+ Spec::Runner.configure do |config|
7
+ config.mock_with :mocha
8
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'geoffrey/template'
3
+
4
+ class SimpleTest < Geoffrey::Template
5
+ title "Simple template test"
6
+ description "It does really nice stuff"
7
+ end
8
+
9
+ class ExtraTest < Geoffrey::Template
10
+ title "A more advanced test"
11
+ description "It does even nicer stuff"
12
+ end
13
+
14
+ describe Geoffrey::Template do
15
+
16
+ it "globally knows of all the described templates" do
17
+ Geoffrey::Template.all.should == [SimpleTest, ExtraTest]
18
+ end
19
+
20
+ it "provides a basic way to describe actions" do
21
+ SimpleTest.title.should == "Simple template test"
22
+ ExtraTest.title.should == "A more advanced test"
23
+ SimpleTest.description.should == "It does really nice stuff"
24
+ ExtraTest.description.should == "It does even nicer stuff"
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geoffrey
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Albert Llop
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-08-28 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bundler
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 0
31
+ - 0
32
+ - rc
33
+ - 5
34
+ version: 1.0.0.rc.5
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ segments:
46
+ - 1
47
+ - 3
48
+ - 0
49
+ version: 1.3.0
50
+ type: :development
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: mocha
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ segments:
61
+ - 0
62
+ - 9
63
+ - 8
64
+ version: 0.9.8
65
+ type: :development
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: plist4r
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ type: :runtime
79
+ version_requirements: *id004
80
+ description: "geoffrey\n\
81
+ ========\n\n\
82
+ ## ALERT!\n\n\
83
+ This is very early alpha code, use with precaution. It's a spinoff of myself willing to\n\
84
+ improve my [dotfiles project](http://github.com/albertllop/dotfiles) a step further. All\n\
85
+ code examples in this README come from it.\n\n\
86
+ ## Introduction\n\n\
87
+ Geoffrey's your little helper, that who just wants to makes your life easier.\n\n\
88
+ It aims to help you create little scripts to setup your OSX the way you like.\n\
89
+ If, like me, you use different computers at work, home, or even when travelling,\n\
90
+ you'll know it's a pain in the ass to keep everything up to date.\n\n\
91
+ Inspired in the numerous dotfiles projects, specially\n\
92
+ [holman's](http://github.com/holman/dotfiles),\n\
93
+ the intention is to bring customization to a bigger extend.\n\n\
94
+ ## Installation\n\n $ [sudo] gem install geoffrey\n\n\
95
+ Geoffrey's Talents\n\
96
+ ==================\n\n\
97
+ Geoffrey has many talents, and thus you'll find he can help you in one of these areas:\n\n\
98
+ ## Packages\n\n\
99
+ If you ever used [Ciar\xC3\xA1n Walsh's](http://ciaranwal.sh) SIMBL plugins, you'll remember\n\
100
+ what a pain it is to install them every time. Now you can do so with the next piece of code:\n\n require 'geoffrey'\n Geoffrey.package do\n url 'http://www.culater.net/dl/files/SIMBL-0.9.7a.zip'\n options :sudo => true, :unless => Proc.new{ File.exists?(\"/Library/LaunchAgents/net.culater.SIMBL.Agent.plist\") }\n end\n\n\
101
+ Geoffrey will take care of downloading the zip file, and install whatever .pkg\n\
102
+ file is in the zip. The possible options are:\n\n\
103
+ * `:sudo` => in case it needs to be executed as sudo to install (it does if the installer would ever ask for your password)\n\
104
+ * `:unless` => in order to make running this idempotent.\n\
105
+ * `:file` => specify which of the files contained in the zip has to be installed. If it's not specified it uses the first .pkg it finds.\n\n\
106
+ With that you'll have SIMBL installed and working. Now suppose you want to install a bundle.\n\
107
+ You'd have to download a file, and move it to a directory. Geoffrey can help you a little,\n\
108
+ basically downloading and uncompressing the zip, and you just have to define the install\n\
109
+ method.\n\n require 'geoffrey'\n Geoffrey.package do\n url \"http://github.com/dabeeeenster/terminaltabswitching/raw/master/TerminalTabSwitching.bundle.zip\"\n options :file => \"TerminalTabSwitching.bundle\"\n\n def install\n plugins_dir = \"#{ENV[\"HOME\"]}/Library/Application Support/SIMBL/Plugins\"\n FileUtils.mkdir_p plugins_dir\n FileUtils.mv file_to_install, plugins_dir, :force => true\n end\n\n end\n\n\
110
+ `file_to_install` is provided by geoffrey poiting to the automatically downloaded/uncompressed file.\n\n\
111
+ ## Application Configuration\n\n\
112
+ Everything in OSX seems to work around `.plist` files. This takes a little bit of work to figure out,\n\
113
+ but once you do, you can have your favourite apps the way you like. This is my script to get Terminal.app\n\
114
+ up and running with Pro scheme, Menlo Font 14pt, and a size 520x100.\n\n require 'geoffrey'\n\n Geoffrey.plist do\n file :terminal\n affects \"/Applications/Utilities/Terminal.app\"\n\n options[\"Default Window Settings\"] = \"Pro\"\n options[\"Startup Window Settings\"] = \"Pro\"\n options[\"HasMigratedDefaults\"] = true\n options[\"Window Settings\"][\"Pro\"][\"Font\"] = \"bplist00\\xD4\\x01\\x02\\x03\\x04\\x05\\x06\\x18\\x19X$versionX$objectsY$archiverT$top\\x12\\x00\\x01\\x86\\xA0\\xA4\\a\\b\\x11\\x12U$null\\xD4\\t\\n\\v\\f\\r\\x0E\\x0F\\x10V$classVNSNameVNSSizeXNSfFlags\\x80\\x03\\x80\\x02\\#@,\\x00\\x00\\x00\\x00\\x00\\x00\\x10\\x10]Menlo-Regular\\xD2\\x13\\x14\\x15\\x16Z$classnameX$classesVNSFont\\xA2\\x15\\x17XNSObject_\\x10\\x0FNSKeyedArchiver\\xD1\\x1A\\eTroot\\x80\\x01\\b\\x11\\x1A#-27<BKRY`ikmvx\\x86\\x8B\\x96\\x9F\\xA6\\xA9\\xB2\\xC4\\xC7\\xCC\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x1C\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xCE\"\n options[\"Window Settings\"][\"Pro\"][\"Font\"].blob = true\n options[\"Window Settings\"][\"Pro\"][\"columnCount\"] = 520\n options[\"Window Settings\"][\"Pro\"][\"rowCount\"] = 100\n end\n\n\
115
+ * `file` => Geoffrey knows of a few files in your system you can specify with symbols. If you want to work with a different one, just write the full path.\n\
116
+ * `affects` => When you close Terminal.app, it'll dump its otions into the plist. So you have to stop it, change the plist file, then reopen it. Geoffrey does this automatically if you tell him what must be rebooted.\n\
117
+ * `options` => Its the plist has per se. Using the fantastic [plist4r](http://github.com/dreamcat4/plist4r) gem, you can modify it.\n\n\
118
+ You might have seen something peculiar:\n\n options[\"Window Settings\"][\"Pro\"][\"Font\"].blob = true\n\n\
119
+ Some values in plist files are of type \"Data\", which is just binary stuff. Plist4r handles\n\
120
+ these as strings with a special flag.\n\n\
121
+ The best way to know what to put in every value, is to just go to the file and take a\n\
122
+ look. They all tend to make sense. For data values, however, you might have more work. The\n\
123
+ way I do it is opening the file with Plist4r, and reading the value:\n\n require 'plist4r'\n plist = Plist4r.open(\"the/file.plist\")\n plist[\"whatever\"][\"option\"] # => copy whatever it returns\n\n\
124
+ Just make sure that when you set it in your geoffrey you put the flag blog true. Otherwise you might see some really weird system errors.\n\n\
125
+ ## A few words\n\n\
126
+ This is work done in my free hours, it's not yet finished. The code is dirty and mainly undocumented. It all started on #whyday,\n\
127
+ but I'm so lazy that I've needed a lot of time to do just this. \n\n\
128
+ Thanks!\n"
129
+ email:
130
+ - mrsimo@gmail.com
131
+ executables: []
132
+
133
+ extensions: []
134
+
135
+ extra_rdoc_files: []
136
+
137
+ files:
138
+ - .gitignore
139
+ - Gemfile
140
+ - Gemfile.lock
141
+ - README.md
142
+ - Rakefile
143
+ - geoffrey.gemspec
144
+ - lib/geoffrey.rb
145
+ - lib/geoffrey/package.rb
146
+ - lib/geoffrey/plist.rb
147
+ - lib/geoffrey/template.rb
148
+ - lib/geoffrey/version.rb
149
+ - spec/package_spec.rb
150
+ - spec/plist_spec.rb
151
+ - spec/spec_helper.rb
152
+ - spec/static/example.plist
153
+ - spec/static/test.tar.gz
154
+ - spec/static/test.tgz
155
+ - spec/static/test.txt.gz
156
+ - spec/static/test.txt.zip
157
+ - spec/template_spec.rb
158
+ has_rdoc: true
159
+ homepage:
160
+ licenses: []
161
+
162
+ post_install_message:
163
+ rdoc_options: []
164
+
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ segments:
173
+ - 0
174
+ version: "0"
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ none: false
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ segments:
181
+ - 1
182
+ - 3
183
+ - 6
184
+ version: 1.3.6
185
+ requirements: []
186
+
187
+ rubyforge_project: geoffrey
188
+ rubygems_version: 1.3.7
189
+ signing_key:
190
+ specification_version: 3
191
+ summary: Geoffrey is a little helper to aid in the installation of packages and configuration of various Mac OSX applications.
192
+ test_files: []
193
+