xcodeproject_swift 0.3.13
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 +7 -0
- data/.gitignore +30 -0
- data/.rspec +2 -0
- data/.rubocop.yml +37 -0
- data/.travis.yml +13 -0
- data/.yardopts +7 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +192 -0
- data/Rakefile +11 -0
- data/lib/xcodeproject.rb +2 -0
- data/lib/xcodeproject/build_phase_node.rb +111 -0
- data/lib/xcodeproject/data.rb +89 -0
- data/lib/xcodeproject/exceptions.rb +29 -0
- data/lib/xcodeproject/extend/array.rb +32 -0
- data/lib/xcodeproject/extend/hash.rb +35 -0
- data/lib/xcodeproject/extend/string.rb +31 -0
- data/lib/xcodeproject/file_node.rb +86 -0
- data/lib/xcodeproject/formatter.rb +47 -0
- data/lib/xcodeproject/node.rb +42 -0
- data/lib/xcodeproject/pbx_build_file.rb +63 -0
- data/lib/xcodeproject/pbx_file_reference.rb +82 -0
- data/lib/xcodeproject/pbx_group.rb +204 -0
- data/lib/xcodeproject/pbx_native_target.rb +94 -0
- data/lib/xcodeproject/pbx_project.rb +57 -0
- data/lib/xcodeproject/project.rb +72 -0
- data/lib/xcodeproject/root_node.rb +127 -0
- data/lib/xcodeproject/tasks/build_task.rb +59 -0
- data/lib/xcodeproject/uuid_generator.rb +37 -0
- data/lib/xcodeproject/version.rb +27 -0
- data/lib/xcodeproject/xc_build_configuration.rb +98 -0
- data/lib/xcodeproject/xc_configuration_list.rb +47 -0
- data/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-a.h +1 -0
- data/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-a.m +1 -0
- data/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-r.h +1 -0
- data/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-r.m +1 -0
- data/resources/example/dir1b/dir2b/file3b.m +0 -0
- data/resources/example/dir1b/file2b.m +0 -0
- data/resources/example/dir1c/file2c.h +0 -0
- data/resources/example/dir1c/file2c.m +0 -0
- data/resources/example/example.xcodeproj/project.pbxproj +324 -0
- data/resources/example/example/AppDelegate.h +7 -0
- data/resources/example/example/AppDelegate.m +49 -0
- data/resources/example/example/en.lproj/InfoPlist.strings +2 -0
- data/resources/example/example/example-Info.plist +45 -0
- data/resources/example/example/example-Prefix.pch +14 -0
- data/resources/example/example/main.m +10 -0
- data/spec/build_phase_node_spec.rb +103 -0
- data/spec/file_node_spec.rb +58 -0
- data/spec/pbx_build_file_spec.rb +26 -0
- data/spec/pbx_file_reference_spec.rb +42 -0
- data/spec/pbx_group_spec.rb +360 -0
- data/spec/pbx_native_target_spec.rb +62 -0
- data/spec/pbx_project_spec.rb +39 -0
- data/spec/project_spec.rb +86 -0
- data/spec/spec_helper.rb +67 -0
- data/spec/support/shared_examples/file_node_shared_examples.rb +27 -0
- data/spec/xc_build_configuration_spec.rb +114 -0
- data/spec/xc_configuration_list_spec.rb +23 -0
- data/xcodeproject.gemspec +29 -0
- metadata +233 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe XcodeProject::PBXNativeTarget do
|
4
|
+
let(:obj) { @data.target('example') }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@data = prepare_example_project.read
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#sources' do
|
11
|
+
it '=> PBXSourcesBuildPhase#files' do
|
12
|
+
files = mock
|
13
|
+
mock(obj).sources_build_phase.mock!.files do files end
|
14
|
+
expect(obj.sources).to eql(files)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#add_source' do
|
19
|
+
it '=> PBXSourcesBuildPhase#add_file' do
|
20
|
+
file = mock
|
21
|
+
mock(obj).sources_build_phase.mock!.add_file(file)
|
22
|
+
obj.add_source(file)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#remove_source' do
|
27
|
+
it '=> PBXSourcesBuildPhase#remove_file' do
|
28
|
+
file = mock
|
29
|
+
mock(obj).sources_build_phase.mock!.remove_file(file)
|
30
|
+
obj.remove_source(file)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#build_configurations_list' do
|
35
|
+
it 'returns the build configuration list object' do
|
36
|
+
expect(obj.build_configurations_list).to be_a(XcodeProject::XCConfigurationList)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#configs' do
|
41
|
+
it '=> XCConfigurationList#build_configurations' do
|
42
|
+
res = mock
|
43
|
+
mock(obj).build_configurations_list.mock!.build_configurations do res end
|
44
|
+
expect(obj.configs).to eql(res)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#config' do
|
49
|
+
it '=> XCConfigurationList#build_configuration' do
|
50
|
+
name = mock
|
51
|
+
res = mock
|
52
|
+
mock(obj).build_configurations_list.mock!.build_configuration(name) do res end
|
53
|
+
expect(obj.config(name)).to eql(res)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#build_phases' do
|
58
|
+
it 'returns the array of build phase objects' do
|
59
|
+
expect(obj.build_phases).to be_a(Array)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe XcodeProject::PBXProject do
|
4
|
+
let(:obj) { @data.project }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@data = prepare_example_project.read
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#targets' do
|
11
|
+
it 'returns the array of target objects' do
|
12
|
+
targets = obj.targets
|
13
|
+
expect(targets).to be_a(Array)
|
14
|
+
targets.each do |obj|
|
15
|
+
expect(obj).to be_a(XcodeProject::PBXNativeTarget)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#target' do
|
21
|
+
context 'if the target exists' do
|
22
|
+
it 'returns the object' do
|
23
|
+
expect(obj.target('example')).to be_a(XcodeProject::PBXNativeTarget)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'if the target doesn\'t exist' do
|
28
|
+
it 'returns nil' do
|
29
|
+
expect(obj.target('ghost-target')).to be_nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#main_group' do
|
35
|
+
it 'returns the main group object' do
|
36
|
+
expect(obj.main_group).to be_a(XcodeProject::PBXGroup)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe XcodeProject::Project do
|
4
|
+
let(:proj) { prepare_example_project }
|
5
|
+
|
6
|
+
describe '#new' do
|
7
|
+
context 'if the project file exists' do
|
8
|
+
it 'constructs an project object' do
|
9
|
+
expect(XcodeProject::Project.new(example_project_bundle_path)).to be_a(XcodeProject::Project)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'if the project file doesn\'t exist' do
|
14
|
+
let(:proj_ne) { "#{example_empty_sandbox_path}/ghost.xcodeproj" }
|
15
|
+
it 'throws the exception' do
|
16
|
+
expect { XcodeProject::Project.new(proj_ne) }.to raise_exception(XcodeProject::FilePathError)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#file_path' do
|
22
|
+
it 'returns the project\'s file path' do
|
23
|
+
expect(proj.file_path).to eql(example_project_file_path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#bundle_path' do
|
28
|
+
it 'returns the project\'s bundle path' do
|
29
|
+
expect(proj.bundle_path).to eql(example_project_bundle_path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#find' do
|
34
|
+
context 'if a specified directory contains project files' do
|
35
|
+
it 'returns an array of project objects' do
|
36
|
+
projs = XcodeProject::Project.find(example_project_bundle_path)
|
37
|
+
expect(projs.size).to eql(1)
|
38
|
+
expect(projs.first.bundle_path).to eql(proj.bundle_path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'if a specified directory pattern contains project files' do
|
43
|
+
it 'returns an array of project objects' do
|
44
|
+
projs = XcodeProject::Project.find("#{example_sandbox_path}/*")
|
45
|
+
expect(projs.size).to eql(1)
|
46
|
+
expect(projs.first.bundle_path).to eql(proj.bundle_path)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'if a specified directory doesn\'t contain project files' do
|
51
|
+
it 'returns an empty array' do
|
52
|
+
projs = XcodeProject::Project.find(example_empty_sandbox_path)
|
53
|
+
expect(projs.size).to eql(0)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#read' do
|
59
|
+
it 'returns the data object' do
|
60
|
+
expect(proj.read).to be_a(XcodeProject::Data)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'reads the project file' do
|
64
|
+
mock.proxy(proj).file_path
|
65
|
+
proj.read
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#write' do
|
70
|
+
it 'writes the project file' do
|
71
|
+
data = proj.read
|
72
|
+
|
73
|
+
mock.proxy(proj).file_path
|
74
|
+
proj.write(data)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#change' do
|
79
|
+
it 'reads the file file and then writes it' do
|
80
|
+
proj_mock = mock.proxy(proj)
|
81
|
+
proj_mock.read
|
82
|
+
proj_mock.write(is_a(XcodeProject::Data))
|
83
|
+
proj.change { |_data| }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
require 'rr'
|
9
|
+
require_relative '../lib/xcodeproject/project'
|
10
|
+
require_relative '../lib/xcodeproject/exceptions'
|
11
|
+
require_relative 'support/shared_examples/file_node_shared_examples'
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.run_all_when_everything_filtered = true
|
15
|
+
config.filter_run :focus
|
16
|
+
config.mock_with :rr
|
17
|
+
end
|
18
|
+
|
19
|
+
# Example project file hierarhy
|
20
|
+
#
|
21
|
+
# main
|
22
|
+
# \--group1a
|
23
|
+
# |--group2a
|
24
|
+
# |--dir2c
|
25
|
+
# | \--dir3a
|
26
|
+
# | \--dir4a
|
27
|
+
# | |--file5a-a.m
|
28
|
+
# | |--file5a-a.h
|
29
|
+
# | |--file5a-r.m
|
30
|
+
# | \--file5a-r.h
|
31
|
+
# |
|
32
|
+
# |--file2c.m
|
33
|
+
# \--file2c.h
|
34
|
+
|
35
|
+
def prepare_sandbox
|
36
|
+
` mkdir -p #{example_sandbox_path} ` unless File.exist?(example_sandbox_path)
|
37
|
+
end
|
38
|
+
|
39
|
+
def prepare_example_project
|
40
|
+
prepare_sandbox
|
41
|
+
|
42
|
+
proj_source_dir = "#{File.dirname(__FILE__)}/../resources/example"
|
43
|
+
` rm -vr #{example_project_dir} `
|
44
|
+
` cp -vr #{proj_source_dir} #{example_sandbox_path} `
|
45
|
+
|
46
|
+
XcodeProject::Project.new(example_project_bundle_path)
|
47
|
+
end
|
48
|
+
|
49
|
+
def example_sandbox_path
|
50
|
+
Pathname.new('/tmp/example_sandbox')
|
51
|
+
end
|
52
|
+
|
53
|
+
def example_empty_sandbox_path
|
54
|
+
Pathname.new('/tmp/example_sandbox_empty')
|
55
|
+
end
|
56
|
+
|
57
|
+
def example_project_dir
|
58
|
+
example_sandbox_path.join('example')
|
59
|
+
end
|
60
|
+
|
61
|
+
def example_project_bundle_path
|
62
|
+
example_project_dir.join('example.xcodeproj')
|
63
|
+
end
|
64
|
+
|
65
|
+
def example_project_file_path
|
66
|
+
example_project_bundle_path.join('project.pbxproj')
|
67
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
shared_examples 'a file node' do
|
2
|
+
describe '#parent' do
|
3
|
+
context 'if the object is nested file node' do
|
4
|
+
it 'returns the parent object' do
|
5
|
+
file_nodes_gpaths do |gpath|
|
6
|
+
expect(main_group.child(gpath).parent).to be_a(XcodeProject::PBXGroup)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#group_path' do
|
13
|
+
it 'returns the abstract path from project main group' do
|
14
|
+
expect(file_nodes_gpaths.map { |gpath|
|
15
|
+
main_group.child(gpath).group_path
|
16
|
+
}).to eql(file_nodes_gpaths.map { |gpath| Pathname.new(gpath) })
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#total_path' do
|
21
|
+
it 'returns the absolute file path' do
|
22
|
+
expect(file_nodes_gpaths.map { |gpath|
|
23
|
+
main_group.child(gpath).total_path
|
24
|
+
}).to eql(file_nodes_total_paths.map { |gpath| Pathname.new(gpath) })
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe XcodeProject::XCBuildConfiguration do
|
4
|
+
let(:obj) { @data.target('example').config('Release') }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@data = prepare_example_project.read
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#plist_path' do
|
11
|
+
it 'returns plist file path' do
|
12
|
+
expect(obj.send(:plist_path)).to eql(example_project_dir.join('example/example-Info.plist'))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#version' do
|
17
|
+
context 'by default' do
|
18
|
+
it 'returns major version' do
|
19
|
+
expect(obj.version).to eql(obj.version(:major))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'if passed :major' do
|
24
|
+
it 'returns major version' do
|
25
|
+
expect(obj.version(:major)).to eql('1.0')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'if passed :minor' do
|
30
|
+
it 'returns minor version' do
|
31
|
+
expect(obj.version(:minor)).to eql('345')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'if passed :both' do
|
36
|
+
it 'returns both, major and minor versions' do
|
37
|
+
expect(obj.version(:both)).to eql('1.0.345')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#change_version' do
|
43
|
+
let(:version) { '2.0' }
|
44
|
+
|
45
|
+
context 'by default' do
|
46
|
+
it 'changes major version' do
|
47
|
+
obj.change_version(version)
|
48
|
+
expect(obj.version(:major)).to eql(version)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'if passed :major' do
|
53
|
+
it 'changes major version' do
|
54
|
+
obj.change_version(version, :major)
|
55
|
+
expect(obj.version(:major)).to eql(version)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'if passed :minor' do
|
60
|
+
it 'changes minor version' do
|
61
|
+
obj.change_version(version, :minor)
|
62
|
+
expect(obj.version(:minor)).to eql(version)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#increment_version' do
|
68
|
+
context 'by default' do
|
69
|
+
let(:next_version) { '1.1' }
|
70
|
+
|
71
|
+
it 'increments major version' do
|
72
|
+
obj.increment_version
|
73
|
+
expect(obj.version(:major)).to eql(next_version)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'if passed :major' do
|
78
|
+
let(:next_version) { '1.1' }
|
79
|
+
|
80
|
+
it 'increments major version' do
|
81
|
+
obj.increment_version(:major)
|
82
|
+
expect(obj.version(:major)).to eql(next_version)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'if passed :minor' do
|
87
|
+
let(:next_version) { '346' }
|
88
|
+
|
89
|
+
it 'increments minor version' do
|
90
|
+
obj.increment_version(:minor)
|
91
|
+
expect(obj.version(:minor)).to eql(next_version)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#read_property' do
|
97
|
+
let(:key) { 'CFBundleShortVersionString' }
|
98
|
+
let(:value) { '1.0' }
|
99
|
+
|
100
|
+
it 'read a property by key from plist file' do
|
101
|
+
expect(obj.send(:read_property, key)).to eql(value)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#write_property' do
|
106
|
+
let(:key) { 'CFBundleShortVersionString' }
|
107
|
+
let(:value) { '1.1' }
|
108
|
+
|
109
|
+
it 'write value by key to plist file' do
|
110
|
+
obj.send(:write_property, key, value)
|
111
|
+
expect(obj.send(:read_property, key)).to eql(value)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe XcodeProject::XCConfigurationList do
|
4
|
+
let(:obj) { @data.target('example').build_configurations_list }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@data = prepare_example_project.read
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#build_configuration' do
|
11
|
+
let(:name) { 'Release' }
|
12
|
+
|
13
|
+
it 'returns build configuration object' do
|
14
|
+
expect(obj.build_configuration(name)).to be_a(XcodeProject::XCBuildConfiguration)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#build_configurations' do
|
19
|
+
it 'returns an array of build configuration objects' do
|
20
|
+
expect(obj.build_configurations).to be_a(Array)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/xcodeproject/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'xcodeproject_swift'
|
6
|
+
gem.version = XcodeProject::VERSION
|
7
|
+
gem.summary = 'Read, write and build xcode projects'
|
8
|
+
gem.description = 'XcodeProject is the Ruby API for working with Xcode project files'
|
9
|
+
gem.author = 'Andrei Nesterov'
|
10
|
+
gem.email = 'ae.nesterov@gmail.com'
|
11
|
+
gem.homepage = 'https://github.com/manifest/xcodeproject'
|
12
|
+
gem.rubyforge_project = 'xcodeproject'
|
13
|
+
gem.license = 'MIT'
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
|
20
|
+
gem.required_ruby_version = '>= 2.0.0'
|
21
|
+
gem.add_runtime_dependency 'rake', '>= 10.0'
|
22
|
+
gem.add_runtime_dependency 'json', '~> 1.8'
|
23
|
+
gem.add_runtime_dependency 'uuid', '~> 2.3'
|
24
|
+
gem.add_runtime_dependency 'xcodebuild-rb', '~> 0.2.0'
|
25
|
+
gem.add_development_dependency 'rspec', '~> 3.4', '>= 3.4.0'
|
26
|
+
gem.add_development_dependency 'rr', '~> 1.0.4'
|
27
|
+
gem.add_development_dependency 'redcarpet', '~> 2.1.1'
|
28
|
+
gem.add_development_dependency 'yard', '~> 0.8.2'
|
29
|
+
end
|