dmg 0.0.3 → 0.0.4
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 +1 -1
- data/dmg.gemspec +5 -1
- data/features/dmg.feature +14 -0
- data/features/support/env.rb +23 -0
- data/lib/dmg.rb +47 -3
- data/lib/dmg/cli.rb +22 -12
- data/lib/dmg/output_helpers.rb +54 -0
- data/lib/dmg/pkg.rb +69 -24
- data/lib/dmg/pkgs.yml +12 -20
- data/lib/dmg/source.rb +66 -0
- data/lib/dmg/version.rb +1 -1
- data/spec/data/pkgs_1.yml +22 -0
- data/spec/data/pkgs_2.yml +24 -0
- data/spec/lib/pkg_spec.rb +106 -0
- data/spec/lib/sources_spec.rb +40 -0
- data/spec/spec_helper.rb +16 -0
- metadata +65 -9
data/Gemfile
CHANGED
data/dmg.gemspec
CHANGED
@@ -8,12 +8,16 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Philippe Creux"]
|
10
10
|
s.email = ["pcreux@gmail.com"]
|
11
|
-
s.homepage = ""
|
11
|
+
s.homepage = "https://github.com/versapay/dmg"
|
12
12
|
s.summary = %q{Install popular applications provided as dmgs from the command line}
|
13
13
|
s.description = %q{It's like apt-get for Mac}
|
14
14
|
|
15
15
|
s.default_executable = %q{dmg}
|
16
16
|
|
17
|
+
s.add_development_dependency 'rspec'
|
18
|
+
s.add_development_dependency 'cucumber'
|
19
|
+
s.add_development_dependency 'aruba'
|
20
|
+
|
17
21
|
s.files = `git ls-files`.split("\n")
|
18
22
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
23
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: dmg
|
2
|
+
|
3
|
+
In order to install dmgs via the command line
|
4
|
+
As a Mac user
|
5
|
+
I want to type dmg install chrome and it should just work!
|
6
|
+
|
7
|
+
Scenario: Run dmg for the first time
|
8
|
+
When I run "dmg list"
|
9
|
+
Then the output should contain "chrome"
|
10
|
+
Then the file ".dmg/sources.yml" should contain:
|
11
|
+
"""
|
12
|
+
- https://github.com/pcreux/dmg-pkgs/raw/master/pkgs.yml
|
13
|
+
"""
|
14
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Bundler.require
|
5
|
+
|
6
|
+
require 'aruba/cucumber'
|
7
|
+
|
8
|
+
# Following from 'aruba/cucumber'
|
9
|
+
Before do
|
10
|
+
@__aruba_original_paths = (ENV['PATH'] || '').split(File::PATH_SEPARATOR)
|
11
|
+
ENV['PATH'] = ([File.expand_path('bin')] + @__aruba_original_paths).join(File::PATH_SEPARATOR)
|
12
|
+
ENV['DMG_HOME'] = File.join(File.dirname(__FILE__), '..', '..', 'tmp', 'aruba')
|
13
|
+
end
|
14
|
+
|
15
|
+
After do
|
16
|
+
ENV['PATH'] = @__aruba_original_paths.join(File::PATH_SEPARATOR)
|
17
|
+
end
|
18
|
+
# End of following from 'aruba/cucumber'
|
19
|
+
|
20
|
+
Then /^the file "([^"]*)" should contain:$/ do |file, exact_content|
|
21
|
+
check_file_content(file, exact_content, true)
|
22
|
+
end
|
23
|
+
|
data/lib/dmg.rb
CHANGED
@@ -1,7 +1,51 @@
|
|
1
|
-
module DMG; end
|
2
|
-
|
3
1
|
require 'yaml'
|
4
2
|
|
5
|
-
|
3
|
+
module DMG
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def home_dir
|
7
|
+
ENV['DMG_HOME'] || ENV['HOME']
|
8
|
+
end
|
9
|
+
|
10
|
+
def config_dir
|
11
|
+
File.join(home_dir, '.dmg')
|
12
|
+
end
|
13
|
+
|
14
|
+
def sources_file
|
15
|
+
File.join(config_dir, 'sources.yml')
|
16
|
+
end
|
17
|
+
|
18
|
+
def combined_pkgs_file
|
19
|
+
File.join(config_dir, 'pkgs.yml')
|
20
|
+
end
|
21
|
+
|
22
|
+
def default_configuration
|
23
|
+
['https://github.com/pcreux/dmg-pkgs/raw/master/pkgs.yml']
|
24
|
+
end
|
25
|
+
|
26
|
+
def setup!
|
27
|
+
create_dmg_directory_if_needed
|
28
|
+
generate_default_source_file_if_needed
|
29
|
+
download_sources
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_dmg_directory_if_needed
|
33
|
+
unless File.directory?(config_dir)
|
34
|
+
Dir::mkdir(config_dir)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_default_source_file_if_needed
|
39
|
+
unless File.exists? sources_file
|
40
|
+
File.open(sources_file, 'w') { |f| f.write default_configuration.to_yaml }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def download_sources
|
45
|
+
DMG::Source.download_and_combine
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
%w{errors output_helpers source pkg cli}.each do |file|
|
6
50
|
require File.dirname(__FILE__) + "/dmg/#{file}"
|
7
51
|
end
|
data/lib/dmg/cli.rb
CHANGED
@@ -1,16 +1,26 @@
|
|
1
1
|
class DMG::CLI
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
DMG
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
2
|
+
class << self
|
3
|
+
include OutputHelpers
|
4
|
+
|
5
|
+
def run!
|
6
|
+
|
7
|
+
DMG.setup!
|
8
|
+
|
9
|
+
case ARGV[0]
|
10
|
+
when "install"
|
11
|
+
DMG::Pkg.install(ARGV[1..-1])
|
12
|
+
when "list"
|
13
|
+
puts DMG::Pkg.list
|
14
|
+
else
|
15
|
+
puts <<-EOF
|
16
|
+
Usage:
|
17
|
+
dmg install PACKAGE
|
18
|
+
dmg list
|
19
|
+
EOF
|
20
|
+
end
|
21
|
+
|
22
|
+
rescue DMG::DMGError => e
|
23
|
+
alert(e.message)
|
14
24
|
end
|
15
25
|
end
|
16
26
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module OutputHelpers
|
2
|
+
def info(text)
|
3
|
+
puts Output.green(text)
|
4
|
+
end
|
5
|
+
|
6
|
+
def debug(text)
|
7
|
+
puts Output.grey(text)
|
8
|
+
end
|
9
|
+
|
10
|
+
def alert(text)
|
11
|
+
puts Output.red(text)
|
12
|
+
end
|
13
|
+
|
14
|
+
module Output
|
15
|
+
|
16
|
+
extend self
|
17
|
+
|
18
|
+
def color(text, color_code)
|
19
|
+
"#{color_code}#{text}\e[0m"
|
20
|
+
end
|
21
|
+
|
22
|
+
def bold(text)
|
23
|
+
color(text, "\e[1m")
|
24
|
+
end
|
25
|
+
|
26
|
+
def white(text)
|
27
|
+
color(text, "\e[37m")
|
28
|
+
end
|
29
|
+
|
30
|
+
def green(text)
|
31
|
+
color(text, "\e[32m")
|
32
|
+
end
|
33
|
+
|
34
|
+
def red(text)
|
35
|
+
color(text, "\e[31m")
|
36
|
+
end
|
37
|
+
|
38
|
+
def magenta(text)
|
39
|
+
color(text, "\e[35m")
|
40
|
+
end
|
41
|
+
|
42
|
+
def yellow(text)
|
43
|
+
color(text, "\e[33m")
|
44
|
+
end
|
45
|
+
|
46
|
+
def blue(text)
|
47
|
+
color(text, "\e[34m")
|
48
|
+
end
|
49
|
+
|
50
|
+
def grey(text)
|
51
|
+
color(text, "\e[90m")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/dmg/pkg.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module DMG
|
2
2
|
class Pkg
|
3
3
|
def self.list
|
4
|
-
|
4
|
+
all.map(&:name).sort
|
5
5
|
end
|
6
6
|
|
7
7
|
def self.install(pkg_names)
|
@@ -9,53 +9,98 @@ module DMG
|
|
9
9
|
pkgs.each(&:install!)
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.
|
13
|
-
|
14
|
-
|
15
|
-
pkgs = YAML.load_file(File.dirname(__FILE__) + '/pkgs.yml')
|
16
|
-
pkgs.each do |key, values|
|
17
|
-
@@all << Pkg.new({'name' => key}.merge(values))
|
18
|
-
end
|
12
|
+
def self.find!(pkg_name)
|
13
|
+
pkg = all.select { |pkg| pkg.name == pkg_name }.first
|
14
|
+
raise PackageNotFound, "Can't find a package called '#{pkg_name}'" unless pkg
|
19
15
|
|
20
|
-
|
16
|
+
pkg
|
21
17
|
end
|
22
18
|
|
23
|
-
attr_reader :name, :package, :url, :volume_dir
|
19
|
+
attr_reader :name, :package, :url, :volume_dir, :mpkg
|
24
20
|
|
25
21
|
def initialize(args)
|
26
22
|
@name = args['name']
|
27
23
|
@package = args['package']
|
28
24
|
@url = args['url']
|
29
25
|
@volume_dir = args['volume_dir'] || @package
|
26
|
+
@mpkg = args['mpkg']
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def self.all
|
32
|
+
return @@all if defined?(@@all)
|
33
|
+
@@all = []
|
34
|
+
hash_from_yaml.each do |key, values|
|
35
|
+
@@all << Pkg.new({'name' => key}.merge(values))
|
36
|
+
end
|
37
|
+
|
38
|
+
@@all
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.hash_from_yaml
|
42
|
+
YAML.load_file(File.dirname(__FILE__) + '/pkgs.yml')
|
30
43
|
end
|
31
44
|
|
45
|
+
include OutputHelpers
|
46
|
+
|
32
47
|
def install!
|
33
|
-
|
34
|
-
|
48
|
+
if downloaded?
|
49
|
+
info "#{name} already downloaded in #{dmg_file}"
|
50
|
+
else
|
51
|
+
download
|
52
|
+
end
|
35
53
|
|
36
|
-
|
37
|
-
|
38
|
-
|
54
|
+
mount unless mounted?
|
55
|
+
if mpkg
|
56
|
+
open_mpkg
|
57
|
+
info "I've just launched #{name} installer!"
|
58
|
+
info ""
|
59
|
+
info "Don't forget to unmount the volume once done. Just run the following command:"
|
60
|
+
info " hdiutil detach '/Volumes/#{volume_dir}'"
|
61
|
+
info ""
|
62
|
+
else
|
63
|
+
copy_app
|
64
|
+
info "#{name} is now installed!"
|
39
65
|
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def dmg_file
|
69
|
+
"#{ENV['HOME']}/Downloads/#{package}.dmg"
|
70
|
+
end
|
71
|
+
|
72
|
+
def destination
|
73
|
+
'/Applications'
|
74
|
+
end
|
75
|
+
|
76
|
+
def mounted?
|
77
|
+
!!`hdiutil info`[/image-path.*#{dmg_file}/]
|
78
|
+
end
|
79
|
+
|
80
|
+
def download
|
81
|
+
run_cmd "curl -L #{url} -o '#{dmg_file}'"
|
82
|
+
end
|
40
83
|
|
41
|
-
|
84
|
+
def mount
|
42
85
|
run_cmd "hdid '#{dmg_file}'"
|
86
|
+
end
|
87
|
+
|
88
|
+
def open_mpkg
|
89
|
+
run_cmd "open /Volumes/#{volume_dir}/#{mpkg}.mpkg"
|
90
|
+
end
|
91
|
+
|
92
|
+
def copy_app
|
43
93
|
run_cmd "sudo cp -fr '/Volumes/#{volume_dir}/#{package}.app' '#{destination}'"
|
44
94
|
run_cmd "hdiutil detach '/Volumes/#{volume_dir}'"
|
45
95
|
run_cmd "sudo chmod 755 '#{destination}/#{package}.app/Contents/MacOS/#{package}'"
|
46
96
|
end
|
47
97
|
|
48
|
-
|
49
|
-
|
50
|
-
def self.find!(pkg_name)
|
51
|
-
pkg = all.select { |pkg| pkg.name == pkg_name }.first
|
52
|
-
raise PackageNotFound, "Can't find a package called '#{pkg_name}'" unless pkg
|
53
|
-
|
54
|
-
pkg
|
98
|
+
def downloaded?
|
99
|
+
File.exist?(dmg_file)
|
55
100
|
end
|
56
101
|
|
57
102
|
def run_cmd(cmd)
|
58
|
-
|
103
|
+
debug cmd
|
59
104
|
raise DMGError, "Failed to run a command" unless system(cmd)
|
60
105
|
end
|
61
106
|
end
|
data/lib/dmg/pkgs.yml
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# Does not work because of a broken symlink in the dmg
|
2
|
+
#dropbox:
|
3
|
+
# package: Dropbox
|
4
|
+
# volume_dir: Dropbox Installer
|
5
|
+
# url: "http://www.dropbox.com/download?plat=mac"
|
5
6
|
|
6
7
|
chrome:
|
7
8
|
package: Google Chrome
|
@@ -11,25 +12,16 @@ skype:
|
|
11
12
|
package: Skype
|
12
13
|
url: http://www.skype.com/go/getskype-macosx.dmg
|
13
14
|
|
14
|
-
steam:
|
15
|
-
package: Steam
|
16
|
-
url: http://cdn.store.steampowered.com/public/client/installer/steam.dmg
|
17
|
-
|
18
|
-
macirssi:
|
19
|
-
package: MacIrssi
|
20
|
-
url: http://www.sysctl.co.uk/projects/macirssi/downloads/MacIrssi-0.8.6.6.dmg
|
21
|
-
|
22
15
|
picasa:
|
23
16
|
package: Picasa
|
24
17
|
volume_dir: Picasa 3.8.9
|
25
18
|
url: http://dl.google.com/photos/picasamac38.dmg
|
26
19
|
|
27
|
-
|
28
|
-
package:
|
29
|
-
|
30
|
-
|
20
|
+
virtualbox:
|
21
|
+
package: VirtualBox
|
22
|
+
url: http://download.virtualbox.org/virtualbox/4.0.4/VirtualBox-4.0.4-70112-OSX.dmg
|
23
|
+
mpkg: VirtualBox
|
31
24
|
|
32
|
-
|
33
|
-
package:
|
34
|
-
url: http://
|
35
|
-
|
25
|
+
launchbar:
|
26
|
+
package: LaunchBar
|
27
|
+
url: http://www.obdev.at/downloads/launchbar/LaunchBar-5.0.4.dmg
|
data/lib/dmg/source.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module DMG
|
5
|
+
class Source
|
6
|
+
class << self
|
7
|
+
def download_and_combine
|
8
|
+
combine(Source.all)
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def combine(sources)
|
14
|
+
combined_pkgs_hash = {}
|
15
|
+
|
16
|
+
sources.each do |source|
|
17
|
+
combined_pkgs_hash.merge!(source.pkgs_hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
File.open(DMG::combined_pkgs_file, 'w') { |f| f.write(combined_pkgs_hash.to_yaml) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def all
|
24
|
+
YAML.load_file(DMG::sources_file).map do |path_or_url|
|
25
|
+
Source.new(path_or_url)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end # class << self
|
29
|
+
|
30
|
+
attr_reader :pkgs_hash
|
31
|
+
|
32
|
+
def initialize(path_or_url)
|
33
|
+
@pkgs_hash = YAML.load(get(path_or_url))
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return content from path or url
|
37
|
+
def get(path_or_url)
|
38
|
+
case path_or_url
|
39
|
+
when /^http(s):\/\//
|
40
|
+
get_file(path_or_url)
|
41
|
+
else
|
42
|
+
read_file(path_or_url)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
# Get file content from a url
|
49
|
+
def get_file(url)
|
50
|
+
uri = URI.parse(url)
|
51
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
52
|
+
http.use_ssl = true if uri.port == 443
|
53
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
54
|
+
|
55
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
56
|
+
|
57
|
+
response = http.request(request)
|
58
|
+
response.body
|
59
|
+
end
|
60
|
+
|
61
|
+
# Return file content from a path
|
62
|
+
def read_file(path)
|
63
|
+
File.read(path)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/dmg/version.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Does not work because of a broken symlink in the dmg
|
2
|
+
#dropbox:
|
3
|
+
# package: Dropbox
|
4
|
+
# volume_dir: Dropbox Installer
|
5
|
+
# url: "http://www.dropbox.com/download?plat=mac"
|
6
|
+
|
7
|
+
chrome:
|
8
|
+
package: Google Chrome
|
9
|
+
url: "https://dl-ssl.google.com/chrome/mac/stable/GGRM/googlechrome.dmg"
|
10
|
+
|
11
|
+
skype:
|
12
|
+
package: Skype
|
13
|
+
url: http://www.skype.com/go/getskype-macosx.dmg
|
14
|
+
|
15
|
+
picasa:
|
16
|
+
package: Picasa
|
17
|
+
volume_dir: Picasa 3.8.9
|
18
|
+
url: http://dl.google.com/photos/picasamac38.dmg
|
19
|
+
|
20
|
+
launchbar:
|
21
|
+
package: LaunchBar
|
22
|
+
url: http://www.obdev.at/downloads/launchbar/LaunchBar-5.0.4.dmg
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Does not work because of a broken symlink in the dmg
|
2
|
+
#dropbox:
|
3
|
+
# package: Dropbox
|
4
|
+
# volume_dir: Dropbox Installer
|
5
|
+
# url: "http://www.dropbox.com/download?plat=mac"
|
6
|
+
|
7
|
+
chrome:
|
8
|
+
package: Google Chrome
|
9
|
+
url: "https://dl-ssl.google.com/chrome/mac/stable/GGRM/googlechrome.dmg"
|
10
|
+
|
11
|
+
skype:
|
12
|
+
package: Skype
|
13
|
+
url: http://www.skype.com/go/getskype-macosx.dmg
|
14
|
+
|
15
|
+
picasa:
|
16
|
+
package: Picasa
|
17
|
+
volume_dir: Picasa 3.8.9
|
18
|
+
url: http://dl.google.com/photos/picasamac38.dmg
|
19
|
+
|
20
|
+
virtualbox:
|
21
|
+
package: VirtualBox
|
22
|
+
url: http://download.virtualbox.org/virtualbox/4.0.4/VirtualBox-4.0.4-70112-OSX.dmg
|
23
|
+
mpkg: VirtualBox
|
24
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DMG::Pkg do
|
4
|
+
before do
|
5
|
+
DMG::Pkg.stub!(:hash_from_yaml) do
|
6
|
+
{
|
7
|
+
"launchbar"=> {"url"=>"http://example.com/launchbar.dmg", "package"=>"LaunchBar"},
|
8
|
+
"virtualbox"=> {"url"=> "http://example.com/virtualbox.dmg", "package"=>"VirtualBox", "mpkg"=>"VirtualBox"},
|
9
|
+
"picasa"=> {"url"=>"http://example.com/picasa.dmg", "package"=>"Picasa", "volume_dir"=>"Picasa 3.8.9"}
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
DMG::Pkg.stub!(:install!)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "##all" do
|
17
|
+
subject { DMG::Pkg.all }
|
18
|
+
|
19
|
+
it "should return an array of DMG::Pkg" do
|
20
|
+
subject.should have(3).items
|
21
|
+
subject.each do |pkg|
|
22
|
+
pkg.should be_a(DMG::Pkg)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "one of the packages" do
|
27
|
+
subject { DMG::Pkg.all.select { |p| p.name == "launchbar" }.first }
|
28
|
+
its(:name) { should == "launchbar" }
|
29
|
+
its(:url) { should == "http://example.com/launchbar.dmg" }
|
30
|
+
its(:package) { should == "LaunchBar"}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "##list" do
|
35
|
+
subject { DMG::Pkg.list }
|
36
|
+
|
37
|
+
it "should return an array of packages names" do
|
38
|
+
subject.should be_an(Array)
|
39
|
+
subject.first.should be_a(String)
|
40
|
+
subject.sort.should == subject
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "##install" do
|
45
|
+
let(:launchbar) { DMG::Pkg.find!("launchbar") }
|
46
|
+
let(:picasa) { DMG::Pkg.find!("picasa") }
|
47
|
+
let(:virtualbox) { DMG::Pkg.find!("virtualbox") }
|
48
|
+
|
49
|
+
context "all the packages passed in exist" do
|
50
|
+
it "should call install on the packages with a name matching the ones passed in" do
|
51
|
+
launchbar.should_receive :install!
|
52
|
+
picasa.should_receive :install!
|
53
|
+
virtualbox.should_not_receive :install!
|
54
|
+
|
55
|
+
DMG::Pkg.install(%w(launchbar picasa))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "one of the package does not exist" do
|
60
|
+
it "should raise PackageNotFound" do
|
61
|
+
expect { DMG::Pkg.install(%w(launchbar coffeemaker)) }.should raise_error(DMG::PackageNotFound)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should not install any package" do
|
65
|
+
launchbar.should_not_receive :install!
|
66
|
+
DMG::Pkg.install(%w(launchbar coffeemaker)) rescue nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#initialize" do
|
72
|
+
context %{when passing in { "name" => "launchbar", "url" => "http://example.com/launchbar.dmg", "package" => "LaunchBar"} } do
|
73
|
+
subject { DMG::Pkg.new({ "name" => "launchbar", "url" => "http://example.com/launchbar.dmg", "package" => "LaunchBar"}) }
|
74
|
+
|
75
|
+
its(:name) { should == "launchbar" }
|
76
|
+
its(:package) { should == "LaunchBar" }
|
77
|
+
its(:url) { should == "http://example.com/launchbar.dmg" }
|
78
|
+
its(:volume_dir) { should == "LaunchBar" }
|
79
|
+
its(:mpkg) { should be_nil }
|
80
|
+
end
|
81
|
+
|
82
|
+
context %{when passing in { "package" => "LaunchBar", "volume_dir" => "LaunchBarDMG", "mpkg" => "install.mpkg"} } do
|
83
|
+
subject { DMG::Pkg.new({ "package" => "LaunchBar", "volume_dir" => "LaunchBarDMG", "mpkg" => "install.mpkg"}) }
|
84
|
+
|
85
|
+
its(:package) { should == "LaunchBar" }
|
86
|
+
its(:volume_dir) { should == "LaunchBarDMG" }
|
87
|
+
its(:mpkg) { should == "install.mpkg" }
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when the name, package or url is missing" do
|
91
|
+
it "should raise an exception"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#install! (protected)" do
|
96
|
+
# This method runs a bunch of system commands that can only be
|
97
|
+
# tested in integration tests only
|
98
|
+
# We should refactor it as it contains a few switches:
|
99
|
+
context "when dmg not installed yet"
|
100
|
+
context "when dmg already installed"
|
101
|
+
context "when dmg not downloaded yet"
|
102
|
+
context "when dmg already downloaded"
|
103
|
+
context "when dmg has a mpkg"
|
104
|
+
context "when dmg does not have a mpkg"
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DMG::Source do
|
4
|
+
|
5
|
+
let(:pkgs_1_path) { File.join(File.dirname(__FILE__), '..', 'data', 'pkgs_1.yml') }
|
6
|
+
let(:pkgs_2_path) { File.join(File.dirname(__FILE__), '..', 'data', 'pkgs_2.yml') }
|
7
|
+
let(:pkgs_1_url) { 'https://github.com/versapay/dmg/raw/master/spec/data/pkgs_1.yml' }
|
8
|
+
|
9
|
+
describe "#initialize" do
|
10
|
+
context "when given a path to a yaml file" do
|
11
|
+
subject { DMG::Source.new(pkgs_1_path) }
|
12
|
+
|
13
|
+
its(:pkgs_hash) { should == YAML.load_file(pkgs_1_path) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when given a url" do
|
17
|
+
subject { DMG::Source.new(pkgs_1_url) }
|
18
|
+
|
19
|
+
its(:pkgs_hash) { should == YAML.load_file(pkgs_1_path) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#download_and_combine" do
|
24
|
+
before do
|
25
|
+
File.open(DMG.sources_file, 'w') { |f| f.write [pkgs_1_path, pkgs_2_path].to_yaml }
|
26
|
+
DMG::Source.download_and_combine
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "generated combined packages file" do
|
30
|
+
let(:combined_pkgs) { YAML.load_file(DMG.combined_pkgs_file) }
|
31
|
+
|
32
|
+
subject { combined_pkgs }
|
33
|
+
|
34
|
+
it { should include("launchbar") } # in pkgs_1.yml only
|
35
|
+
it { should include("virtualbox") } # in pkgs_2.yml only
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bundler"
|
6
|
+
Bundler.load
|
7
|
+
|
8
|
+
require 'rspec'
|
9
|
+
require 'dmg'
|
10
|
+
|
11
|
+
Rspec.configure do |config|
|
12
|
+
config.mock_with :rspec
|
13
|
+
end
|
14
|
+
|
15
|
+
ENV['DMG_HOME'] = File.join(File.dirname(__FILE__), '..', 'tmp', 'aruba')
|
16
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dmg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Philippe Creux
|
@@ -15,10 +15,51 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-05-02 00:00:00 -07:00
|
19
19
|
default_executable: dmg
|
20
|
-
dependencies:
|
21
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: cucumber
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: aruba
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :development
|
62
|
+
version_requirements: *id003
|
22
63
|
description: It's like apt-get for Mac
|
23
64
|
email:
|
24
65
|
- pcreux@gmail.com
|
@@ -35,14 +76,23 @@ files:
|
|
35
76
|
- Rakefile
|
36
77
|
- bin/dmg
|
37
78
|
- dmg.gemspec
|
79
|
+
- features/dmg.feature
|
80
|
+
- features/support/env.rb
|
38
81
|
- lib/dmg.rb
|
39
82
|
- lib/dmg/cli.rb
|
40
83
|
- lib/dmg/errors.rb
|
84
|
+
- lib/dmg/output_helpers.rb
|
41
85
|
- lib/dmg/pkg.rb
|
42
86
|
- lib/dmg/pkgs.yml
|
87
|
+
- lib/dmg/source.rb
|
43
88
|
- lib/dmg/version.rb
|
89
|
+
- spec/data/pkgs_1.yml
|
90
|
+
- spec/data/pkgs_2.yml
|
91
|
+
- spec/lib/pkg_spec.rb
|
92
|
+
- spec/lib/sources_spec.rb
|
93
|
+
- spec/spec_helper.rb
|
44
94
|
has_rdoc: true
|
45
|
-
homepage:
|
95
|
+
homepage: https://github.com/versapay/dmg
|
46
96
|
licenses: []
|
47
97
|
|
48
98
|
post_install_message:
|
@@ -75,5 +125,11 @@ rubygems_version: 1.3.7
|
|
75
125
|
signing_key:
|
76
126
|
specification_version: 3
|
77
127
|
summary: Install popular applications provided as dmgs from the command line
|
78
|
-
test_files:
|
79
|
-
|
128
|
+
test_files:
|
129
|
+
- features/dmg.feature
|
130
|
+
- features/support/env.rb
|
131
|
+
- spec/data/pkgs_1.yml
|
132
|
+
- spec/data/pkgs_2.yml
|
133
|
+
- spec/lib/pkg_spec.rb
|
134
|
+
- spec/lib/sources_spec.rb
|
135
|
+
- spec/spec_helper.rb
|