longbow 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +24 -18
- data/bin/longbow +2 -2
- data/lib/longbow/commands/install.rb +2 -0
- data/lib/longbow/commands/shoot.rb +4 -4
- data/lib/longbow/images.rb +211 -64
- data/lib/longbow/plist.rb +3 -9
- data/lib/longbow/targets.rb +6 -4
- data/lib/longbow/version.rb +1 -1
- metadata +4 -9
- data/longbow-0.0.1.gem +0 -0
- data/longbow-0.0.2.gem +0 -0
- data/longbow.gemspec +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d9d23f8abda5c70020a897a8d10561bcbbf4369
|
4
|
+
data.tar.gz: 6648c78d32411ecbedc89c2a17f2abe443d2c0b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8516a7b65a6286cd209e75c1c8163488d451bffd5ede55e57d67bb043178b752905efd0c82ff7f1399a9c1188010b8ea4c7e1899f03585280e13162cfcfba9d6
|
7
|
+
data.tar.gz: 6bb1b3e92a8a622f32b98d8883a1ee20c82f78568bd8dccbbd47b57e30df4637f26b12e7531fc9c15c337b16d68c18dc7d5ec649fcfb022140c9e3a7aa8d5dae
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,18 +2,18 @@
|
|
2
2
|
|
3
3
|
**Problem**
|
4
4
|
|
5
|
-
One codebase. Multiple App Store
|
5
|
+
One codebase. Multiple App Store submission targets with different icons, launch images, info.plist keys, etc.
|
6
6
|
|
7
7
|
**Solution**
|
8
8
|
|
9
9
|
```
|
10
|
-
longbow install
|
11
|
-
longbow shoot
|
10
|
+
$ longbow install
|
11
|
+
$ longbow shoot
|
12
12
|
```
|
13
13
|
|
14
14
|
**About**
|
15
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
|
16
|
+
Longbow is a command-line run ruby gem that duplicates the main target in your `.xcworkspace` or `.xcodeproj` file, then reads from a JSON file to fill out the rest of your new target. It looks for certain keys and does 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
17
|
|
18
18
|
**Requirements**
|
19
19
|
|
@@ -26,19 +26,12 @@ Longbow requires Xcode 5+, and your app must use the new .xcassets paradigm for
|
|
26
26
|
* [Formatting longbow.json](#formatting-longbow-json)
|
27
27
|
* [Create a Target](#create-a-target)
|
28
28
|
* [Global Options](#global-options)
|
29
|
+
* [The Future](#the-future)
|
29
30
|
* [Contributing](#contributing)
|
30
31
|
|
31
32
|
## Installation
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
gem 'longbow'
|
36
|
-
|
37
|
-
And then execute:
|
38
|
-
|
39
|
-
$ bundle
|
40
|
-
|
41
|
-
Or install it yourself as:
|
34
|
+
Longbow is officially hosted on [RubyGems](http://rubygems.org/gems/longbow), so installation is a breeze:
|
42
35
|
|
43
36
|
$ gem install longbow
|
44
37
|
|
@@ -46,7 +39,7 @@ Or install it yourself as:
|
|
46
39
|
|
47
40
|
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
41
|
|
49
|
-
## Formatting
|
42
|
+
## Formatting longbow.json
|
50
43
|
|
51
44
|
Here's a basic gist of how to format your `longbow.json` file:
|
52
45
|
|
@@ -56,6 +49,7 @@ Here's a basic gist of how to format your `longbow.json` file:
|
|
56
49
|
{
|
57
50
|
"name":"TargetName",
|
58
51
|
"icon_url":"https://somewhere.net/img.png",
|
52
|
+
"launch_phone_p_url":"https://somewhere.net/img2.png",
|
59
53
|
"info_plist": {
|
60
54
|
"CFBundleIdentifier":"com.company.target1",
|
61
55
|
"ProprietaryKey":"Value"
|
@@ -64,6 +58,7 @@ Here's a basic gist of how to format your `longbow.json` file:
|
|
64
58
|
{
|
65
59
|
"name":"TargetName2",
|
66
60
|
"icon_path":"/relative/path/to/file.png",
|
61
|
+
"launch_phone_p_path":"/relative/path/to/file2.png",
|
67
62
|
"info_plist": {
|
68
63
|
"CFBundleIdentifier":"com.company.target2",
|
69
64
|
"ProprietaryKey":"Value2"
|
@@ -83,13 +78,19 @@ In the top-level of the JSON file, we have 3 key/value pairs:
|
|
83
78
|
* `devices`
|
84
79
|
* `global_info_keys`
|
85
80
|
|
86
|
-
The `targets` section contains nested key/value pairs for each specific target. Each target can contain the following keys:
|
81
|
+
The `targets` section contains nested key/value pairs for each specific target. Devices holds an array of "iPhone" and/or "iPad". "global_info_keys" contains key/value pairs that you'd like to add to the info.plist file for all targets in this JSON file. Each target can contain the following keys:
|
87
82
|
|
88
83
|
* `icon_url` or `icon_path`
|
84
|
+
* `launch_phone_p_url` or `launch_phone_p_path`
|
85
|
+
* `launch_phone_l_url` or `launch_phone_l_path`
|
86
|
+
* `launch_tablet_p_url` or `launch_tablet_p_path`
|
87
|
+
* `launch_tablet_l_url` or `launch_tablet_l_path`
|
89
88
|
* `info_plist`
|
90
89
|
* `name`
|
91
90
|
|
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.
|
91
|
+
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 same goes for the launch image keys. The p and l parts correspond to portrait and landscape orientation. 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.
|
92
|
+
|
93
|
+
**Note:** `info_plist` takes precedence over `global_info_keys` for two of the same keys in both places.
|
93
94
|
|
94
95
|
## Creating/Updating a Target
|
95
96
|
|
@@ -97,9 +98,9 @@ Now that you're set up - it's time to add a target. Make sure that you have upda
|
|
97
98
|
|
98
99
|
`longbow shoot -n NameOfTarget`
|
99
100
|
|
100
|
-
What this does is goes to your
|
101
|
+
What this does is goes to your `longbow.json` file and looks for the correct target dictionary, and tries to create a new Target in your app. It then 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
|
|
102
|
-
If you leave off the `-n` option, it will run for all targets in the
|
103
|
+
If you leave off the `-n` option, it will run for all targets in the `longbow.json` file.
|
103
104
|
|
104
105
|
**Other Options**
|
105
106
|
|
@@ -113,6 +114,11 @@ If you leave off the `-n` option, it will run for all targets in the `.longbow.j
|
|
113
114
|
|
114
115
|
`--help` will fill you in on what you need to do for an action.
|
115
116
|
|
117
|
+
## The Future
|
118
|
+
|
119
|
+
* Unit Tests
|
120
|
+
* App Store deployment of Targets
|
121
|
+
|
116
122
|
## Contributing
|
117
123
|
|
118
124
|
1. Fork it
|
data/bin/longbow
CHANGED
@@ -11,7 +11,7 @@ require 'longbow'
|
|
11
11
|
HighLine.track_eof = false # Fix for built-in Ruby
|
12
12
|
|
13
13
|
program :version, Longbow::VERSION
|
14
|
-
program :description, '
|
14
|
+
program :description, 'One codebase. Multiple App Store submission targets with different icons, launch images, info.plist keys, etc.'
|
15
15
|
|
16
16
|
program :help, 'Author', 'Benjamin Gordon (@bennyguitar) for Intermark Group <interactive@intermarkgroup.com>'
|
17
17
|
program :help, 'Website', 'https://github.com/intermark'
|
@@ -21,4 +21,4 @@ global_option('--dontlog') { $nolog = true }
|
|
21
21
|
|
22
22
|
default_command :help
|
23
23
|
|
24
|
-
require 'longbow/commands'
|
24
|
+
require 'longbow/commands'
|
@@ -21,6 +21,7 @@ command :install do |c|
|
|
21
21
|
{
|
22
22
|
"name":"TargetName",
|
23
23
|
"icon_url":"https://somewhere.net/img.png",
|
24
|
+
"launch_phone_p_url":"https://somewhere.net/img2.png",
|
24
25
|
"info_plist": {
|
25
26
|
"CFBundleIdentifier":"com.company.target1",
|
26
27
|
"ProprietaryKey":"Value"
|
@@ -29,6 +30,7 @@ command :install do |c|
|
|
29
30
|
{
|
30
31
|
"name":"TargetName2",
|
31
32
|
"icon_path":"/relative/path/to/file.png",
|
33
|
+
"launch_phone_p_path":"/relative/path/to/file2.png",
|
32
34
|
"info_plist": {
|
33
35
|
"CFBundleIdentifier":"com.company.target2",
|
34
36
|
"ProprietaryKey":"Value2"
|
@@ -9,7 +9,6 @@ command :shoot do |c|
|
|
9
9
|
c.syntax = 'longbow shoot [options]'
|
10
10
|
c.summary = 'Creates/updates a target or all targets in your workspace or project.'
|
11
11
|
c.description = ''
|
12
|
-
|
13
12
|
c.option '-n', '--name NAME', 'Target name from the corresponding longbow.json file.'
|
14
13
|
c.option '-d', '--directory DIRECTORY', 'Path where the .xcodeproj or .xcworkspace file && the longbow.json file live.'
|
15
14
|
|
@@ -59,9 +58,10 @@ command :shoot do |c|
|
|
59
58
|
|
60
59
|
# Begin
|
61
60
|
@targets.each do |t|
|
62
|
-
|
63
|
-
|
64
|
-
Longbow::
|
61
|
+
icon = t['icon_url'] | t['icon_path']
|
62
|
+
launch = t['launch_phone_p_url'] || t['launch_phone_p_path'] || t['launch_phone_l_url'] || t['launch_phone_l_path'] || t['launch_tablet_p_url'] || t['launch_tablet_p_path'] || t['launch_tablet_l_url'] || t['launch_tablet_l_path']
|
63
|
+
Longbow::update_target @directory, t['name'], obj['global_info_keys'], t['info_plist'], icon, launch
|
64
|
+
Longbow::create_images @directory, t, obj
|
65
65
|
Longbow::green ' Finished: ' + t['name'] unless $nolog
|
66
66
|
puts unless $nolog
|
67
67
|
end
|
data/lib/longbow/images.rb
CHANGED
@@ -6,16 +6,13 @@ require 'open-uri'
|
|
6
6
|
|
7
7
|
module Longbow
|
8
8
|
|
9
|
-
#
|
10
|
-
def self.
|
9
|
+
# Images
|
10
|
+
def self.create_images directory, t, obj
|
11
11
|
# Bad Params
|
12
|
-
if !directory || !t
|
12
|
+
if !directory || !t || !obj
|
13
13
|
return false
|
14
14
|
end
|
15
15
|
|
16
|
-
# Set Up
|
17
|
-
target = t['name']
|
18
|
-
|
19
16
|
# Get Device Information
|
20
17
|
iPhone = false
|
21
18
|
iPad = false
|
@@ -26,87 +23,131 @@ module Longbow
|
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
26
|
+
# Resize Icons
|
27
|
+
resize_icons directory, t, iPhone, iPad
|
28
|
+
|
29
|
+
# Resize Launch Images
|
30
|
+
resize_launch_images directory, t
|
31
|
+
|
32
|
+
# Write JSON for Icon Assets
|
33
|
+
write_json_for_icons directory, t, iPhone, iPad
|
34
|
+
|
35
|
+
# Write JSON for Launch Assets
|
36
|
+
write_json_for_launch_images directory, t
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# Create & Resize Icons
|
42
|
+
def self.resize_icons directory, t, iPhone, iPad
|
43
|
+
# Set Up
|
44
|
+
target = t['name']
|
45
|
+
|
29
46
|
# Get Image Information
|
30
47
|
img_path = ''
|
31
48
|
if t['icon_url']
|
32
|
-
img_path = self.path_for_downloaded_image_from_url directory, target, t['icon_url']
|
49
|
+
img_path = self.path_for_downloaded_image_from_url directory, target, t['icon_url'], 'icons'
|
33
50
|
elsif t['icon_path']
|
34
51
|
img_path = directory + '/' + t['icon_path']
|
35
52
|
end
|
36
53
|
|
37
54
|
# Make directory
|
38
|
-
img_dir = make_asset_directory directory, target
|
55
|
+
img_dir = make_asset_directory directory, target, '.appiconset/'
|
39
56
|
|
40
57
|
# Size for iPhone
|
41
58
|
if iPhone
|
42
59
|
image = MiniMagick::Image.open(img_path)
|
43
60
|
return false unless image
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
image.write img_dir + '/icon114x114.png'
|
48
|
-
image.resize '80x80'
|
49
|
-
image.write img_dir + '/icon80x80.png'
|
50
|
-
image.resize '58x58'
|
51
|
-
image.write img_dir + '/icon58x58.png'
|
52
|
-
image.resize '57x57'
|
53
|
-
image.write img_dir + '/icon57x57.png'
|
54
|
-
image.resize '29x29'
|
55
|
-
image.write img_dir + '/icon29x29.png'
|
56
|
-
Longbow::green (' - Created iPhone icon images for ' + target) if $verbose
|
61
|
+
['120x120', '114x114', '80x80', '58x58', '57x57', '29x29'].each do |size|
|
62
|
+
resize_image_to_directory img_dir, image, size, 'icon'
|
63
|
+
end
|
57
64
|
end
|
58
65
|
|
66
|
+
# iPad
|
59
67
|
if iPad
|
60
68
|
image = MiniMagick::Image.open(img_path)
|
61
69
|
return false unless image
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
70
|
+
['152x152', '144x144', '100x100', '80x80', '76x76', '72x72', '58x58', '50x50', '40x40', '29x29'].each do |size|
|
71
|
+
resize_image_to_directory img_dir, image, size, 'icon'
|
72
|
+
end
|
83
73
|
end
|
74
|
+
|
75
|
+
Longbow::green (' - Created Icon images for ' + target) unless $nolog
|
84
76
|
return true
|
85
77
|
end
|
86
78
|
|
87
79
|
|
88
|
-
# Create
|
89
|
-
def self.
|
90
|
-
# Bad Params
|
91
|
-
if !directory || !t
|
92
|
-
return false
|
93
|
-
end
|
94
|
-
|
80
|
+
# Create & Resize Launch Images
|
81
|
+
def self.resize_launch_images directory, t
|
95
82
|
# Set Up
|
96
83
|
target = t['name']
|
97
84
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
85
|
+
['launch_phone_p', 'launch_phone_l', 'launch_tablet_p', 'launch_tablet_l'].each do |key|
|
86
|
+
img_path = ''
|
87
|
+
if t[key + '_url']
|
88
|
+
img_path = self.path_for_downloaded_image_from_url directory, key + '_' + target, t[key + '_url'], 'launch'
|
89
|
+
elsif t[key + '_path']
|
90
|
+
img_path = directory + '/' + t[key + '_path']
|
91
|
+
else
|
92
|
+
next
|
93
|
+
end
|
94
|
+
|
95
|
+
# Make directory
|
96
|
+
img_dir = make_asset_directory directory, target, '.launchimage/'
|
97
|
+
|
98
|
+
# Make resize sizes
|
99
|
+
sizes = []
|
100
|
+
if key == 'launch_phone_p'
|
101
|
+
sizes = ['640x1136','640x960']
|
102
|
+
elsif key == 'launch_phone_l'
|
103
|
+
sizes = ['1136x640','960x640']
|
104
|
+
elsif key == 'launch_tablet_p'
|
105
|
+
sizes = ['1536x2048','768x1024']
|
106
|
+
elsif key == 'launch_tablet_l'
|
107
|
+
sizes = ['2048x1536','1024x768']
|
108
|
+
end
|
109
|
+
|
110
|
+
# Resize Images
|
111
|
+
sizes.each do |size|
|
112
|
+
image = MiniMagick::Image.open(img_path)
|
113
|
+
return false unless image
|
114
|
+
resize_image_to_directory img_dir, image, size, key + '_'
|
105
115
|
end
|
106
116
|
end
|
107
117
|
|
118
|
+
Longbow::green (' - Created Launch images for ' + target) unless $nolog
|
119
|
+
return true
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
# Resize Image to Directory
|
124
|
+
def self.resize_image_to_directory directory, image, size, tag
|
125
|
+
sizes = size.split('x')
|
126
|
+
new_w = Integer(sizes[0])
|
127
|
+
new_h = Integer(sizes[1])
|
128
|
+
w = image[:width]
|
129
|
+
h = image[:height]
|
130
|
+
if w < h
|
131
|
+
m = new_w.to_f/w
|
132
|
+
new_size = new_w.to_s + 'x' + (h*m).to_i.to_s
|
133
|
+
else
|
134
|
+
m = new_h.to_f/h
|
135
|
+
new_size = (w*m).to_i.to_s + 'x' + new_h.to_s
|
136
|
+
end
|
137
|
+
|
138
|
+
image.resize new_size
|
139
|
+
image.crop size + '+0+0' unless new_size == size
|
140
|
+
image.write directory + '/' + tag + size + '.png'
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# Create JSON
|
145
|
+
def self.write_json_for_icons directory, t, iPhone, iPad
|
146
|
+
# Set Up
|
147
|
+
target = t['name']
|
148
|
+
|
108
149
|
# Make directory
|
109
|
-
img_dir = make_asset_directory directory, target
|
150
|
+
img_dir = make_asset_directory directory, target, '.appiconset/'
|
110
151
|
|
111
152
|
# Write the JSON file
|
112
153
|
File.open(img_dir + '/Contents.json', 'w') do |f|
|
@@ -129,20 +170,126 @@ module Longbow
|
|
129
170
|
end
|
130
171
|
|
131
172
|
|
132
|
-
#
|
133
|
-
def self.
|
173
|
+
# JSON for Launch Images
|
174
|
+
def self.write_json_for_launch_images directory, t
|
175
|
+
# Set Up
|
176
|
+
target = t['name']
|
177
|
+
phone_portrait = t['launch_phone_p_url'] || t['launch_phone_p_path']
|
178
|
+
phone_landscape = t['launch_phone_l_url'] || t['launch_phone_l_path']
|
179
|
+
tablet_portrait = t['launch_tablet_p_url'] || t['launch_tablet_p_path']
|
180
|
+
tablet_landscape = t['launch_tablet_l_url'] || t['launch_tablet_l_path']
|
181
|
+
return false unless phone_portrait || phone_landscape || tablet_landscape || tablet_portrait
|
182
|
+
|
183
|
+
# Make Directory
|
184
|
+
img_dir = make_asset_directory directory, target, '.launchimage/'
|
185
|
+
|
186
|
+
File.open(img_dir + '/Contents.json', 'w') do |f|
|
187
|
+
f.write('{"images" : [')
|
188
|
+
|
189
|
+
if phone_portrait
|
190
|
+
f.write('{
|
191
|
+
"orientation" : "portrait",
|
192
|
+
"idiom" : "iphone",
|
193
|
+
"extent" : "full-screen",
|
194
|
+
"minimum-system-version" : "7.0",
|
195
|
+
"filename" : "launch_phone_p_640x960.png",
|
196
|
+
"scale" : "2x"
|
197
|
+
},
|
198
|
+
{
|
199
|
+
"extent" : "full-screen",
|
200
|
+
"idiom" : "iphone",
|
201
|
+
"subtype" : "retina4",
|
202
|
+
"filename" : "launch_phone_p_640x1136.png",
|
203
|
+
"minimum-system-version" : "7.0",
|
204
|
+
"orientation" : "portrait",
|
205
|
+
"scale" : "2x"
|
206
|
+
}')
|
207
|
+
f.write ',' if phone_landscape || tablet_portrait || tablet_landscape
|
208
|
+
end
|
209
|
+
|
210
|
+
if phone_landscape
|
211
|
+
f.write('{
|
212
|
+
"orientation" : "landscape",
|
213
|
+
"idiom" : "iphone",
|
214
|
+
"extent" : "full-screen",
|
215
|
+
"minimum-system-version" : "7.0",
|
216
|
+
"filename" : "launch_phone_l_960x640.png",
|
217
|
+
"scale" : "2x"
|
218
|
+
},
|
219
|
+
{
|
220
|
+
"extent" : "full-screen",
|
221
|
+
"idiom" : "iphone",
|
222
|
+
"subtype" : "retina4",
|
223
|
+
"filename" : "launch_phone_l_1136x640.png",
|
224
|
+
"minimum-system-version" : "7.0",
|
225
|
+
"orientation" : "landscape",
|
226
|
+
"scale" : "2x"
|
227
|
+
}')
|
228
|
+
f.write ',' if tablet_portrait || tablet_landscape
|
229
|
+
end
|
230
|
+
|
231
|
+
if tablet_portrait
|
232
|
+
f.write('{
|
233
|
+
"orientation" : "portrait",
|
234
|
+
"idiom" : "ipad",
|
235
|
+
"extent" : "full-screen",
|
236
|
+
"filename" : "launch_tablet_p_768x1024.png",
|
237
|
+
"minimum-system-version" : "7.0",
|
238
|
+
"scale" : "1x"
|
239
|
+
},
|
240
|
+
{
|
241
|
+
"orientation" : "portrait",
|
242
|
+
"idiom" : "ipad",
|
243
|
+
"extent" : "full-screen",
|
244
|
+
"filename" : "launch_tablet_p_1536x2048.png",
|
245
|
+
"minimum-system-version" : "7.0",
|
246
|
+
"scale" : "2x"
|
247
|
+
}')
|
248
|
+
f.write ',' if tablet_landscape
|
249
|
+
end
|
250
|
+
|
251
|
+
if tablet_landscape
|
252
|
+
f.write('{
|
253
|
+
"orientation" : "landscape",
|
254
|
+
"idiom" : "ipad",
|
255
|
+
"extent" : "full-screen",
|
256
|
+
"filename" : "launch_tablet_l_1024x768.png",
|
257
|
+
"minimum-system-version" : "7.0",
|
258
|
+
"scale" : "1x"
|
259
|
+
},
|
260
|
+
{
|
261
|
+
"orientation" : "landscape",
|
262
|
+
"idiom" : "ipad",
|
263
|
+
"extent" : "full-screen",
|
264
|
+
"filename" : "launch_tablet_l_2048x1536.png",
|
265
|
+
"minimum-system-version" : "7.0",
|
266
|
+
"scale" : "2x"
|
267
|
+
}')
|
268
|
+
end
|
269
|
+
|
270
|
+
f.write('],"info" : {"version" : 1,"author" : "xcode"}}')
|
271
|
+
end
|
272
|
+
|
273
|
+
# Return true
|
274
|
+
Longbow::green (' - Created Images.xcassets launch image set for ' + target) unless $nolog
|
275
|
+
return true
|
276
|
+
end
|
277
|
+
|
278
|
+
|
279
|
+
# Asset Directory Methods
|
280
|
+
def self.make_asset_directory directory, target, path_extension
|
134
281
|
asset_path = assets_file_path directory
|
135
|
-
full_path = asset_path + '/' + target +
|
282
|
+
full_path = asset_path + '/' + target + path_extension
|
136
283
|
FileUtils::mkdir_p full_path
|
137
284
|
return full_path
|
138
285
|
end
|
139
286
|
|
140
|
-
|
141
287
|
def self.assets_file_path directory
|
142
288
|
asset_path = ''
|
143
289
|
Dir.glob(directory + '/**/*/').each do |d|
|
144
290
|
searching = 'Images.xcassets/'
|
145
291
|
asset_path = d if d.slice(d.length - searching.length, searching.length) == searching
|
292
|
+
break if asset_path.length > 0
|
146
293
|
end
|
147
294
|
|
148
295
|
return asset_path
|
@@ -150,9 +297,9 @@ module Longbow
|
|
150
297
|
|
151
298
|
|
152
299
|
# Download Image from URL
|
153
|
-
def self.path_for_downloaded_image_from_url directory,
|
154
|
-
img_path = directory + '/resources/
|
155
|
-
img_file_name =
|
300
|
+
def self.path_for_downloaded_image_from_url directory, filename, url, folder
|
301
|
+
img_path = directory + '/resources/'+ folder + '/'
|
302
|
+
img_file_name = filename + '.png'
|
156
303
|
FileUtils::mkdir_p img_path
|
157
304
|
File.open(img_path + img_file_name, 'wb') do |f|
|
158
305
|
f.write open(url).read
|
data/lib/longbow/plist.rb
CHANGED
@@ -1,23 +1,17 @@
|
|
1
|
-
$:.push File.expand_path('../', __FILE__)
|
2
|
-
require 'mini_magick'
|
3
|
-
require 'colors'
|
4
|
-
require 'xcodeproj'
|
5
|
-
require 'open-uri'
|
6
|
-
|
7
1
|
module Longbow
|
8
2
|
|
9
3
|
# Create Plist from Original Plist Content
|
10
4
|
def self.create_plist_from_old_plist old_plist, info_hash, global_hash
|
11
5
|
return '' unless old_plist && info_hash && global_hash
|
12
6
|
plist_text = old_plist
|
13
|
-
[info_hash
|
7
|
+
[global_hash,info_hash].each do |hash|
|
14
8
|
hash.each_key do |k|
|
15
9
|
value = hash[k]
|
16
10
|
matches = plist_text.match /<key>#{k}<\/key>\s*<(.*?)>.*<\/(.*?)>/
|
17
11
|
if matches
|
18
|
-
plist_text = plist_text.sub(matches[0], "<key>" + k + "</key>\n" + recursive_plist_value_for_value(value))
|
12
|
+
plist_text = plist_text.sub(matches[0], "<key>" + k + "</key>\n" + recursive_plist_value_for_value(value) + "\n")
|
19
13
|
else
|
20
|
-
plist_text = plist_text.sub(/<\/dict>\s*<\/plist>/, "<key>" + k + "</key>\n" + recursive_plist_value_for_value(value) + "</dict></plist>")
|
14
|
+
plist_text = plist_text.sub(/<\/dict>\s*<\/plist>/, "<key>" + k + "</key>\n" + recursive_plist_value_for_value(value) + "\n</dict></plist>")
|
21
15
|
end
|
22
16
|
end
|
23
17
|
end
|
data/lib/longbow/targets.rb
CHANGED
@@ -4,7 +4,7 @@ require 'plist'
|
|
4
4
|
|
5
5
|
module Longbow
|
6
6
|
|
7
|
-
def self.update_target directory, target, global_keys, info_keys
|
7
|
+
def self.update_target directory, target, global_keys, info_keys, icon, launch
|
8
8
|
unless directory && target
|
9
9
|
Longbow::red ' Invalid parameters. Could not create/update target named: ' + target
|
10
10
|
return false
|
@@ -25,7 +25,8 @@ module Longbow
|
|
25
25
|
proj.targets.each do |t|
|
26
26
|
if t.to_s == target
|
27
27
|
@target = t
|
28
|
-
Longbow::
|
28
|
+
Longbow::blue ' ' + target + ' found.' unless $nolog
|
29
|
+
break
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
@@ -58,7 +59,8 @@ module Longbow
|
|
58
59
|
|
59
60
|
# Plist & Icons
|
60
61
|
settings['INFOPLIST_FILE'] = main_plist.split('/')[0] + '/' + target + '-info.plist'
|
61
|
-
settings['ASSETCATALOG_COMPILER_APPICON_NAME'] = target
|
62
|
+
settings['ASSETCATALOG_COMPILER_APPICON_NAME'] = target if icon
|
63
|
+
settings['ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME'] = target if launch
|
62
64
|
|
63
65
|
if File.exists? directory + '/Pods'
|
64
66
|
settings['PODS_ROOT'] = '${SRCROOT}/Pods'
|
@@ -97,7 +99,7 @@ module Longbow
|
|
97
99
|
end
|
98
100
|
end
|
99
101
|
|
100
|
-
Longbow::
|
102
|
+
Longbow::blue ' ' + target + ' created.' unless $nolog
|
101
103
|
else
|
102
104
|
puts
|
103
105
|
Longbow::red ' Target Creation failed for target named: ' + target
|
data/lib/longbow/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: longbow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Intermark Interactive
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -122,10 +122,8 @@ dependencies:
|
|
122
122
|
- - '>='
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
-
description:
|
126
|
-
|
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 '
|
125
|
+
description: One codebase. Multiple App Store submission targets with different icons,
|
126
|
+
launch images, info.plist keys, etc.
|
129
127
|
email:
|
130
128
|
- interactive@intermarkgroup.com
|
131
129
|
executables:
|
@@ -145,9 +143,6 @@ files:
|
|
145
143
|
- ./lib/longbow/version.rb
|
146
144
|
- ./lib/longbow.rb
|
147
145
|
- ./LICENSE.txt
|
148
|
-
- ./longbow-0.0.1.gem
|
149
|
-
- ./longbow-0.0.2.gem
|
150
|
-
- ./longbow.gemspec
|
151
146
|
- ./Rakefile
|
152
147
|
- ./README.md
|
153
148
|
- ./resources/banner.png
|
data/longbow-0.0.1.gem
DELETED
Binary file
|
data/longbow-0.0.2.gem
DELETED
Binary file
|
data/longbow.gemspec
DELETED
@@ -1,35 +0,0 @@
|
|
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
|