ambient-xcode 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []