wrapp 0.7.0 → 1.0.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/README.md +11 -14
- data/Rakefile +8 -1
- data/features/step_definitions/wrapp_steps.rb +6 -28
- data/features/wrap_app.feature +0 -11
- data/lib/wrapp/app_info.rb +9 -3
- data/lib/wrapp/cli.rb +6 -18
- data/lib/wrapp/dmg_builder.rb +16 -43
- data/lib/wrapp/version.rb +1 -1
- data/spec/wrapp/app_info_spec.rb +28 -22
- data/spec/wrapp/dmg_builder_spec.rb +34 -90
- data/wrapp.gemspec +2 -3
- metadata +14 -29
- data/spec/wrapp/cli_spec.rb +0 -101
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54994c6d0a856e53eceb3b353ef7fe2384c05503
|
4
|
+
data.tar.gz: 7ff29db4389a0a90ad6af7a2ad992f702f4df781
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36812b6fcdc3f58b3a07a459c79f24fdbf18c2cb98e3e85307e5d6021f552e1bcd66c8fabc51e10d2f40a70efb46cf036366d2929eac994da54bddb44fb37178
|
7
|
+
data.tar.gz: 4db6c6254add35e2a3860224ff6d94763fa557e75dd70e6c3ab54e71f23a922a7dad5ef7cf53e311789fa8e1e62e04e317a9cf0ad22bf39201d99a06c7bde20d
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -10,43 +10,39 @@ Wrap an App... in a disk image (DMG).
|
|
10
10
|
Say you wanna put your nice Mac OS X application in a handy disk image
|
11
11
|
(DMG) for distribution.
|
12
12
|
Why not use *wrapp* for this?
|
13
|
-
It is
|
13
|
+
It is a short wrapper around `hdiutil` ;-)
|
14
14
|
|
15
15
|
|
16
16
|
## Requirements
|
17
17
|
|
18
|
-
This
|
18
|
+
This runs only on macOS.
|
19
19
|
|
20
20
|
|
21
21
|
## Installation
|
22
22
|
|
23
23
|
Install it yourself as:
|
24
24
|
|
25
|
-
$ sudo gem install wrapp
|
25
|
+
$ sudo gem install wrapp -n /usr/local/bin
|
26
26
|
|
27
27
|
(Note: Rbenv/RVM users probably want to install without `sudo`.)
|
28
28
|
|
29
29
|
|
30
30
|
## Usage
|
31
31
|
|
32
|
-
Try `wrapp --help`!
|
33
|
-
|
34
|
-
Some examples...
|
35
|
-
|
36
|
-
Wrap the *Chunky Bacon* App:
|
37
|
-
|
38
32
|
```
|
39
|
-
wrapp
|
33
|
+
$ wrapp --help
|
34
|
+
Usage: wrapp [options] APP_PATH
|
35
|
+
-f, --filesystem FILESYSTEM Causes a filesystem of the specified type to be written to the image.
|
36
|
+
-n, --volume-name NAME Volume name of the newly created filesystem.
|
40
37
|
```
|
41
38
|
|
42
|
-
|
43
|
-
the content (some stuff like *TeamViewer* or *FileMaker* reside in
|
44
|
-
sub-directories of `/Applications` rather then the top-level itself):
|
39
|
+
Examples...
|
45
40
|
|
46
41
|
```
|
47
|
-
wrapp
|
42
|
+
wrapp /Applications/Chunky\ Bacon.app
|
48
43
|
```
|
49
44
|
|
45
|
+
|
50
46
|
The commands create a DMG like `chunky_bacon_1.2.3.dmg` that contains
|
51
47
|
the given App. (the filename automatically includes the name and version).
|
52
48
|
|
@@ -54,6 +50,7 @@ Thats it.
|
|
54
50
|
|
55
51
|
(NOTE: On authorization errors try prefixing the command with `sudo`!)
|
56
52
|
|
53
|
+
|
57
54
|
## Contributing
|
58
55
|
|
59
56
|
Thanks for your help! Please contact me via Github or check the open
|
data/Rakefile
CHANGED
@@ -10,13 +10,13 @@ end
|
|
10
10
|
|
11
11
|
def attach_dmg
|
12
12
|
assert_dmg_exists
|
13
|
-
|
13
|
+
create_directory(volumes_dir)
|
14
14
|
cmd = "hdiutil attach '#{@app.dmg_filename}' -nobrowse -mountroot '#{volumes_dir}'"
|
15
15
|
run_simple(cmd, true)
|
16
16
|
end
|
17
17
|
|
18
18
|
def detach_dmg
|
19
|
-
|
19
|
+
cd('.') do
|
20
20
|
Dir.glob("#{volumes_dir}/*") do |dir|
|
21
21
|
system("hdiutil detach '#{dir}' -force >/dev/null")
|
22
22
|
end
|
@@ -24,7 +24,7 @@ def detach_dmg
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def assert_dmg_exists
|
27
|
-
|
27
|
+
expect(@app.dmg_filename).to be_an_existing_file
|
28
28
|
end
|
29
29
|
|
30
30
|
def volumes_dir
|
@@ -51,38 +51,16 @@ end
|
|
51
51
|
|
52
52
|
When(/^I wrap the App$/) do
|
53
53
|
cmd = "wrapp '#{@app.app_path}'"
|
54
|
-
run_simple(
|
55
|
-
end
|
56
|
-
|
57
|
-
When(/^I wrap the App including the parent directory$/) do
|
58
|
-
cmd = "wrapp --include-parent-dir '#{@app.app_path}'"
|
59
|
-
run_simple(unescape(cmd))
|
60
|
-
end
|
61
|
-
|
62
|
-
When(/^I wrap the App including \/Applications symlink$/) do
|
63
|
-
cmd = "wrapp --add-applications-link '#{@app.app_path}'"
|
64
|
-
run_simple(unescape(cmd))
|
54
|
+
run_simple(sanitize_text(cmd))
|
65
55
|
end
|
66
56
|
|
67
57
|
Then(/^the App should be wrapped$/) do
|
68
58
|
attach_dmg
|
69
59
|
attached_app_path = File.join(volumes_dir, @app.app_name)
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
Then(/^the App should be wrapped including the parent directory$/) do
|
74
|
-
attach_dmg
|
75
|
-
attached_app_path = File.join(volumes_dir, @app.prefix)
|
76
|
-
check_directory_presence([attached_app_path], true)
|
77
|
-
end
|
78
|
-
|
79
|
-
Then(/^the app should be wrapped including the \/Applications symlink$/) do
|
80
|
-
attach_dmg
|
81
|
-
attached_app_path = File.join(volumes_dir, @app.app_name)
|
82
|
-
check_directory_presence([File.join(attached_app_path, 'Applications')], true)
|
60
|
+
expect(attached_app_path).to be_an_existing_directory
|
83
61
|
end
|
84
62
|
|
85
63
|
Then(/^I should see usage instructions$/) do
|
86
64
|
expected = "Usage: wrapp [options] APP_PATH"
|
87
|
-
|
65
|
+
expect(last_command_stopped).to have_output an_output_string_including(expected)
|
88
66
|
end
|
data/features/wrap_app.feature
CHANGED
@@ -4,22 +4,11 @@ Feature: Wrap App
|
|
4
4
|
As as user
|
5
5
|
I want wrap my App in a DMG
|
6
6
|
|
7
|
-
@announce
|
8
7
|
Scenario: Wrap App
|
9
8
|
Given an App
|
10
9
|
When I wrap the App
|
11
10
|
Then the App should be wrapped
|
12
11
|
|
13
|
-
Scenario: Wrap App including the parent directory
|
14
|
-
Given an App in a directory
|
15
|
-
When I wrap the App including the parent directory
|
16
|
-
Then the App should be wrapped including the parent directory
|
17
|
-
|
18
|
-
Scenario: Wrap App including the /Applications symlink
|
19
|
-
Given an App
|
20
|
-
When I wrap the App including /Applications symlink
|
21
|
-
Then the app should be wrapped including the /Applications symlink
|
22
|
-
|
23
12
|
Scenario: Display usage
|
24
13
|
When I run `wrapp`
|
25
14
|
Then I should see usage instructions
|
data/lib/wrapp/app_info.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Wrapp
|
2
2
|
class AppInfo
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :path
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(path)
|
6
|
+
@path = path
|
7
7
|
end
|
8
8
|
|
9
9
|
def full_name
|
@@ -24,5 +24,11 @@ module Wrapp
|
|
24
24
|
raise "Error reading #{property} from #{plist}" unless $?.success?
|
25
25
|
output.strip
|
26
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def plist
|
31
|
+
File.join(path, 'Contents', 'Info.plist')
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
data/lib/wrapp/cli.rb
CHANGED
@@ -4,26 +4,14 @@ module Wrapp
|
|
4
4
|
|
5
5
|
banner "Usage: #{File.basename($0)} [options] APP_PATH"
|
6
6
|
|
7
|
-
option :include_parent_dir,
|
8
|
-
:long => '--include-parent-dir',
|
9
|
-
:short => '-i',
|
10
|
-
:description => "Include the App's parent directory in the DMG with all(!!!) content.",
|
11
|
-
:boolean => true
|
12
|
-
option :add_applications_link,
|
13
|
-
:long => '--add-applications-link',
|
14
|
-
:short => '-l',
|
15
|
-
:description => 'Add /Applications symlink to the DMG.',
|
16
|
-
:boolean => true,
|
17
|
-
:default => true
|
18
7
|
option :filesystem,
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:default => 'HFS+'
|
8
|
+
long: '--filesystem FILESYSTEM',
|
9
|
+
short: '-f FILESYSTEM',
|
10
|
+
description: 'Causes a filesystem of the specified type to be written to the image.'
|
23
11
|
option :volume_name,
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
12
|
+
long: '--volume-name NAME',
|
13
|
+
short: '-n NAME',
|
14
|
+
description: 'Volume name of the newly created filesystem.'
|
27
15
|
|
28
16
|
class << self
|
29
17
|
def run
|
data/lib/wrapp/dmg_builder.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
require 'tmpdir'
|
2
|
-
|
3
1
|
module Wrapp
|
4
2
|
class DMGBuilder
|
5
|
-
|
3
|
+
DEFAULT_FILESYSTEM = 'HFS+'
|
6
4
|
|
7
5
|
attr_reader :app_path
|
8
6
|
|
@@ -12,59 +10,34 @@ module Wrapp
|
|
12
10
|
end
|
13
11
|
|
14
12
|
def create
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
cmd = %w(hdiutil create)
|
23
|
-
cmd << "-srcfolder '#{dir}'"
|
24
|
-
# NOTE: There is a known bug in hdiutil that causes the image creation
|
25
|
-
# to fail, see: https://discussions.apple.com/thread/5667409
|
26
|
-
# Therefore we have to explicitely set the dmg size for bigger sources.
|
27
|
-
cmd << "-megabytes #{dmg_size}" if big_source_folder?
|
28
|
-
cmd << "'#{dmg_filename}'"
|
29
|
-
system(cmd.join(' '))
|
30
|
-
}
|
13
|
+
cmd = %w(hdiutil create)
|
14
|
+
cmd << "-srcfolder '#{app_path}'"
|
15
|
+
cmd << "-fs '#{filesystem}'"
|
16
|
+
cmd << "-volname '#{volume_name}'"
|
17
|
+
cmd << "'#{dmg_filename}'"
|
18
|
+
system(cmd.join(' '))
|
31
19
|
end
|
32
20
|
|
33
|
-
|
34
|
-
|
35
|
-
def source_path
|
36
|
-
@opts[:include_parent_dir] ? File.dirname(app_path) : app_path
|
21
|
+
def filesystem
|
22
|
+
@opts.fetch(:filesystem) { DEFAULT_FILESYSTEM }
|
37
23
|
end
|
38
24
|
|
39
|
-
|
40
|
-
|
41
|
-
folder_size >= BIG_SOURCE_FOLDER_SIZE
|
25
|
+
def volume_name
|
26
|
+
@opts.fetch(:volume_name) { app.name }
|
42
27
|
end
|
43
28
|
|
44
|
-
|
45
|
-
def dmg_size
|
46
|
-
(folder_size * 1.1).to_i # Source folder + 10% buffer.
|
47
|
-
end
|
29
|
+
private
|
48
30
|
|
49
|
-
#
|
50
|
-
|
51
|
-
|
52
|
-
end
|
31
|
+
#def source_path
|
32
|
+
#@opts[:include_parent_dir] ? File.dirname(app_path) : app_path
|
33
|
+
#end
|
53
34
|
|
54
35
|
def dmg_filename
|
55
36
|
"#{app.full_name}.dmg"
|
56
37
|
end
|
57
38
|
|
58
|
-
def vol_name
|
59
|
-
@opts[:volume_name] ? @opts[:volume_name] : app.name
|
60
|
-
end
|
61
|
-
|
62
39
|
def app
|
63
|
-
@app_info ||= AppInfo.new(
|
64
|
-
end
|
65
|
-
|
66
|
-
def plist
|
67
|
-
File.join(app_path, 'Contents', 'Info.plist')
|
40
|
+
@app_info ||= AppInfo.new(app_path)
|
68
41
|
end
|
69
42
|
end
|
70
43
|
end
|
data/lib/wrapp/version.rb
CHANGED
data/spec/wrapp/app_info_spec.rb
CHANGED
@@ -2,56 +2,62 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Wrapp
|
4
4
|
describe AppInfo do
|
5
|
-
let(:
|
5
|
+
let(:path) { '/Applications/Chunky Bacon.app' }
|
6
|
+
subject { AppInfo.new(path) }
|
6
7
|
|
7
8
|
before do
|
8
|
-
|
9
|
+
allow(subject).to receive(:`) { '' }
|
9
10
|
end
|
10
11
|
|
11
12
|
describe '#full_name' do
|
12
13
|
it 'includes the downcased name and version without spaces' do
|
13
|
-
|
14
|
-
|
15
|
-
expect(
|
14
|
+
allow(subject).to receive(:name) { "Chunky\t Bacon" }
|
15
|
+
allow(subject).to receive(:version) { '1.2.3' }
|
16
|
+
expect(subject.full_name).to eq('chunky_bacon_1.2.3')
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
20
|
describe '#name' do
|
20
21
|
it 'returns the app name' do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
expect(app.name).to eq('Chunky Bacon')
|
22
|
+
allow(subject).to receive(:get_property) { 'Chunky Bacon' }
|
23
|
+
expect(subject.name).to eq('Chunky Bacon')
|
24
|
+
expect(subject).to have_received(:get_property).with('CFBundleName')
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
describe '#version' do
|
29
29
|
it 'returns the app version' do
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
allow(subject).to receive(:get_property) { '0.4.2' }
|
31
|
+
expect(subject.version).to eq('0.4.2')
|
32
|
+
expect(subject).to have_received(:get_property).
|
33
|
+
with('CFBundleShortVersionString')
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
describe '#get_property' do
|
38
38
|
it 'retrieves the property by PlistBuddy' do
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
allow(subject).to receive(:`) { '' }
|
40
|
+
subject.get_property('foo')
|
41
|
+
expect(subject).to have_received(:`).
|
42
|
+
with("/usr/libexec/PlistBuddy -c 'Print :foo' '/Applications/Chunky Bacon.app/Contents/Info.plist'")
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'strips the output' do
|
46
|
-
|
47
|
-
expect(
|
46
|
+
allow(subject).to receive(:`) { "Chunky\n" }
|
47
|
+
expect(subject.get_property(nil)).to eq('Chunky')
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'raises when plistbuddy exists non-zero' do
|
51
|
-
|
51
|
+
allow(subject).to receive(:`) { system('false'); '' }
|
52
52
|
expect {
|
53
|
-
|
54
|
-
}.to raise_error /error reading foo
|
53
|
+
subject.get_property('Foo')
|
54
|
+
}.to raise_error /error reading foo/i
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#plist' do
|
59
|
+
it 'returns the app info plist path' do
|
60
|
+
expect(subject.send(:plist)).to eq('/Applications/Chunky Bacon.app/Contents/Info.plist')
|
55
61
|
end
|
56
62
|
end
|
57
63
|
end
|
@@ -2,123 +2,67 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Wrapp
|
4
4
|
describe DMGBuilder do
|
5
|
-
|
5
|
+
subject { DMGBuilder.new('Chunky Bacon.app') }
|
6
6
|
let(:app) { double('app') }
|
7
7
|
|
8
8
|
before do
|
9
|
-
|
9
|
+
allow(app).to receive(:name) { 'Chunky Bacon' }
|
10
|
+
allow_any_instance_of(DMGBuilder).to receive(:system)
|
10
11
|
end
|
11
12
|
|
12
13
|
describe '#create' do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dmg.stub(:big_source_folder?).and_return(true)
|
21
|
-
dmg.stub(:dmg_size).and_return(123)
|
22
|
-
dmg.should_receive(:system).
|
23
|
-
with("hdiutil create -srcfolder 'Chunky.app' -megabytes 123 'bacon.dmg'")
|
24
|
-
dmg.create
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'with small source folder' do
|
29
|
-
it 'creates a dmg with automatic size' do
|
30
|
-
dmg.stub(:big_source_folder?).and_return(false)
|
31
|
-
dmg.should_receive(:system).
|
32
|
-
with("hdiutil create -srcfolder 'Chunky.app' 'bacon.dmg'")
|
33
|
-
dmg.create
|
34
|
-
end
|
14
|
+
it 'creates dmg with hdiutil' do
|
15
|
+
allow(subject).to receive(:dmg_filename) { 'bacon.dmg' }
|
16
|
+
allow(subject).to receive(:volume_name) { 'Chunky' }
|
17
|
+
allow(subject).to receive(:system)
|
18
|
+
subject.create
|
19
|
+
expect(subject).to have_received(:system).with(
|
20
|
+
"hdiutil create -srcfolder 'Chunky Bacon.app' -fs 'HFS+' -volname 'Chunky' 'bacon.dmg'")
|
35
21
|
end
|
36
22
|
end
|
37
23
|
|
38
24
|
describe '#app_path' do
|
39
25
|
it 'returns the app path' do
|
40
|
-
expect(
|
26
|
+
expect(subject.app_path).to eq('Chunky Bacon.app')
|
41
27
|
end
|
42
28
|
end
|
43
29
|
|
44
|
-
describe '#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
it 'returns the path of the app dir' do
|
50
|
-
expect(dmg.send(:source_path)).to eq('Chunky/Bacon.app')
|
51
|
-
end
|
52
|
-
|
53
|
-
context 'with :include_parent_dir => true' do
|
54
|
-
let(:dmg) { DMGBuilder.new('...', :include_parent_dir => true) }
|
55
|
-
|
56
|
-
it 'returns the path of the app parent dir' do
|
57
|
-
expect(dmg.send(:source_path)).to eq('Chunky')
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe '#big_source_folder?' do
|
63
|
-
it 'is true with source folder >= 100MB' do
|
64
|
-
dmg.stub(:folder_size).and_return(100)
|
65
|
-
expect(dmg.send(:big_source_folder?)).to be true
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'is false with source folder < 100MB' do
|
69
|
-
dmg.stub(:folder_size).and_return(99)
|
70
|
-
expect(dmg.send(:big_source_folder?)).to be false
|
30
|
+
describe '#dmg_filename' do
|
31
|
+
it 'includes the full app name' do
|
32
|
+
allow(app).to receive(:full_name) { 'chunky_bacon_0.4.2' }
|
33
|
+
allow(subject).to receive(:app) { app }
|
34
|
+
expect(subject.send(:dmg_filename)).to eq('chunky_bacon_0.4.2.dmg')
|
71
35
|
end
|
72
36
|
end
|
73
37
|
|
74
|
-
describe '#
|
75
|
-
|
76
|
-
|
77
|
-
expect(dmg.send(:dmg_size)).to eq(110)
|
78
|
-
end
|
79
|
-
end
|
38
|
+
describe '#volume_name' do
|
39
|
+
context 'with option :volume_name' do
|
40
|
+
subject { DMGBuilder.new('...', volume_name: 'Hi') }
|
80
41
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
dmg.should_receive(:`).with("du -ms '/chunky/bacon'").and_return('')
|
85
|
-
dmg.send(:folder_size)
|
42
|
+
it 'returns volume name from option' do
|
43
|
+
expect(subject.volume_name).to eq 'Hi'
|
44
|
+
end
|
86
45
|
end
|
87
46
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
expect(dmg.send(:folder_size)).to eq(100)
|
92
|
-
end
|
93
|
-
end
|
47
|
+
context 'without option :volume_name' do
|
48
|
+
subject { DMGBuilder.new('...') }
|
49
|
+
let(:app) { double('app') }
|
94
50
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
expect(dmg.send(:dmg_filename)).to eq('chunky_bacon_0.4.2.dmg')
|
100
|
-
end
|
101
|
-
end
|
51
|
+
before do
|
52
|
+
allow(app).to receive(:name) { 'Hello' }
|
53
|
+
allow(subject).to receive(:app) { app }
|
54
|
+
end
|
102
55
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
dmg.stub(:app).and_return(app)
|
107
|
-
expect(dmg.send(:vol_name)).to eq('chunky_bacon')
|
56
|
+
it 'returns application name' do
|
57
|
+
expect(subject.volume_name).to eq 'Hello'
|
58
|
+
end
|
108
59
|
end
|
109
60
|
end
|
110
61
|
|
111
62
|
describe '#app' do
|
112
63
|
it 'creates a cached app_info instance' do
|
113
|
-
|
114
|
-
|
115
|
-
expect(dmg.send(:app)).to eq(app)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
describe '#plist' do
|
120
|
-
it 'returns the app info plist path' do
|
121
|
-
expect(dmg.send(:plist)).to eq('Chunky Bacon.app/Contents/Info.plist')
|
64
|
+
allow(AppInfo).to receive(:new).with('Chunky Bacon.app') { app }
|
65
|
+
expect(subject.send(:app)).to eq(app)
|
122
66
|
end
|
123
67
|
end
|
124
68
|
end
|
data/wrapp.gemspec
CHANGED
@@ -22,8 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
24
24
|
spec.add_development_dependency 'rake'
|
25
|
-
spec.add_development_dependency '
|
26
|
-
spec.add_development_dependency '
|
27
|
-
spec.add_development_dependency 'guard-rspec'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
|
+
spec.add_development_dependency 'cucumber', '~> 3.0'
|
28
27
|
spec.add_development_dependency 'aruba'
|
29
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wrapp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Björn Albers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixlib-cli
|
@@ -53,47 +53,33 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - '>='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: guard-cucumber
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - '>='
|
59
|
+
- - ~>
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
61
|
+
version: '3.0'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- -
|
66
|
+
- - ~>
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
68
|
+
version: '3.0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
70
|
+
name: cucumber
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
|
-
- -
|
73
|
+
- - ~>
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
75
|
+
version: '3.0'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
|
-
- -
|
80
|
+
- - ~>
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
82
|
+
version: '3.0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: aruba
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,6 +103,7 @@ extensions: []
|
|
117
103
|
extra_rdoc_files: []
|
118
104
|
files:
|
119
105
|
- .gitignore
|
106
|
+
- .travis.yml
|
120
107
|
- Gemfile
|
121
108
|
- Guardfile
|
122
109
|
- LICENSE.txt
|
@@ -134,7 +121,6 @@ files:
|
|
134
121
|
- lib/wrapp/version.rb
|
135
122
|
- spec/spec_helper.rb
|
136
123
|
- spec/wrapp/app_info_spec.rb
|
137
|
-
- spec/wrapp/cli_spec.rb
|
138
124
|
- spec/wrapp/dmg_builder_spec.rb
|
139
125
|
- wrapp.gemspec
|
140
126
|
homepage: https://github.com/bjoernalbers/wrapp
|
@@ -160,7 +146,7 @@ rubyforge_project:
|
|
160
146
|
rubygems_version: 2.6.10
|
161
147
|
signing_key:
|
162
148
|
specification_version: 4
|
163
|
-
summary: wrapp-0.
|
149
|
+
summary: wrapp-1.0.0
|
164
150
|
test_files:
|
165
151
|
- features/step_definitions/wrapp_steps.rb
|
166
152
|
- features/support/app.rb
|
@@ -168,5 +154,4 @@ test_files:
|
|
168
154
|
- features/wrap_app.feature
|
169
155
|
- spec/spec_helper.rb
|
170
156
|
- spec/wrapp/app_info_spec.rb
|
171
|
-
- spec/wrapp/cli_spec.rb
|
172
157
|
- spec/wrapp/dmg_builder_spec.rb
|
data/spec/wrapp/cli_spec.rb
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Wrapp
|
4
|
-
describe CLI do
|
5
|
-
let(:cli) { CLI.new }
|
6
|
-
let(:app_path) { '/Applications/Chunky Bacon.app' }
|
7
|
-
|
8
|
-
it 'include usage instructions in the banner' do
|
9
|
-
expect(CLI.banner).to match(/^usage: \w+ \[options\] \w+$/i)
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '.run' do
|
13
|
-
it 'runs an instance with ARGV' do
|
14
|
-
cli.should_receive(:run).with(ARGV)
|
15
|
-
CLI.stub(:new).and_return(cli)
|
16
|
-
CLI.run
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'without arguments' do
|
20
|
-
let(:argv) { [] }
|
21
|
-
|
22
|
-
before do
|
23
|
-
cli.stub(:warn)
|
24
|
-
cli.stub(:puts)
|
25
|
-
cli.stub(:exit)
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'exits non-zero' do
|
29
|
-
cli.should_receive(:exit).with(2)
|
30
|
-
cli.run(argv)
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'displays usage on stdout' do
|
34
|
-
cli.should_receive(:opt_parser).and_return('usage')
|
35
|
-
cli.should_receive(:puts).with('usage')
|
36
|
-
cli.run(argv)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'displays what is missing on stderr' do
|
40
|
-
cli.should_receive(:warn).with('ERROR: App path is missing!')
|
41
|
-
cli.run(argv)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe '#run' do
|
47
|
-
let(:argv) { [app_path] }
|
48
|
-
|
49
|
-
it 'wraps the app' do
|
50
|
-
cli.should_receive(:wrapp).with(app_path, {})
|
51
|
-
cli.run(argv)
|
52
|
-
end
|
53
|
-
|
54
|
-
%w(--include-parent-dir -i).each do |opt|
|
55
|
-
context "with #{opt}" do
|
56
|
-
let(:argv) { [app_path, opt] }
|
57
|
-
|
58
|
-
it 'wraps the app including the parent directory' do
|
59
|
-
cli.should_receive(:wrapp).
|
60
|
-
with(app_path, :include_parent_dir => true)
|
61
|
-
cli.run(argv)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
%w(--filesystem -fs).each do |opt|
|
67
|
-
context "with #{opt}" do
|
68
|
-
let(:argv) { [app_path, opt] }
|
69
|
-
|
70
|
-
it 'specifies the filesystem type' do
|
71
|
-
cli.should_receive(:wrapp)
|
72
|
-
.with(app_path, :filesystem => 'HFS+')
|
73
|
-
cli.run(argv)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
%w(--volume-name -n).each do |opt|
|
79
|
-
context "with #{opt}" do
|
80
|
-
let(:argv) { [app_path, opt] }
|
81
|
-
|
82
|
-
if 'specifies the volume name' do
|
83
|
-
cli.should_receive(:wrapp)
|
84
|
-
.with(app_path, :volume_name => '')
|
85
|
-
cli.run(argv)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe '#wrapp' do
|
92
|
-
it 'creates the dmg via dmg builder' do
|
93
|
-
opts = %(some options and arguments)
|
94
|
-
dmg = double('dmg_builder')
|
95
|
-
dmg.should_receive(:create)
|
96
|
-
DMGBuilder.should_receive(:new).with(*opts).and_return(dmg)
|
97
|
-
cli.wrapp(*opts)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|