firestone 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.2"
4
+ - "1.9.3"
5
+ - jruby-19mode
6
+ - rbx-19mode
7
+ script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in init.gemspec
4
+ gemspec
@@ -0,0 +1,62 @@
1
+ # firestone [![Build Status](https://travis-ci.org/Achillefs/firestone.png?branch=master)](https://travis-ci.org/Achillefs/firestone)
2
+
3
+ A collection of Firefox automation and programmatic management scripts in Ruby
4
+
5
+ ## Platforms
6
+
7
+ Profile and Addon management works on Windows, Linux and Mac OSX.
8
+ The Installer is only implemented for OSX at this time.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'firestone', :require => 'firefox'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install firestone
23
+
24
+ ## Usage
25
+
26
+ ### Install Firefox from a ruby script
27
+
28
+ require 'firefox'
29
+ Firefox.install!
30
+
31
+ or
32
+
33
+ require 'firefox'
34
+ installer = Firefox::Installer.new(:osx)
35
+ installer.install!
36
+
37
+ This currently only works on OSX.
38
+
39
+ ### Create a new Firefox profile with a couple of custom preferences
40
+
41
+ require 'firefox'
42
+ p = Firefox::Profile.create('./newprofile')
43
+ p.prefs = {
44
+ 'browser.rights.3.shown' => true,
45
+ 'browser.shell.checkDefaultBrowser' => false,
46
+ 'toolkit.telemetry.prompted' => 2,
47
+ 'toolkit.telemetry.rejected' => true
48
+ }
49
+ p.save!
50
+
51
+ This will create a new firefox profile in `./newprofile`. It will populate the new profile's preferences with the values provided.
52
+ If the given folder does not exist it will create it.
53
+
54
+ ## Suggestions, comments, bugs, whatever
55
+ Feel free to use Issues to submit bugs, suggestions or feature requests.
56
+
57
+ ## Contributing
58
+ 1. Fork it
59
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
60
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
61
+ 4. Push to the branch (`git push origin my-new-feature`)
62
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "firefox/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "firestone"
7
+ s.version = Firefox::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Achilles Charmpilas"]
10
+ s.email = ["ac@humbuckercode.co.uk"]
11
+ s.homepage = "http://humbuckercode.co.uk/licks/gems/firestone"
12
+ s.summary = %q{A collection of Firefox automation and programmatic management scripts in Ruby}
13
+ s.description = %q{A collection of Firefox automation and programmatic management scripts in Ruby}
14
+
15
+ s.rubyforge_project = "firestone"
16
+ s.add_dependency 'progressbar'
17
+ s.add_development_dependency 'rspec'
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+ end
@@ -0,0 +1,7 @@
1
+ require "#{File.dirname(File.realpath(__FILE__))}/fondue"
2
+ %W{ version base prefs profile addons installer }.each { |r| require "#{File.dirname(File.realpath(__FILE__))}/firefox/#{r}" }
3
+ module Firefox
4
+ def self.install!
5
+ installer = Firefox::Installer.new(Firefox::Base.platform(RUBY_PLATFORM))
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ module Firefox
2
+ class Addons < Fondue::HashClass
3
+ attr_accessor :path, :addons
4
+
5
+ def initialize extension_path
6
+ @path = extension_path
7
+ @addons = {}
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,39 @@
1
+ module Firefox
2
+ class UnsupportedOSError < Exception # :nodoc:
3
+ def initialize message
4
+ super message
5
+ end
6
+ end
7
+
8
+ class Base
9
+ class <<self
10
+ def bin_path
11
+ return ENV['FIREFOX_PATH'] if ENV['FIREFOX_PATH']
12
+
13
+ @bin_path = ''
14
+ case platform(RUBY_PLATFORM)
15
+ when :osx
16
+ @bin_path = '/Applications/Firefox.app/Contents/MacOS/firefox-bin'
17
+ when :win
18
+ @bin_path = '"C:\Program Files\Mozilla Firefox\firefox.exe"'
19
+ when :linux
20
+ @bin_path = '/usr/bin/firefox'
21
+ else
22
+ raise UnsupportedOSError.new("I don't really know what OS you're on, sorry")
23
+ end
24
+ end
25
+
26
+ def platform(host_os)
27
+ return :osx if host_os =~ /darwin/
28
+ return :linux if host_os =~ /linux/
29
+ return :windows if host_os =~ /mingw32|mswin32/
30
+ return :unknown
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+
37
+ /darwin/
38
+ /linux/
39
+ /mingw32/
@@ -0,0 +1,66 @@
1
+ require 'open-uri'
2
+ require 'rubygems'
3
+ require 'progressbar'
4
+
5
+ module Firefox
6
+ class Installer
7
+ attr_reader :os, :lang, :version
8
+
9
+ def initialize os, language = nil, version = nil, opts = {}
10
+ # set dmg if specified
11
+ if opts[:dmg]
12
+ @dmg_file = opts.delete(:dmg)
13
+ raise "#{@dmg_file} not found" unless File.exist?(@dmg_file)
14
+ end
15
+ @os = os
16
+ @lang = language || 'en-US'
17
+ @version = version || get_current_version
18
+ end
19
+
20
+ def install!
21
+ # if no dmg was specified, download an installer
22
+ unless @dmg_file
23
+ download_url = "http://download.mozilla.org/?lang=#{lang}&product=firefox-#{version}&os=#{os}"
24
+ pbar = nil
25
+ installer = open(download_url,
26
+ :content_length_proc => lambda {|t|
27
+ if t && 0 < t
28
+ pbar = ProgressBar.new("Downloading", t)
29
+ pbar.bar_mark = '='
30
+ pbar.file_transfer_mode
31
+ end
32
+ },
33
+ :progress_proc => lambda {|s|
34
+ pbar.set s if pbar
35
+ }
36
+ )
37
+ pbar.finish
38
+ end
39
+
40
+ case os
41
+ when :osx
42
+ tmp_path = @dmg_file ? @dmg_file : File.join(Dir.tmpdir,'firefox.dmg')
43
+ unless @dmg_file
44
+ File.open(tmp_path,'w') { |f| f.write(installer.read) }
45
+ puts "Downloaded installer in #{tmp_path}"
46
+ end
47
+
48
+ puts "hdiutil mount #{tmp_path} 2>&1"
49
+ mount_response = `hdiutil mount #{tmp_path} 2>&1`
50
+ raise mount_response if mount_response =~ /mount failed/
51
+ volume = mount_response.split.last
52
+ puts "Mounted on #{volume}"
53
+ FileUtils.cp_r(File.join(volume,'Firefox.app'), '/Applications/Firefox.app')
54
+ puts 'Copied App in /Applications'
55
+ unmount_response = `hdiutil unmount #{volume} 2>&1`
56
+ raise unmount_response if unmount_response =~ /unmount failed/
57
+ puts "Unmounted #{volume}"
58
+ end
59
+ end
60
+
61
+ def get_current_version
62
+ page = open("http://www.mozilla.org/en-US/").read
63
+ page.scan(/download\.html\?product\=firefox\-([^&]*)/).first.first
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,80 @@
1
+ # A ruby interface to Firefox Prefs.js
2
+ module Firefox
3
+ class Prefs < Fondue::HashClass
4
+ # default prefs.js banner
5
+ BANNER = %{# Mozilla User Preferences
6
+
7
+ /* Do not edit this file.
8
+ *
9
+ * If you make changes to this file while the application is running,
10
+ * the changes will be overwritten when the application exits.
11
+ *
12
+ * To make a manual change to preferences, you can visit the URL about:config
13
+ */
14
+
15
+ }
16
+
17
+ attr_accessor :raw_prefs, :path, :prefs
18
+
19
+ def initialize path_to_prefs
20
+ @path = path_to_prefs
21
+ @prefs = {}
22
+ @types = {}
23
+ parse_prefs!
24
+ end
25
+
26
+ def write! write_path = ''
27
+ path = write_path == '' ? @path : write_path
28
+ File.open(path,'w') { |f| f.write(stringified_prefs) }
29
+ end
30
+
31
+ def stringified_prefs
32
+ string = ''
33
+ string << BANNER
34
+ string << @prefs.map { |key,val|
35
+ %{user_pref("#{key}", #{val.is_a?(String) ? %{"#{val}"} : val});}
36
+ }.join("\n")
37
+ string << "\n"
38
+ end
39
+ protected
40
+ def parse_prefs!
41
+ File.open(path).each_line do |p|
42
+ hits = p.scan /user_pref\("([^"]*)",([^\)]*)\)\;/
43
+ if hits
44
+ key,val = hits.first
45
+ @types[key] = find_type(val)
46
+ @prefs[key] = typecast(key,val) unless key.nil?
47
+ end
48
+ end
49
+ end
50
+
51
+ def find_type value
52
+ case value
53
+ when /^ "/
54
+ 'string'
55
+ when ' true'
56
+ 'true'
57
+ when ' false'
58
+ 'false'
59
+ else
60
+ 'integer'
61
+ end
62
+ end
63
+
64
+ def typecast key,value
65
+ value = value.strip.gsub(/^"/,'').strip.gsub(/"$/,'')
66
+ case @types[key]
67
+ when 'integer'
68
+ value.to_i
69
+ when 'string'
70
+ value
71
+ when 'true'
72
+ true
73
+ when 'false'
74
+ false
75
+ else
76
+ value
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,42 @@
1
+ require 'fileutils'
2
+
3
+ module Firefox
4
+ class ProfileInitializationError < Exception # :nodoc:
5
+ end
6
+
7
+ # A Firefox profile. Allows basic creation and management of a profile.
8
+ # Supports preference setting and addon installation
9
+ class Profile
10
+ attr_accessor :prefs, :addons
11
+
12
+ def initialize path
13
+ @prefs = Prefs.new(File.join(path,'prefs.js'))
14
+ @addons = Addons.new(File.join(path,'extensions'))
15
+ end
16
+
17
+ def save!
18
+ self.prefs.write!
19
+ end
20
+
21
+ class << self
22
+ # Register a new profile with firefox.
23
+ # This is the right way to initialize a new profile.
24
+ # It checks if the given directory exists, creates it if not
25
+ def create path
26
+ FileUtils.mkdir_p(path) unless File.directory?(path)
27
+ FileUtils.touch(%W[prefs user].map { |f| File.join(path,"#{f}.js") })
28
+ response = call_ff_create(path)
29
+ if response =~ /Error/
30
+ raise ProfileInitializationError, response
31
+ else
32
+ self.new(path)
33
+ end
34
+ end
35
+
36
+ def call_ff_create path
37
+ name = File.split(path).last
38
+ %x[#{Base.bin_path} -CreateProfile \"#{name} #{File.realpath(path)}\" 2>&1]
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ module Firefox
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,4 @@
1
+ %W{ version hash_class }.each { |r| require "#{File.dirname(File.realpath(__FILE__))}/fondue/#{r}" }
2
+
3
+ module Fondue
4
+ end
@@ -0,0 +1,58 @@
1
+ module Fondue
2
+ # A basic hash-centric class implementation.
3
+ # Extend it and specify a hash_attribute, to which all missing methods will be delegated to.
4
+ # If no hash attribute is specified, it is inferred from the class name
5
+ # Example:
6
+ # class MyDataContainer < Fondue::HashClass
7
+ # hash_attribute :data
8
+ # end
9
+ #
10
+ # c = MyDataContainer.new(:data => {:foo => 'bar'})
11
+ # c.map { |k,v| puts "#{k} => #{v}" }
12
+ # #=> "foo => bar"
13
+ # c[:foo]
14
+ # #=> 'bar'
15
+ # c.foo
16
+ # #=> 'bar'
17
+ class HashClass
18
+ def initialize options = {}
19
+ options.map do |k,v|
20
+ self.class.send(:attr_accessor,k.to_sym) unless respond_to?(:"#{k}=")
21
+ send(:"#{k}=",v)
22
+ end
23
+ end
24
+
25
+ def method_missing name, *args, &block
26
+ hash = instance_variable_get(self.class.get_hash_attribute)
27
+ if hash.respond_to?(name)
28
+ hash.send(name,*args)
29
+ elsif hash.key?(name)
30
+ hash[name]
31
+ elsif hash.key?(name.to_s)
32
+ hash[name.to_s]
33
+ else
34
+ super
35
+ end
36
+ end
37
+
38
+ class << self
39
+
40
+ def hash_attribute attr_name
41
+ @hash_attribute = "@#{attr_name}"
42
+ end
43
+
44
+ def get_hash_attribute
45
+ if @hash_attribute and @hash_attribute != ''
46
+ @hash_attribute
47
+ else
48
+ "@#{stringify(self.to_s)}"
49
+ end
50
+ end
51
+
52
+ def stringify klass
53
+ string = klass.to_s.split('::').last
54
+ string.gsub(/([A-Z][a-z]*)/,'_\1').gsub(/^_/,'').downcase
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module Fondue
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Firefox::Addons do
4
+ before { @path = './spec/files/' }
5
+ subject { Firefox::Addons.new(@path) }
6
+
7
+ it { subject.size.should eq(0) }
8
+ end
@@ -0,0 +1,76 @@
1
+ # Mozilla User Preferences
2
+
3
+ /* Do not edit this file.
4
+ *
5
+ * If you make changes to this file while the application is running,
6
+ * the changes will be overwritten when the application exits.
7
+ *
8
+ * To make a manual change to preferences, you can visit the URL about:config
9
+ */
10
+
11
+ user_pref("app.update.lastUpdateTime.addon-background-update-timer", 1360330995);
12
+ user_pref("app.update.lastUpdateTime.background-update-timer", 1360330875);
13
+ user_pref("app.update.lastUpdateTime.blocklist-background-update-timer", 1360331115);
14
+ user_pref("app.update.lastUpdateTime.browser-cleanup-thumbnails", 1360334835);
15
+ user_pref("app.update.lastUpdateTime.search-engine-update-timer", 1360330755);
16
+ user_pref("browser.bookmarks.restore_default_bookmarks", false);
17
+ user_pref("browser.cache.disk.capacity", 358400);
18
+ user_pref("browser.cache.disk.smart_size.first_run", false);
19
+ user_pref("browser.cache.disk.smart_size.use_old_max", false);
20
+ user_pref("browser.cache.disk.smart_size_cached_value", 358400);
21
+ user_pref("browser.migration.version", 8);
22
+ user_pref("browser.newtabpage.storageVersion", 1);
23
+ user_pref("browser.pagethumbnails.storage_version", 2);
24
+ user_pref("browser.places.smartBookmarksVersion", 4);
25
+ user_pref("browser.preferences.advanced.selectedTabIndex", 1);
26
+ user_pref("browser.rights.3.shown", true);
27
+ user_pref("browser.shell.checkDefaultBrowser", false);
28
+ user_pref("browser.startup.homepage_override.buildID", "20130201065344");
29
+ user_pref("browser.startup.homepage_override.mstone", "18.0.2");
30
+ user_pref("extensions.blocklist.pingCountTotal", 2);
31
+ user_pref("extensions.blocklist.pingCountVersion", 2);
32
+ user_pref("extensions.bootstrappedAddons", "{}");
33
+ user_pref("extensions.databaseSchema", 14);
34
+ user_pref("extensions.enabledAddons", "%7B81BF1D23-5F17-408D-AC6B-BD6DF7CAF670%7D:7.6.0.2,%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D:18.0.2");
35
+ user_pref("extensions.imacros.close-sidebar", false);
36
+ user_pref("extensions.imacros.defdatapath", "/Users/achilles/Scripts/serpclicker/iMacros/Datasources");
37
+ user_pref("extensions.imacros.defdownpath", "/Users/achilles/Scripts/serpclicker/iMacros/Downloads");
38
+ user_pref("extensions.imacros.deflogpath", "/Users/achilles/Scripts/serpclicker/iMacros");
39
+ user_pref("extensions.imacros.defsavepath", "/Users/achilles/Scripts/serpclicker/iMacros/Macros");
40
+ user_pref("extensions.imacros.prefs-checked", true);
41
+ user_pref("extensions.imacros.toolbar-checked", true);
42
+ user_pref("extensions.imacros.version", "7.6.0.2");
43
+ user_pref("extensions.installCache", "[{\"name\":\"app-system-local\",\"addons\":{\"web2pdfextension@web2pdf.adobedotcom\":{\"descriptor\":\"/Library/Application Support/Mozilla/Extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/web2pdfextension@web2pdf.adobedotcom\",\"mtime\":1346950540000}}},{\"name\":\"app-global\",\"addons\":{\"{972ce4c6-7e08-4474-a285-3208198ce6fd}\":{\"descriptor\":\"/Applications/Firefox.app/Contents/MacOS/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}\",\"mtime\":1360168925000}}},{\"name\":\"app-profile\",\"addons\":{\"{81BF1D23-5F17-408D-AC6B-BD6DF7CAF670}\":{\"descriptor\":\"/Users/achilles/Scripts/serpclicker/profiles/2200/extensions/{81BF1D23-5F17-408D-AC6B-BD6DF7CAF670}\",\"mtime\":1360326598000}}}]");
44
+ user_pref("extensions.lastAppVersion", "18.0.2");
45
+ user_pref("extensions.lastPlatformVersion", "18.0.2");
46
+ user_pref("extensions.pendingOperations", false);
47
+ user_pref("extensions.shownSelectionUI", true);
48
+ user_pref("gecko.buildID", "20130201065344");
49
+ user_pref("gecko.mstone", "18.0.2");
50
+ user_pref("gfx.blacklist.webgl.msaa", 4);
51
+ user_pref("idle.lastDailyNotification", 1360332222);
52
+ user_pref("intl.charsetmenu.browser.cache", "UTF-8");
53
+ user_pref("network.cookie.prefsMigrated", true);
54
+ user_pref("network.proxy.socks", "127.0.0.1");
55
+ user_pref("network.proxy.socks_port", 2200);
56
+ user_pref("network.proxy.type", 1);
57
+ user_pref("places.database.lastMaintenance", 1360332223);
58
+ user_pref("places.history.expiration.transient_current_max_pages", 104858);
59
+ user_pref("privacy.sanitize.migrateFx3Prefs", true);
60
+ user_pref("services.sync.clients.lastSync", "0");
61
+ user_pref("services.sync.clients.lastSyncLocal", "0");
62
+ user_pref("services.sync.globalScore", 0);
63
+ user_pref("services.sync.migrated", true);
64
+ user_pref("services.sync.nextSync", 0);
65
+ user_pref("services.sync.tabs.lastSync", "0");
66
+ user_pref("services.sync.tabs.lastSyncLocal", "0");
67
+ user_pref("storage.vacuum.last.index", 0);
68
+ user_pref("storage.vacuum.last.places.sqlite", 1360332223);
69
+ user_pref("toolkit.startup.last_success", 1360330635);
70
+ user_pref("toolkit.telemetry.prompted", 2);
71
+ user_pref("toolkit.telemetry.rejected", true);
72
+ user_pref("urlclassifier.keyupdatetime.https://sb-ssl.google.com/safebrowsing/newkey", 1362918603);
73
+ user_pref("xpinstall.whitelist.add", "");
74
+ user_pref("xpinstall.whitelist.add.180", "");
75
+ user_pref("xpinstall.whitelist.add.36", "");
76
+ user_pref("xpinstall", "test");
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'fondue/hash_class'
3
+
4
+ describe Fondue::HashClass do
5
+ before { @hash = {:foo => 'bar', 'bin' => :bash} }
6
+ subject { Fondue::HashClass.new(:hash_class => @hash) }
7
+
8
+ it {subject.hash_class.should eq(@hash)}
9
+ it {subject.foo.should eq('bar')}
10
+ it {subject[:foo].should eq('bar')}
11
+ it {subject.bin.should eq(:bash)}
12
+ it {subject['bin'].should eq(:bash)}
13
+ it {subject.class.get_hash_attribute.should eq('@hash_class')}
14
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Firefox::Prefs do
4
+ before { @read_path = './spec/files/prefs.js' }
5
+ subject { Firefox::Prefs.new(@read_path) }
6
+ it { subject.size.should eq(66) }
7
+ it { subject["app.update.lastUpdateTime.addon-background-update-timer"].should eq(1360330995) }
8
+ it { subject["intl.charsetmenu.browser.cache"].should eq('UTF-8') }
9
+ it { subject.xpinstall.should eq('test') }
10
+ it { subject.key?("intl.charsetmenu.browser.cache").should eq(true) }
11
+ it { subject.each.should be_a(Enumerable) }
12
+
13
+ context "write!" do
14
+ before { @write_path = './spec/files/new_prefs.js' }
15
+ after { FileUtils.rm @write_path }
16
+
17
+ it 'can write config' do
18
+ subject.write! @write_path
19
+ File.read(@write_path).should eq(File.read(@read_path))
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Firefox::Profile do
4
+ before { @path = './spec/files/' }
5
+
6
+ context '#register_profile' do
7
+ before {
8
+ @path = './spec/files/testprofile'
9
+ Firefox::Profile.stub(:call_ff_create).and_return("Success: created profile 'test /Users/achilles/Scripts/serpclicker/profiles/' at '/Users/achilles/Scripts/serpclicker/profiles/prefs.js'")
10
+ }
11
+ after { FileUtils.rm_rf @path }
12
+ subject { Firefox::Profile.create(@path) }
13
+
14
+ it { subject.should be_a(Firefox::Profile) }
15
+ it "saves prefs on save" do
16
+ subject.prefs.merge!({ :test => true })
17
+ subject.save!
18
+
19
+ n = Firefox::Profile.new(@path)
20
+ n.prefs.prefs.should eq({ "test" => true })
21
+ end
22
+ end
23
+
24
+ subject { Firefox::Profile.new(@path) }
25
+ it { subject.prefs.should be_a(Firefox::Prefs) }
26
+ it { subject.addons.should be_a(Firefox::Addons) }
27
+ end
@@ -0,0 +1,2 @@
1
+ require 'rspec'
2
+ require './lib/firefox'
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: firestone
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Achilles Charmpilas
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-17 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: progressbar
16
+ requirement: &2161532540 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2161532540
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &2161532120 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2161532120
36
+ description: A collection of Firefox automation and programmatic management scripts
37
+ in Ruby
38
+ email:
39
+ - ac@humbuckercode.co.uk
40
+ executables: []
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitignore
45
+ - .travis.yml
46
+ - Gemfile
47
+ - README.md
48
+ - Rakefile
49
+ - firestone.gemspec
50
+ - lib/firefox.rb
51
+ - lib/firefox/addons.rb
52
+ - lib/firefox/base.rb
53
+ - lib/firefox/installer.rb
54
+ - lib/firefox/prefs.rb
55
+ - lib/firefox/profile.rb
56
+ - lib/firefox/version.rb
57
+ - lib/fondue.rb
58
+ - lib/fondue/hash_class.rb
59
+ - lib/fondue/version.rb
60
+ - spec/addons_spec.rb
61
+ - spec/files/prefs.js
62
+ - spec/hash_class_spec.rb
63
+ - spec/prefs_spec.rb
64
+ - spec/profile_spec.rb
65
+ - spec/spec_helper.rb
66
+ homepage: http://humbuckercode.co.uk/licks/gems/firestone
67
+ licenses: []
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project: firestone
86
+ rubygems_version: 1.8.10
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: A collection of Firefox automation and programmatic management scripts in
90
+ Ruby
91
+ test_files:
92
+ - spec/addons_spec.rb
93
+ - spec/files/prefs.js
94
+ - spec/hash_class_spec.rb
95
+ - spec/prefs_spec.rb
96
+ - spec/profile_spec.rb
97
+ - spec/spec_helper.rb