ambient-xcode 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 98615ee39dc25f247d8064579087ebdf523a796a
4
+ data.tar.gz: 7c0663d987218c7d8426e4957d12000d04ae7c43
5
+ SHA512:
6
+ metadata.gz: c504951669259411ab0d46c4c6423356afd05c913b2078fc0f77d7a9715d377d170e23d0fb7b8d7a50f66e9ea8308d447aa337a6db8819163ae0302c8868d16e
7
+ data.tar.gz: 0b4bf94607805be90413cd7cc3219bfcc5f2f2611be0ee37f8b592447768070113d3fd9276f19f121fa84b8e3f9d87d25a817980f90c25dddc81330e6e2ef8c6
@@ -0,0 +1,59 @@
1
+ Ambient environment for Xcode projects
2
+ ======================================
3
+
4
+ Ambient lets you define all of your xcode project environment settings all in one easy to read Ruby file, and re-apply it to your Xcode project to ensure settings are correct.
5
+
6
+ An `xcconfig` file can be used in order to help abstract your settings away from the main project file. The disadvantage of `xcconfig` files though is that they can still be overridden by settings defined in the project. Ambient doesn't have this issue as it simply overwrites the values in the project file.
7
+
8
+ Installation
9
+ ============
10
+
11
+ Add the following to your `Gemfile`:
12
+ ```
13
+ gem "ambient-xcode", git: "https://github.com/Dan2552/ambient-xcode"
14
+ ```
15
+
16
+ Usage
17
+ =====
18
+
19
+ Create an `Ambientfile` defining your project in the same directory as your `*.xcodeproj` file.
20
+
21
+ Here's an example of the `Ambientfile` structure:
22
+ ```ruby
23
+ enable_warnings_and_static_analyser!
24
+ use_defaults_for_everything_not_specified_in_this_file!
25
+
26
+ option "IPHONEOS_DEPLOYMENT_TARGET", "7.0"
27
+ option "SDKROOT", "iphoneos"
28
+ option "CLANG_ENABLE_OBJC_ARC", true
29
+ option "CLANG_ENABLE_MODULES", true
30
+
31
+ target "MyProject" do
32
+ scheme "Debug" do
33
+ option "PRODUCT_NAME", "Debug"
34
+ option "BUNDLE_DISPLAY_NAME_SUFFIX", "uk.danielgreen.MyProject"
35
+ end
36
+ end
37
+ ```
38
+
39
+ run `ambient` from the command line to write your settings into your project.
40
+
41
+ Notes
42
+ =====
43
+
44
+ - You can re-run `ambient` as many times as possible.
45
+ - Use the `use_defaults_for_everything_not_specified_in_this_file!` setting to ensure your project file is clean. Warning though: this setting will clear all your targets' settings, so be sure to define absolutely every setting in the `Ambientfile` if you want to use this.
46
+ - When defining settings directly within a target, the setting is set to each scheme.
47
+
48
+
49
+ Possible future features
50
+ ========================
51
+
52
+ - Defining capabilities (per target if possible... using `.entitlements` maybe)
53
+ - Helper method to change build phases to default
54
+ - Version number + build number
55
+ - Team ID
56
+ - Provisioning profiles from searching by name rather than storing a uuid (so it actually works across teams)
57
+ - `Info.plist` definitions
58
+ - ?
59
+ - Ability to not have to commit `*.xcodeproj` into version control (maybe too far?)
@@ -0,0 +1,21 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'ambient-xcode'
6
+ gem.version = '0.1.0'
7
+ gem.authors = ['Daniel Green']
8
+ gem.email = ['dan2552@gmail.com']
9
+ gem.description = %q{CLI for configuring Xcode projects from a Ruby file.}
10
+ gem.summary = %q{Define your envrionment settings all in one easy to read Ruby file, and re-apply it to your Xcode project to ensure settings are correct.}
11
+ gem.homepage = 'https://github.com/Dan2552/ambient'
12
+ gem.license = 'MIT'
13
+
14
+ gem.add_dependency 'xcodeproj', '~> 0.25'
15
+ gem.add_dependency 'highline', '~> 1.6'
16
+
17
+ gem.files = `git ls-files`.split($/)
18
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.require_paths = ['lib']
21
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+
4
+ $:.push File.expand_path("../../lib", __FILE__)
5
+
6
+ require 'ambient'
7
+ Ambient.setup_project
@@ -0,0 +1,110 @@
1
+ unless Kernel.respond_to?(:require_relative)
2
+ module Kernel
3
+ def require_relative(path)
4
+ require File.join(File.dirname(caller[0]), path.to_str)
5
+ end
6
+ end
7
+ end
8
+
9
+ require_relative 'project_helper'
10
+ require_relative 'dsl'
11
+
12
+ module Ambient
13
+ extend self
14
+ Ambient::ROOT = File.expand_path('.', File.dirname(__FILE__))
15
+
16
+ @use_defaults = false
17
+ @project_options = {}
18
+ @shared_target_options = {}
19
+ @target_options = {}
20
+ @parents = {}
21
+ def configure(&block)
22
+ instance_eval &block
23
+ end
24
+
25
+ def project_helper
26
+ @project_helper ||= ProjectHelper.new
27
+ end
28
+
29
+ def set_parent_target(target, child, parent)
30
+ @parents[target] ||= {}
31
+ @parents[target][child] = parent
32
+ end
33
+
34
+ def set_option(option, value, target: nil, scheme: nil, parent: nil)
35
+ value = "YES" if value == true
36
+ value = "NO" if value == false
37
+ value = nil if value == :default
38
+
39
+ if target
40
+ if scheme
41
+ @target_options[target] ||= {}
42
+ @target_options[target][scheme] ||= {}
43
+ @target_options[target][scheme][option] = value
44
+ else
45
+ # require 'pry'; binding.pry
46
+ @shared_target_options[target] ||= {}
47
+ @shared_target_options[target][option] = value
48
+ end
49
+ else
50
+ @project_options[option] = value
51
+ end
52
+ end
53
+
54
+ def setup_project
55
+ project_helper.print_info
56
+ reset_project_to_defaults
57
+ reset_targets_to_defaults
58
+ process_project_options
59
+ process_shared_target_options
60
+ process_target_options
61
+ end
62
+
63
+ def reset_project_to_defaults
64
+ if @use_defaults
65
+ puts "resetting project settings to xcode default settings"
66
+ project_helper.reset_project_to_defaults
67
+ end
68
+ end
69
+
70
+ def reset_targets_to_defaults
71
+ if @use_defaults
72
+ puts "resetting target settings to xcode default settings"
73
+ project_helper.reset_targets_to_defaults
74
+ end
75
+ end
76
+
77
+ def process_project_options
78
+ puts "applying ambient project settings"
79
+ project_helper.process_project_options(@project_options)
80
+ end
81
+
82
+ def process_shared_target_options
83
+ puts "applying ambient shared target settings"
84
+ project_helper.process_shared_target_options(@shared_target_options)
85
+ end
86
+
87
+ def process_target_options
88
+ puts "applying ambient target settings"
89
+ load_in_parent_target_values
90
+ project_helper.process_target_options(@target_options)
91
+ end
92
+
93
+ def load_in_parent_target_values
94
+ @parents.each do |target, parents|
95
+ parents.each do |child, parent|
96
+ if parent
97
+ options = @target_options[target]
98
+ child_options = options[child]
99
+ parent_options = options[parent]
100
+ child_options.merge!(parent_options) { |_, child, _| child }
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ ambient = File.join(Dir.pwd, 'Ambientfile')
107
+ raise "ambient not found" unless File.exists?(ambient)
108
+
109
+ load ambient
110
+ end
@@ -0,0 +1,87 @@
1
+ def option(name, value)
2
+ Ambient.configure { set_option(name, value) }
3
+ end
4
+
5
+ def enable_warnings_and_static_analyser!
6
+ warnings = %w(GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED
7
+ GCC_WARN_MISSING_PARENTHESES
8
+ GCC_WARN_ABOUT_RETURN_TYPE
9
+ GCC_WARN_SIGN_COMPARE
10
+ GCC_WARN_CHECK_SWITCH_STATEMENTS
11
+ GCC_WARN_UNUSED_FUNCTION
12
+ GCC_WARN_UNUSED_LABEL
13
+ GCC_WARN_UNUSED_VALUE
14
+ GCC_WARN_UNUSED_VARIABLE
15
+ GCC_WARN_SHADOW
16
+ GCC_WARN_64_TO_32_BIT_CONVERSION
17
+ GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS
18
+ GCC_WARN_UNDECLARED_SELECTOR
19
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF
20
+ GCC_WARN_UNINITIALIZED_AUTOS
21
+ CLANG_WARN_INT_CONVERSION
22
+ CLANG_WARN_ENUM_CONVERSION
23
+ CLANG_WARN_CONSTANT_CONVERSION
24
+ CLANG_WARN_BOOL_CONVERSION
25
+ CLANG_WARN_EMPTY_BODY
26
+ CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION
27
+ CLANG_WARN__DUPLICATE_METHOD_MATCH
28
+ GCC_WARN_64_TO_32_BIT_CONVERSION
29
+ RUN_CLANG_STATIC_ANALYZER
30
+ GCC_TREAT_WARNINGS_AS_ERRORS)
31
+ warnings.each { |w| option(w, true) }
32
+ end
33
+
34
+ def target(name, &block)
35
+ TargetScope.new(name).configure(&block)
36
+ end
37
+
38
+ def use_defaults_for_everything_not_specified_in_this_file!
39
+ Ambient.configure { @use_defaults = true }
40
+ end
41
+
42
+ class TargetScope
43
+ attr_reader :name
44
+
45
+ def initialize(name)
46
+ @name = name
47
+ end
48
+
49
+ def configure(&block)
50
+ instance_eval(&block)
51
+ end
52
+
53
+ def option(option_name, value)
54
+ target_name = @name
55
+ Ambient.configure { set_option(option_name, value, target: target_name) }
56
+ end
57
+
58
+ def scheme(name, parent: nil, &block)
59
+ SchemeScope.new(self, name, parent).configure(&block)
60
+ end
61
+ end
62
+
63
+ class SchemeScope
64
+ def initialize(target, name, parent)
65
+ @target = target
66
+ @name = name
67
+ @parent = parent
68
+
69
+ child = name
70
+ Ambient.configure { set_parent_target(target.name, child, parent) }
71
+ end
72
+
73
+ def configure(&block)
74
+ instance_eval(&block)
75
+ end
76
+
77
+ def option(option_name, value)
78
+ target = @target
79
+ name = @name
80
+ parent = @parent
81
+
82
+ Ambient.configure do
83
+ # require 'pry'; binding.pry
84
+ set_option(option_name, value, target: target.name, scheme: name, parent: parent)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,79 @@
1
+ require 'xcodeproj'
2
+ require 'highline/import'
3
+
4
+ class ProjectHelper
5
+ PROJECTS = Dir.glob('*.xcodeproj')
6
+
7
+ def initialize
8
+ @project = Xcodeproj::Project.open(PROJECTS.first)
9
+ end
10
+
11
+ def reset_project_to_defaults
12
+ @project.build_configurations.each do |configuration|
13
+ build_settings = configuration.build_settings
14
+ build_settings.each { |k, _| build_settings.delete(k) }
15
+ end
16
+ save_changes
17
+ end
18
+
19
+ def reset_targets_to_defaults
20
+ @project.targets.each do |target|
21
+ @project.build_configurations.each do |configuration|
22
+ build_settings = target.build_configuration_list.build_settings(configuration.to_s)
23
+ build_settings.each { |k, _| build_settings.delete(k) }
24
+ end
25
+ end
26
+ end
27
+
28
+ def process_project_options(options)
29
+ @project.build_configurations.each do |configuration|
30
+ options.each do |key, value|
31
+ configuration.build_settings[key] = value
32
+ configuration.build_settings.delete(key) if value == nil
33
+ end
34
+ end
35
+ save_changes
36
+ end
37
+
38
+ def process_shared_target_options(shared_target_options)
39
+ @project.targets.each do |target|
40
+ options = shared_target_options[target.to_s]
41
+ if options
42
+ @project.build_configurations.each do |configuration|
43
+ target.build_configuration_list.build_settings(configuration.to_s).merge!(options)
44
+ end
45
+ end
46
+ end
47
+ save_changes
48
+ end
49
+
50
+ def process_target_options(target_options)
51
+ @project.targets.each do |target|
52
+ options = target_options[target.to_s]
53
+ if options
54
+ @project.build_configurations.each do |configuration|
55
+ scheme_options = options[configuration.to_s]
56
+ if scheme_options
57
+ target.build_configuration_list.build_settings(configuration.to_s).merge!(scheme_options)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ save_changes
63
+ end
64
+
65
+ def print_info
66
+ puts "Targets:"
67
+ @project.targets.each { |t| puts "- #{t.to_s}" }
68
+ puts ""
69
+ puts "Build configurations:"
70
+ @project.build_configurations.each { |c| puts "- #{c.to_s}" }
71
+ puts ""
72
+ end
73
+
74
+ private
75
+
76
+ def save_changes
77
+ @project.save
78
+ end
79
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ambient-xcode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Green
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xcodeproj
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.25'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.25'
27
+ - !ruby/object:Gem::Dependency
28
+ name: highline
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ description: CLI for configuring Xcode projects from a Ruby file.
42
+ email:
43
+ - dan2552@gmail.com
44
+ executables:
45
+ - ambient
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - README.md
50
+ - ambient-xcode.gemspec
51
+ - bin/ambient
52
+ - lib/ambient.rb
53
+ - lib/dsl.rb
54
+ - lib/project_helper.rb
55
+ homepage: https://github.com/Dan2552/ambient
56
+ licenses:
57
+ - MIT
58
+ metadata: {}
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 2.2.2
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: Define your envrionment settings all in one easy to read Ruby file, and re-apply
79
+ it to your Xcode project to ensure settings are correct.
80
+ test_files: []