longbow 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 96a0a8923328aceeec013bb664110ef3d068523a
4
+ data.tar.gz: d84d3828e7aaf15061d8f5ed54e0eb591f84898e
5
+ SHA512:
6
+ metadata.gz: c05a5c08829a5e7b02fd7995d93c52352681a596a8b5bc7619275b94556231b69151d7ae4b08b3b560088625f0c5fa2dd8064926b1d156290f96d932ca2d28dc
7
+ data.tar.gz: 74047f1e332771e912c69fe00a0817de6595d626fec6e2bd079b9d764fb9f7626f7caf22b87d1e387a0099b9341f2ae0d98cc463a948df46fa6cc8723e63f2a5
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in longbow.gemspec
4
+ gemspec
5
+
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ longbow (0.0.1)
5
+ bundler (~> 1.3)
6
+ commander (~> 4.1)
7
+ dotenv (~> 0.7)
8
+ fileutils
9
+ json
10
+ mini_magick (~> 3.7.0)
11
+ xcodeproj
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ activesupport (3.2.16)
17
+ i18n (~> 0.6, >= 0.6.4)
18
+ multi_json (~> 1.0)
19
+ colored (1.2)
20
+ commander (4.1.5)
21
+ highline (~> 1.6.11)
22
+ dotenv (0.10.0)
23
+ fileutils (0.7)
24
+ rmagick (>= 2.13.1)
25
+ highline (1.6.20)
26
+ i18n (0.6.9)
27
+ json (1.8.1)
28
+ mini_magick (3.7.0)
29
+ subexec (~> 0.2.1)
30
+ multi_json (1.9.2)
31
+ rake (10.1.1)
32
+ rmagick (2.13.2)
33
+ subexec (0.2.3)
34
+ xcodeproj (0.16.0)
35
+ activesupport (~> 3.0)
36
+ colored (~> 1.2)
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ longbow!
43
+ rake
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Intermark Group
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,122 @@
1
+ ![banner](resources/banner.png)
2
+
3
+ **Problem**
4
+
5
+ One codebase. Multiple App Store submissions with different icons, info.plist keys, etc.
6
+
7
+ **Solution**
8
+
9
+ ```
10
+ longbow install
11
+ longbow shoot
12
+ ```
13
+
14
+ **About**
15
+
16
+ Longbow duplicates the main target in your `.xcworkspace` or `.xcodeproj` file, then reads from a JSON file to fill out the rest of your target. It looks for certain keys and creates such things like taking an icon image and resizing it for the various icons you'll need, and adding keys to the info.plist file for that target. The goal was to be practically autonomous in creating new targets and apps.
17
+
18
+ **Requirements**
19
+
20
+ Longbow requires Xcode 5+, and your app must use the new .xcassets paradigm for icons, launch screens, etc.
21
+
22
+ ## Table of Contents
23
+
24
+ * [Installation](#installation)
25
+ * [Set Up](#set-up)
26
+ * [Formatting longbow.json](#formatting-longbow-json)
27
+ * [Create a Target](#create-a-target)
28
+ * [Global Options](#global-options)
29
+ * [Contributing](#contributing)
30
+
31
+ ## Installation
32
+
33
+ Add this line to your application's Gemfile:
34
+
35
+ gem 'longbow'
36
+
37
+ And then execute:
38
+
39
+ $ bundle
40
+
41
+ Or install it yourself as:
42
+
43
+ $ gem install longbow
44
+
45
+ ## Set Up
46
+
47
+ Run `longbow install` in the directory where your `.xcworkspace` or `.xcodeproj` file lives. This will create a file, `longbow.json`, where they will be used to build out from here. You are almost ready to start creating new targets
48
+
49
+ ## Formatting .longbow.json
50
+
51
+ Here's a basic gist of how to format your `longbow.json` file:
52
+
53
+ ```
54
+ {
55
+ "targets":[
56
+ {
57
+ "name":"TargetName",
58
+ "icon_url":"https://somewhere.net/img.png",
59
+ "info_plist": {
60
+ "CFBundleIdentifier":"com.company.target1",
61
+ "ProprietaryKey":"Value"
62
+ }
63
+ },
64
+ {
65
+ "name":"TargetName2",
66
+ "icon_path":"/relative/path/to/file.png",
67
+ "info_plist": {
68
+ "CFBundleIdentifier":"com.company.target2",
69
+ "ProprietaryKey":"Value2"
70
+ }
71
+ }
72
+ ],
73
+ "global_info_keys":{
74
+ "somekey":"somevalue"
75
+ },
76
+ "devices":["iPhone","iPad"]
77
+ }
78
+ ```
79
+
80
+ In the top-level of the JSON file, we have 3 key/value pairs:
81
+
82
+ * `targets`
83
+ * `devices`
84
+ * `global_info_keys`
85
+
86
+ The `targets` section contains nested key/value pairs for each specific target. Each target can contain the following keys:
87
+
88
+ * `icon_url` or `icon_path`
89
+ * `info_plist`
90
+ * `name`
91
+
92
+ The `icon_url` and `icon_path` key corresponds to the location of the icon image. It will be downloaded from the web if necessary, then resized depending on your device setting and added to the Images.xcassets file for that target. The `info_plist` key corresponds to another set of key/value pairs that will be added or updated in the info.plist file specifically for this target.
93
+
94
+ ## Creating/Updating a Target
95
+
96
+ Now that you're set up - it's time to add a target. Make sure that you have updated your `longbow.json` file with the correct information for your target, and then run the following command inside the project directory.
97
+
98
+ `longbow shoot -n NameOfTarget`
99
+
100
+ What this does is goes to your `.longbow.json` file and looks for json{"targets"}{"NameOfTarget"} and tries to create a new Target in your app, and handles the various icons/info_plist additions specifically for this target. If your target already exists, it will just update the icon images and plist settings.
101
+
102
+ If you leave off the `-n` option, it will run for all targets in the `.longbow.json` file.
103
+
104
+ **Other Options**
105
+
106
+ * `-d, --directory` - if not in the current directory, specify a new path
107
+
108
+ `longbow shoot -n NameOfTarget -d ~/Path/To/App`
109
+
110
+ ## Global Options
111
+
112
+ `--dontlog` will not log the status/operations to the console.
113
+
114
+ `--help` will fill you in on what you need to do for an action.
115
+
116
+ ## Contributing
117
+
118
+ 1. Fork it
119
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
120
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
121
+ 4. Push to the branch (`git push origin my-new-feature`)
122
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ gemspec = eval(File.read("longbow.gemspec"))
4
+
5
+ task :build => "#{gemspec.full_name}.gem"
6
+
7
+ file "#{gemspec.full_name}.gem" => gemspec.files + ["longbow.gemspec"] do
8
+ system "gem build longbow.gemspec"
9
+ end
data/bin/longbow ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'dotenv'
4
+ Dotenv.load
5
+
6
+ require 'commander/import'
7
+
8
+ $:.push File.expand_path("../../lib", __FILE__)
9
+ require 'longbow'
10
+
11
+ HighLine.track_eof = false # Fix for built-in Ruby
12
+
13
+ program :version, Longbow::VERSION
14
+ program :description, 'Create duplicate Targets for your Xcode workspace/project.'
15
+
16
+ program :help, 'Author', 'Benjamin Gordon (@bennyguitar) for Intermark Group <interactive@intermarkgroup.com>'
17
+ program :help, 'Website', 'https://github.com/intermark'
18
+ program :help_formatter, :compact
19
+
20
+ global_option('--dontlog') { $nolog = true }
21
+
22
+ default_command :help
23
+
24
+ require 'longbow/commands'
@@ -0,0 +1,19 @@
1
+ module Longbow
2
+ # Main Colorize Functions
3
+ def self.colorize(text, color_code)
4
+ puts "\e[#{color_code}m#{text}\e[0m"
5
+ end
6
+
7
+ # Specific Colors
8
+ def self.red(text)
9
+ colorize(text, 31)
10
+ end
11
+
12
+ def self.green(text)
13
+ colorize(text, 32)
14
+ end
15
+
16
+ def self.blue(text)
17
+ colorize(text, 36)
18
+ end
19
+ end
@@ -0,0 +1,47 @@
1
+ $:.push File.expand_path('../../', __FILE__)
2
+ require 'fileutils'
3
+ require 'longbow'
4
+
5
+ command :install do |c|
6
+ c.syntax = 'longbow install [options]'
7
+ c.summary = 'Creates the required files in your directory.'
8
+ c.description = ''
9
+ c.option '-d', '--directory DIRECTORY', 'Path where the .xcproj or .xcworkspace file && the longbow.json file live.'
10
+
11
+ c.action do |args, options|
12
+ @directory = options.directory ? options.directory : Dir.pwd
13
+ @json_path = @directory + '/longbow.json'
14
+
15
+ if File.exist?(@json_path)
16
+ Longbow::red ' longbow.json already exists at ' + @json_path
17
+ else
18
+ File.open(@json_path, 'w') do |f|
19
+ f.write('{
20
+ "targets":[
21
+ {
22
+ "name":"TargetName",
23
+ "icon_url":"https://somewhere.net/img.png",
24
+ "info_plist": {
25
+ "CFBundleIdentifier":"com.company.target1",
26
+ "ProprietaryKey":"Value"
27
+ }
28
+ },
29
+ {
30
+ "name":"TargetName2",
31
+ "icon_path":"/relative/path/to/file.png",
32
+ "info_plist": {
33
+ "CFBundleIdentifier":"com.company.target2",
34
+ "ProprietaryKey":"Value2"
35
+ }
36
+ }
37
+ ],
38
+ "global_info_keys":{
39
+ "somekey":"somevalue"
40
+ },
41
+ "devices":["iPhone","iPad"]
42
+ }')
43
+ end
44
+ Longbow::green ' longbow.json created' unless $nolog
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,69 @@
1
+ $:.push File.expand_path('../../', __FILE__)
2
+ require 'fileutils'
3
+ require 'longbow/colors'
4
+ require 'longbow/targets'
5
+ require 'longbow/images'
6
+ require 'json'
7
+
8
+ command :shoot do |c|
9
+ c.syntax = 'longbow shoot [options]'
10
+ c.summary = 'Creates/updates a target or all targets in your workspace or project.'
11
+ c.description = ''
12
+
13
+ c.option '-n', '--name NAME', 'Target name from the corresponding longbow.json file.'
14
+ c.option '-d', '--directory DIRECTORY', 'Path where the .xcodeproj or .xcworkspace file && the longbow.json file live.'
15
+
16
+ c.action do |args, options|
17
+ # Set Up
18
+ @target_name = options.name ? options.name : nil
19
+ @directory = options.directory ? options.directory : Dir.pwd
20
+ @targets = []
21
+
22
+ # Check for .longbow.json
23
+ @json_path = @directory + '/longbow.json'
24
+ if !File.exists?(@json_path)
25
+ puts
26
+ Longbow::red " Couldn't find longbow.json at " + @json_path
27
+ puts
28
+ puts " Run this command to install the correct files:"
29
+ puts " longbow install"
30
+ puts
31
+ next
32
+ end
33
+
34
+ # Create an Object from JSON
35
+ json_contents = File.open(@json_path).read
36
+ unless !!JSON.parse(json_contents)
37
+ Longbow::red ' Invalid JSON - lint it, and try again.'
38
+ next
39
+ end
40
+ obj = JSON.parse(json_contents)
41
+
42
+ # Check for Target Name
43
+ if @target_name
44
+ obj['targets'].each do |t|
45
+ @targets << t if t['name'] == @target_name
46
+ end
47
+
48
+ if @targets.length == 0
49
+ puts
50
+ Longbow::red " Couldn't find a target named " + @target_name + " in the .longbow.json file."
51
+ puts
52
+ next
53
+ end
54
+ else
55
+ obj['targets'].each do |t|
56
+ @targets << t
57
+ end
58
+ end
59
+
60
+ # Begin
61
+ @targets.each do |t|
62
+ Longbow::update_target @directory, t['name'], obj['global_info_keys'], t['info_plist']
63
+ Longbow::resize_icons @directory, t, obj
64
+ Longbow::write_json_for_icons @directory, t, obj
65
+ Longbow::green ' Finished: ' + t['name'] unless $nolog
66
+ puts unless $nolog
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,4 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+
3
+ require 'commands/shoot'
4
+ require 'commands/install'
@@ -0,0 +1,165 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+ require 'mini_magick'
3
+ require 'colors'
4
+ require 'xcodeproj'
5
+ require 'open-uri'
6
+
7
+ module Longbow
8
+
9
+ # Resize Icon
10
+ def self.resize_icons(directory, t, obj)
11
+ # Bad Params
12
+ if !directory || !t
13
+ return false
14
+ end
15
+
16
+ # Set Up
17
+ target = t['name']
18
+
19
+ # Get Device Information
20
+ iPhone = false
21
+ iPad = false
22
+ if obj['devices']
23
+ obj['devices'].each do |d|
24
+ iPhone = true if d == 'iPhone'
25
+ iPad = true if d == 'iPad'
26
+ end
27
+ end
28
+
29
+ # Get Image Information
30
+ img_path = ''
31
+ if t['icon_url']
32
+ img_path = self.path_for_downloaded_image_from_url directory, target, t['icon_url']
33
+ elsif t['icon_path']
34
+ img_path = directory + '/' + t['icon_path']
35
+ end
36
+
37
+ # Make directory
38
+ img_dir = make_asset_directory directory, target
39
+
40
+ # Make image
41
+ image = MiniMagick::Image.open(img_path)
42
+ return false unless image
43
+
44
+ # Size for iPhone
45
+ if iPhone
46
+ image.resize '120x120'
47
+ image.write img_dir + '/icon120x120.png'
48
+ image.resize '114x114'
49
+ image.write img_dir + '/icon114x114.png'
50
+ image.resize '80x80'
51
+ image.write img_dir + '/icon80x80.png'
52
+ image.resize '58x58'
53
+ image.write img_dir + '/icon58x58.png'
54
+ image.resize '57x57'
55
+ image.write img_dir + '/icon57x57.png'
56
+ image.resize '29x29'
57
+ image.write img_dir + '/icon29x29.png'
58
+ Longbow::green (' - Created iPhone icon images for ' + target) if $verbose
59
+ end
60
+
61
+ if iPad
62
+ image.resize '152x152'
63
+ image.write img_dir + '/icon152x152.png'
64
+ image.resize '144x144'
65
+ image.write img_dir + '/icon144x144.png'
66
+ image.resize '100x100'
67
+ image.write img_dir + '/icon100x100.png'
68
+ image.resize '80x80'
69
+ image.write img_dir + '/icon80x80.png'
70
+ image.resize '76x76'
71
+ image.write img_dir + '/icon76x76.png'
72
+ image.resize '72x72'
73
+ image.write img_dir + '/icon72x72.png'
74
+ image.resize '58x58'
75
+ image.write img_dir + '/icon58x58.png'
76
+ image.resize '50x50'
77
+ image.write img_dir + '/icon50x50.png'
78
+ image.resize '40x40'
79
+ image.write img_dir + '/icon40x40.png'
80
+ image.resize '29x29'
81
+ image.write img_dir + '/icon29x29.png'
82
+ Longbow::green (' - Created iPad icon images for ' + target) unless $nolog
83
+ end
84
+ return true
85
+ end
86
+
87
+
88
+ # Create JSON
89
+ def self.write_json_for_icons(directory, t, obj)
90
+ # Bad Params
91
+ if !directory || !t
92
+ return false
93
+ end
94
+
95
+ # Set Up
96
+ target = t['name']
97
+
98
+ # Get Device Information
99
+ iPhone = false
100
+ iPad = false
101
+ if obj['devices']
102
+ obj['devices'].each do |d|
103
+ iPhone = true if d == 'iPhone'
104
+ iPad = true if d == 'iPad'
105
+ end
106
+ end
107
+
108
+ # Make directory
109
+ img_dir = make_asset_directory directory, target
110
+
111
+ # Write the JSON file
112
+ File.open(img_dir + '/Contents.json', 'w') do |f|
113
+ f.write('{ "images" : [ ')
114
+
115
+ if iPhone
116
+ f.write( '{ "size" : "29x29", "idiom" : "iphone", "filename" : "icon58x58.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon80x80.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon120x120.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon29x29.png", "scale" : "1x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon57x57.png", "scale" : "1x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon114x114.png", "scale" : "2x" }' + (iPad ? ',' : ''))
117
+ end
118
+
119
+ if iPad
120
+ f.write( '{ "idiom" : "ipad", "size" : "29x29", "scale" : "1x", "filename" : "icon29x29.png" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x", "filename" : "icon58x58.png" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x", "filename" : "icon40x40.png" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x", "filename" : "icon80x80.png" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x", "filename" : "icon76x76.png" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x", "filename" : "icon152x152.png" }, { "idiom" : "ipad", "size" : "50x50", "scale" : "1x", "filename" : "icon50x50.png" }, { "idiom" : "ipad", "size" : "50x50", "scale" : "2x", "filename" : "icon100x100.png" }, { "idiom" : "ipad", "size" : "72x72", "scale" : "1x", "filename" : "icon72x72.png" }, { "idiom" : "ipad", "size" : "72x72", "scale" : "2x", "filename" : "icon144x144.png" }')
121
+ end
122
+
123
+ f.write(' ], "info" : { "version" : 1, "author" : "xcode" }, "properties" : { "pre-rendered" : true } }')
124
+ end
125
+
126
+ # Return true
127
+ Longbow::green (' - Created Images.xcassets icon set for ' + target) unless $nolog
128
+ return true
129
+ end
130
+
131
+
132
+ # Make Directory for Images.xcassets
133
+ def self.make_asset_directory directory, target
134
+ asset_path = assets_file_path directory
135
+ full_path = asset_path + '/' + target + '.appiconset/'
136
+ FileUtils::mkdir_p full_path
137
+ return full_path
138
+ end
139
+
140
+
141
+ def self.assets_file_path directory
142
+ asset_path = ''
143
+ Dir.glob(directory + '/**/*/').each do |d|
144
+ searching = 'Images.xcassets/'
145
+ asset_path = d if d.slice(d.length - searching.length, searching.length) == searching
146
+ end
147
+
148
+ return asset_path
149
+ end
150
+
151
+
152
+ # Download Image from URL
153
+ def self.path_for_downloaded_image_from_url directory, target, url
154
+ img_path = directory + '/resources/icons/'
155
+ img_file_name = target + '.png'
156
+ FileUtils::mkdir_p img_path
157
+ File.open(img_path + img_file_name, 'wb') do |f|
158
+ f.write open(url).read
159
+ end
160
+
161
+ return img_path + img_file_name
162
+ end
163
+
164
+
165
+ end
@@ -0,0 +1,68 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+ require 'mini_magick'
3
+ require 'colors'
4
+ require 'xcodeproj'
5
+ require 'open-uri'
6
+
7
+ module Longbow
8
+
9
+ # Create Plist from Original Plist Content
10
+ def self.create_plist_from_old_plist old_plist, info_hash, global_hash
11
+ return '' unless old_plist && info_hash && global_hash
12
+ plist_text = old_plist
13
+ [info_hash,global_hash].each do |hash|
14
+ hash.each_key do |k|
15
+ value = hash[k]
16
+ matches = plist_text.match /<key>#{k}<\/key>\s*<(.*?)>.*<\/(.*?)>/
17
+ if matches
18
+ plist_text = plist_text.sub(matches[0], "<key>" + k + "</key>\n" + recursive_plist_value_for_value(value))
19
+ else
20
+ plist_text = plist_text.sub(/<\/dict>\s*<\/plist>/, "<key>" + k + "</key>\n" + recursive_plist_value_for_value(value) + "</dict></plist>")
21
+ end
22
+ end
23
+ end
24
+
25
+ return plist_text
26
+ end
27
+
28
+ # Recursively create Plist Values for a given object
29
+ def self.recursive_plist_value_for_value value
30
+ return '' unless value
31
+
32
+ # Check Number
33
+ if value.kind_of?(Numeric)
34
+ return '<real>' + value.to_s + '</real>'
35
+ end
36
+
37
+ # Check Boolean
38
+ if !!value == value
39
+ if value == true
40
+ return '<true />'
41
+ else
42
+ return '<false />'
43
+ end
44
+ end
45
+
46
+ # Check Array
47
+ if value.kind_of?(Array)
48
+ total_values = '<array>'
49
+ value.each do |v|
50
+ total_values += recursive_plist_value_for_value(v)
51
+ end
52
+ return total_values + '</array>'
53
+ end
54
+
55
+ # Check Hash
56
+ if value.kind_of?(Hash)
57
+ total_values = '<dict>'
58
+ value.each_key do |key|
59
+ total_values += '<key>' + key + '</key>'
60
+ total_values += recursive_plist_value_for_value value[key]
61
+ end
62
+ return total_values + '</dict>'
63
+ end
64
+
65
+ return '<string>' + value.to_s + '</string>'
66
+ end
67
+
68
+ end
@@ -0,0 +1,110 @@
1
+ require 'xcodeproj'
2
+ require 'colors'
3
+ require 'plist'
4
+
5
+ module Longbow
6
+
7
+ def self.update_target directory, target, global_keys, info_keys
8
+ unless directory && target && global_keys && info_keys
9
+ Longbow::red ' Invalid parameters. Could not create/update target named: ' + target
10
+ return false
11
+ end
12
+
13
+ # Find Project File
14
+ project_paths = []
15
+ Dir.foreach(directory) do |fname|
16
+ project_paths << fname if fname.include? '.xcodeproj'
17
+ end
18
+
19
+ # Open The Project
20
+ return false if project_paths.length == 0
21
+ proj = Xcodeproj::Project.open(project_paths[0])
22
+
23
+ # Get Main Target's Basic Info
24
+ @target = nil
25
+ proj.targets.each do |t|
26
+ if t.to_s == target
27
+ @target = t
28
+ Longbow::green ' ' + target + ' found.' unless $nolog
29
+ end
30
+ end
31
+
32
+ # Create Target if Necessary
33
+ main_target = proj.targets.first
34
+ @target = create_target(proj, target) unless @target
35
+
36
+ # Plist Creating/Adding
37
+ main_plist = main_target.build_configurations[0].build_settings['INFOPLIST_FILE']
38
+ main_plist_contents = File.read(directory + '/' + main_plist)
39
+ target_plist_path = directory + '/' + main_plist.split('/')[0] + '/' + target + '-info.plist'
40
+ plist_text = Longbow::create_plist_from_old_plist main_plist_contents, info_keys, global_keys
41
+ File.open(target_plist_path, 'w') do |f|
42
+ f.write(plist_text)
43
+ end
44
+ Longbow::green ' - ' + target + '-info.plist Updated.' unless $nolog
45
+
46
+
47
+ # Add Build Settings
48
+ @target.build_configurations.each do |b|
49
+ # Main Settings
50
+ main_settings = nil
51
+ main_target.build_configurations.each do |bc|
52
+ main_settings = bc.build_settings if bc.to_s == b.to_s
53
+ end
54
+ settings = b.build_settings
55
+ main_settings.each_key do |key|
56
+ settings[key] = main_settings[key]
57
+ end
58
+
59
+ # Plist & Icons
60
+ settings['INFOPLIST_FILE'] = main_plist.split('/')[0] + '/' + target + '-info.plist'
61
+ settings['ASSETCATALOG_COMPILER_APPICON_NAME'] = target
62
+
63
+ if File.exists? directory + '/Pods'
64
+ settings['PODS_ROOT'] = '${SRCROOT}/Pods'
65
+ settings['HEADER_SEARCH_PATHS'] = ['${PODS_ROOT}/Headers/**']
66
+ end
67
+ end
68
+
69
+ # Save The Project
70
+ proj.save
71
+ end
72
+
73
+ def self.create_target project, target
74
+ main_target = project.targets.first
75
+ deployment_target = main_target.deployment_target
76
+
77
+ # Create New Target
78
+ new_target = Xcodeproj::Project::ProjectHelper.new_target project, :application, target, :ios, deployment_target, project.products_group
79
+ if new_target
80
+ # Add Build Phases
81
+ main_target.build_phases.objects.each do |b|
82
+ if b.isa == 'PBXSourcesBuildPhase'
83
+ b.files_references.each do |f|
84
+ new_target.source_build_phase.add_file_reference f
85
+ end
86
+ elsif b.isa == 'PBXFrameworksBuildPhase'
87
+ b.files_references.each do |f|
88
+ new_target.frameworks_build_phase.add_file_reference f
89
+ end
90
+ elsif b.isa == 'PBXResourcesBuildPhase'
91
+ b.files_references.each do |f|
92
+ new_target.resources_build_phase.add_file_reference f
93
+ end
94
+ elsif b.isa == 'PBXShellScriptBuildPhase'
95
+ phase = new_target.new_shell_script_build_phase(name = b.display_name)
96
+ phase.shell_script = b.shell_script
97
+ end
98
+ end
99
+
100
+ Longbow::green ' ' + target + ' created.' unless $nolog
101
+ else
102
+ puts
103
+ Longbow::red ' Target Creation failed for target named: ' + target
104
+ puts
105
+ end
106
+
107
+ return new_target
108
+ end
109
+
110
+ end
@@ -0,0 +1,3 @@
1
+ module Longbow
2
+ VERSION = "0.0.1"
3
+ end
data/lib/longbow.rb ADDED
@@ -0,0 +1,6 @@
1
+ # Library files
2
+ require 'longbow/colors'
3
+ require 'longbow/version'
4
+ require 'longbow/commands'
5
+ require 'longbow/images'
6
+ require 'longbow/targets'
data/longbow-0.0.1.gem ADDED
Binary file
data/longbow.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'longbow/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "longbow"
8
+ spec.version = Longbow::VERSION
9
+ spec.authors = ["Intermark Interactive"]
10
+ spec.email = ["interactive@intermarkgroup.com"]
11
+ spec.description = "Duplicates the main target of an xcodeproj/xcworkspace and renames it, its info.plist, and its image.xcassets as well. It then optionally reads from a .longbow.json file in your project directory that adds info.plist keys, urls to a 1024x1024 icon that it resizes to fit device type. It also handles "
12
+ spec.summary = "Better target creation for one iOS codebase."
13
+ spec.homepage = "https://github.com/intermark/longbow"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'bundler', '~> 1.3'
22
+ spec.add_dependency 'fileutils'
23
+ spec.add_dependency 'commander', '~> 4.1'
24
+ spec.add_dependency 'dotenv', '~> 0.7'
25
+ spec.add_dependency 'mini_magick', '~> 3.7.0'
26
+ spec.add_dependency 'xcodeproj'
27
+ spec.add_dependency 'json'
28
+
29
+ spec.add_development_dependency "rake"
30
+
31
+ spec.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
32
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
33
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
34
+ spec.require_paths = ["lib"]
35
+ end
Binary file
metadata ADDED
@@ -0,0 +1,178 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: longbow
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Intermark Interactive
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fileutils
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: commander
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '4.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '4.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dotenv
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '0.7'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '0.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mini_magick
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 3.7.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 3.7.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: xcodeproj
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: json
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: 'Duplicates the main target of an xcodeproj/xcworkspace and renames it,
126
+ its info.plist, and its image.xcassets as well. It then optionally reads from a
127
+ .longbow.json file in your project directory that adds info.plist keys, urls to
128
+ a 1024x1024 icon that it resizes to fit device type. It also handles '
129
+ email:
130
+ - interactive@intermarkgroup.com
131
+ executables:
132
+ - longbow
133
+ extensions: []
134
+ extra_rdoc_files: []
135
+ files:
136
+ - ./Gemfile
137
+ - ./Gemfile.lock
138
+ - ./lib/longbow/colors.rb
139
+ - ./lib/longbow/commands/install.rb
140
+ - ./lib/longbow/commands/shoot.rb
141
+ - ./lib/longbow/commands.rb
142
+ - ./lib/longbow/images.rb
143
+ - ./lib/longbow/plist.rb
144
+ - ./lib/longbow/targets.rb
145
+ - ./lib/longbow/version.rb
146
+ - ./lib/longbow.rb
147
+ - ./LICENSE.txt
148
+ - ./longbow-0.0.1.gem
149
+ - ./longbow.gemspec
150
+ - ./Rakefile
151
+ - ./README.md
152
+ - ./resources/banner.png
153
+ - bin/longbow
154
+ homepage: https://github.com/intermark/longbow
155
+ licenses:
156
+ - MIT
157
+ metadata: {}
158
+ post_install_message:
159
+ rdoc_options: []
160
+ require_paths:
161
+ - lib
162
+ required_ruby_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ required_rubygems_version: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - '>='
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ requirements: []
173
+ rubyforge_project:
174
+ rubygems_version: 2.1.11
175
+ signing_key:
176
+ specification_version: 4
177
+ summary: Better target creation for one iOS codebase.
178
+ test_files: []