longbow-fdv 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,121 @@
1
+ require 'xcodeproj'
2
+ require 'colors'
3
+ require 'plist'
4
+ require 'utilities'
5
+
6
+ module Longbow
7
+
8
+ def self.update_target directory, target, global_keys, info_keys, icon, launch
9
+ unless directory && target
10
+ Longbow::red ' Invalid parameters. Could not create/update target named: ' + target
11
+ return false
12
+ end
13
+
14
+ # Find Project File
15
+ project_paths = []
16
+ Dir.foreach(directory) do |fname|
17
+ project_paths << fname if fname.include? '.xcodeproj'
18
+ end
19
+
20
+ # Open The Project
21
+ return false if project_paths.length == 0
22
+ proj = Xcodeproj::Project.open(project_paths[0])
23
+
24
+ # Get Main Target's Basic Info
25
+ @target = nil
26
+ proj.targets.each do |t|
27
+ if t.to_s == target
28
+ @target = t
29
+ Longbow::blue ' ' + target + ' found.' unless $nolog
30
+ break
31
+ end
32
+ end
33
+
34
+ #puts proj.pretty_print
35
+
36
+ # Create Target if Necessary
37
+ main_target = proj.targets.first
38
+ @target = create_target(proj, target) unless @target
39
+
40
+ # Plist Creating/Adding
41
+ main_plist = main_target.build_configurations[0].build_settings['INFOPLIST_FILE']
42
+
43
+ main_plist.sub! '$(SRCROOT)/', ''
44
+ main_plist_contents = File.read(directory + '/' + main_plist)
45
+ target_plist_path = directory + '/' + main_plist.split('/')[0] + '/' + target + '-info.plist'
46
+ plist_text = Longbow::create_plist_from_old_plist main_plist_contents, info_keys, global_keys
47
+ File.open(target_plist_path, 'w') do |f|
48
+ f.write(plist_text)
49
+ end
50
+ Longbow::green ' - ' + target + '-info.plist Updated.' unless $nolog
51
+
52
+ # Add Build Settings
53
+ @target.build_configurations.each do |b|
54
+ # Main Settings
55
+ main_settings = nil
56
+ base_config = nil
57
+ main_target.build_configurations.each do |bc|
58
+ main_settings = bc.build_settings if bc.to_s == b.to_s
59
+ base_config = bc.base_configuration_reference if bc.to_s == b.to_s
60
+ end
61
+ settings = b.build_settings
62
+
63
+ if main_settings
64
+ main_settings.each_key do |key|
65
+ settings[key] = main_settings[key]
66
+ end
67
+ end
68
+ # Plist & Icons
69
+ settings['INFOPLIST_FILE'] = main_plist.split('/')[0] + '/' + target + '-info.plist'
70
+ settings['ASSETCATALOG_COMPILER_APPICON_NAME'] = Longbow::stripped_text(target) if icon
71
+ settings['ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME'] = Longbow::stripped_text(target) if launch
72
+ settings['SKIP_INSTALL'] = 'NO'
73
+
74
+ if File.exists? directory + '/Pods'
75
+ b.base_configuration_reference = base_config
76
+ settings['PODS_ROOT'] = '${SRCROOT}/Pods'
77
+ end
78
+ end
79
+
80
+ # Save The Project
81
+ proj.save
82
+ end
83
+
84
+ def self.create_target project, target
85
+ main_target = project.targets.first
86
+ deployment_target = main_target.deployment_target
87
+
88
+ # Create New Target
89
+ new_target = Xcodeproj::Project::ProjectHelper.new_target project, :application, target, :ios, deployment_target, project.products_group, 'en'
90
+ if new_target
91
+ # Add Build Phases
92
+ main_target.build_phases.objects.each do |b|
93
+ if b.isa == 'PBXSourcesBuildPhase'
94
+ b.files_references.each do |f|
95
+ new_target.source_build_phase.add_file_reference f
96
+ end
97
+ elsif b.isa == 'PBXFrameworksBuildPhase'
98
+ b.files_references.each do |f|
99
+ new_target.frameworks_build_phase.add_file_reference f
100
+ end
101
+ elsif b.isa == 'PBXResourcesBuildPhase'
102
+ b.files_references.each do |f|
103
+ new_target.resources_build_phase.add_file_reference f
104
+ end
105
+ elsif b.isa == 'PBXShellScriptBuildPhase'
106
+ phase = new_target.new_shell_script_build_phase(name = b.display_name)
107
+ phase.shell_script = b.shell_script
108
+ end
109
+ end
110
+
111
+ Longbow::blue ' ' + target + ' created.' unless $nolog
112
+ else
113
+ puts
114
+ Longbow::red ' Target Creation failed for target named: ' + target
115
+ puts
116
+ end
117
+
118
+ return new_target
119
+ end
120
+
121
+ end
@@ -0,0 +1,8 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+
3
+ module Longbow
4
+ # Strip Non-Alphanumerics
5
+ def self.stripped_text text
6
+ return text.gsub(/[^0-9a-z ]/i, '')
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+ require 'colors'
3
+
4
+ module Longbow
5
+ VERSION = '0.1.0'
6
+
7
+ def self.check_for_newer_version
8
+ unless Gem.latest_version_for('longbow').to_s == VERSION
9
+ Longbow::purple "\n A newer version of longbow is available. Run '[sudo] gem update longbow'."
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ #!/bin/bash
2
+ set -e # Bomb on any script errors
3
+ target_string="$1"
4
+ verbose=false
5
+ if [ -n "$2" ]; then
6
+ verbose=true
7
+ fi
8
+
9
+ function main {
10
+ # Get targets into an array, run 'em
11
+ IFS=',' read -a targets <<< "$target_string"
12
+ for target in "${targets[@]}"; do
13
+ _run_target $target;
14
+ done
15
+ # Remove files added by ruby script
16
+ rm "capture.js"
17
+ rm "config-screenshots.sh"
18
+ rm "ui-screen-shooter.sh"
19
+ rm "unix_instruments.sh"
20
+ }
21
+
22
+ function _run_target {
23
+ echo " Running $1"
24
+ if [ "$verbose" = true ]; then
25
+ source ui-screen-shooter.sh "$HOME/Desktop/screenshots/$1" "$1"
26
+ else
27
+ source ui-screen-shooter.sh "$HOME/Desktop/screenshots/$1" "$1" >/dev/null 2>/dev/null
28
+ fi
29
+ }
30
+
31
+ main
Binary file
@@ -0,0 +1,84 @@
1
+ // Copyright (c) 2012 Jonathan Penn (http://cocoamanifest.net/)
2
+
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ var kPortraitString = "portrait"
22
+ var kLandscapeString = "landscape"
23
+
24
+ var kMaxDimension4inch = 568;
25
+ var kMaxDimension4point7inch = 667;
26
+ var kMaxDimension5point5inch = 736;
27
+
28
+ // rectMaxSizeMatchesPhoneWithMaxDimensionForOrientation(rect, maxDimension, orientation)
29
+ //
30
+ // Returns whether the given rect matches a given max dimension in a particular orientation.
31
+ //
32
+ // `rect` is the rectangle representing the image size you want to check
33
+ // `maxDimension` is the size of the longest side of the screen on a given device
34
+ // `orientation` is...well...duh!
35
+ //
36
+ function rectMaxSizeMatchesPhoneWithMaxDimensionForOrientation(rect, maxDimension, orientation) {
37
+ return (orientation == kPortraitString && rect.size.height == maxDimension) || (orientation == kLandscapeString && rect.size.width == maxDimension)
38
+ }
39
+
40
+ // captureLocalizedScreenshot(name)
41
+ //
42
+ // Tells the local target to take a screen shot and names the file after the
43
+ // state of the simulator like so:
44
+ //
45
+ // [model]___[orientation]___[name].png
46
+ //
47
+ // `model` is the model of the device (iphone, iphone5, ipad)
48
+ // `orientation` is...well...duh!
49
+ // `name` is what you passed in to the function
50
+ //
51
+ // Screenshots are saved along with the trace results in UI Automation. See
52
+ // `run_screenshooter.sh` for examples on how to pull those images out and put
53
+ // them wherever you want.
54
+ //
55
+ function captureLocalizedScreenshot(name) {
56
+ var target = UIATarget.localTarget();
57
+ var model = target.model();
58
+ var rect = target.rect();
59
+
60
+ var orientation = kPortraitString;
61
+ if (rect.size.height < rect.size.width) {
62
+ orientation = kLandscapeString;
63
+ }
64
+
65
+ if (model.match(/iPhone/)) {
66
+ if (rectMaxSizeMatchesPhoneWithMaxDimensionForOrientation(rect, kMaxDimension4inch, orientation)) {
67
+ model = "iOS-4-in";
68
+ }
69
+ else if (rectMaxSizeMatchesPhoneWithMaxDimensionForOrientation(rect, kMaxDimension4point7inch, orientation)) {
70
+ model = "iOS-4.7-in";
71
+ }
72
+ else if (rectMaxSizeMatchesPhoneWithMaxDimensionForOrientation(rect, kMaxDimension5point5inch, orientation)) {
73
+ model = "iOS-5.5-in";
74
+ }
75
+ else {
76
+ model = "iOS-3.5-in";
77
+ }
78
+ } else {
79
+ model = "iOS-iPad";
80
+ }
81
+
82
+ var parts = [model, orientation, name];
83
+ target.captureScreenWithName(parts.join("___"));
84
+ }
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ # This is an example configuration file to be used with ui-screen-shooter
3
+ # It is designed to work with the Hello World International application
4
+ # Please copy to config-screenshots.sh and edit for your needs
5
+
6
+
7
+ # LOCALE
8
+ # ======
9
+ # Set the locales here in which your screenshots should be made.
10
+ # Use format like en-US zh-Hans for filenames compatible with iTMSTransporter
11
+ # Note: to get the locale names for your existing app:
12
+ # - Download .itmsp file with iTMSTransporter
13
+ # - Run `grep locale ~/Desktop/*.itmsp/metadata.xml | grep name | sort -u`
14
+
15
+ export languages="en-US"
16
+
17
+
18
+ # SIMULATORS
19
+ # ==========
20
+ # The simulators we want to run the script against, declared as a Bash array.
21
+ # Run `instruments -s devices` to get a list of all the possible string values.
22
+
23
+ declare -xa simulators=(
24
+ "iPhone 6 (8.1 Simulator)",
25
+ "iPhone 6 Plus (8.1 Simulator)",
26
+ "iPhone 5S (8.1 Simulator)",
27
+ "iPhone 4S (8.1 Simulator)"
28
+ )
@@ -0,0 +1,206 @@
1
+ #!/bin/bash
2
+ # Copyright (c) 2012 Jonathan Penn (http://cocoamanifest.net/)
3
+
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+
22
+
23
+ # Tell bash that we want the whole script to fail if any part fails.
24
+ set -e
25
+
26
+ # We require a parameter for where to put the results and the test script
27
+ destination="$1"
28
+ scheme_name="$2"
29
+ ui_script="$3"
30
+
31
+ function main {
32
+ # Load configuration
33
+ # Not in a separate function because you can't exort arrays
34
+ # https://stackoverflow.com/questions/5564418/exporting-an-array-in-bash-script
35
+ # Will export languages and simulators bash variables
36
+ export UISS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
37
+ if [ -f "$UISS_DIR"/config-screenshots.sh ]; then
38
+ source "$UISS_DIR"/config-screenshots.sh
39
+ else
40
+ if [ -f "$UISS_DIR"/config-screenshots.example.sh ]; then
41
+ source "$UISS_DIR"/config-screenshots.example.sh
42
+ echo "WARNING: Using example config-screenshots file, you should create your own"
43
+ else
44
+ echo "Configuration \"config-screenshots.sh\" does not exist! Aborting."
45
+ exit 1
46
+ fi
47
+ fi
48
+
49
+ _check_destination
50
+ _check_ui_script
51
+ _check_scheme_name
52
+ _xcode clean build
53
+
54
+ for simulator in "${simulators[@]}"; do
55
+ for language in $languages; do
56
+ _clean_trace_results_dir
57
+ _run_automation "$ui_script" "$language" "$simulator"
58
+ _copy_screenshots "$language"
59
+ done
60
+ done
61
+
62
+ _close_sim
63
+
64
+ echo
65
+ echo "Screenshots complete!"
66
+ }
67
+
68
+ # Global variables to keep track of where everything goes
69
+ tmp_dir="/tmp"
70
+ build_dir="$tmp_dir/screen_shooter"
71
+ bundle_dir="$build_dir/app.app"
72
+ trace_results_dir="$build_dir/traces"
73
+
74
+ function _check_destination {
75
+ # Abort if the destination directory already exists. Better safe than sorry.
76
+
77
+ if [ -z "$destination" ]; then
78
+ destination="$HOME/Desktop/screenshots"
79
+ fi
80
+ if [ -d "$destination" ]; then
81
+ echo "Destination directory \"$destination\" already exists! Moving Directory."
82
+ mv "$destination" "$HOME/Desktop/screenshots$(date +"%Y%m%d%H%M")"
83
+ fi
84
+ }
85
+
86
+ function _check_ui_script {
87
+ # Abort if the UI script does not exist.
88
+
89
+ if [ -z "$ui_script" ]; then
90
+ ui_script="./config-automation.js"
91
+ fi
92
+ if [ ! -f "$ui_script" ]; then
93
+ if [ -f "./config-automation.example.js" ]; then
94
+ ui_script="./config-automation.js"
95
+ echo "WARNING: Using example config-automation, please create your own"
96
+ else
97
+ echo "Config-automation does not exist! Aborting."
98
+ exit 1
99
+ fi
100
+ fi
101
+ }
102
+
103
+ function _check_scheme_name {
104
+ if [ -z "$scheme_name" ]; then
105
+ scheme_name=$(basename *.xcworkspace .xcworkspace)
106
+ echo "No scheme name specified, using the default."
107
+ fi
108
+ }
109
+
110
+ function _xcode {
111
+ # A wrapper around `xcodebuild` that tells it to build the app in the temp
112
+ # directory. If your app uses workspaces or special schemes, you'll need to
113
+ # specify them here.
114
+ #
115
+ # Use `man xcodebuild` for more information on how to build your project.
116
+ if test -n "$(find . -maxdepth 1 -name '*.xcworkspace' -print -quit)"
117
+ then
118
+ base=$(basename *.xcworkspace .xcworkspace)
119
+ # First build omits PRODUCT_NAME
120
+ # Do NOT ask me why you need to build this twice for it to work
121
+ # or how I became to know this fact
122
+ xcodebuild -sdk "iphonesimulator$ios_version" \
123
+ CONFIGURATION_BUILD_DIR="$build_dir/build" \
124
+ -workspace "$base.xcworkspace" -scheme "$scheme_name" -configuration Debug \
125
+ PRODUCT_NAME="$scheme_name" \
126
+ DSTROOT=$build_dir \
127
+ OBJROOT=$build_dir \
128
+ SYMROOT=$build_dir \
129
+ ONLY_ACTIVE_ARCH=NO \
130
+ "$@"
131
+ xcodebuild -sdk "iphonesimulator$ios_version" \
132
+ CONFIGURATION_BUILD_DIR="$build_dir/build" \
133
+ -workspace "$base.xcworkspace" -scheme "$scheme_name" -configuration Debug \
134
+ PRODUCT_NAME="$scheme_name" \
135
+ DSTROOT=$build_dir \
136
+ OBJROOT=$build_dir \
137
+ SYMROOT=$build_dir \
138
+ ONLY_ACTIVE_ARCH=NO \
139
+ "$@"
140
+ cp -r "$build_dir/build/$scheme_name.app" "$build_dir"
141
+ bundle_dir="$build_dir/$scheme_name.app"
142
+ else
143
+ xcodebuild -sdk "iphonesimulator$ios_version" \
144
+ CONFIGURATION_BUILD_DIR=$build_dir \
145
+ PRODUCT_NAME=app \
146
+ "$@"
147
+ fi
148
+ }
149
+
150
+ function _clean_trace_results_dir {
151
+ # Removes the trace results directory. We need to do this because Instruments
152
+ # keeps appending new trace runs and it's simpler for us to always assume
153
+ # there's just one run recorded where we look for screenshots.
154
+
155
+ rm -rf "$trace_results_dir"
156
+ mkdir -p "$trace_results_dir"
157
+ }
158
+
159
+ function _run_automation {
160
+ # Runs the UI Automation JavaScript file that actually takes the screenshots.
161
+
162
+ automation_script="$1"
163
+ language="$2"
164
+ simulator="$3"
165
+
166
+ echo "Running automation script \"$automation_script\"
167
+ for \"$simulator\"
168
+ in language \"${language}\"..."
169
+
170
+ dev_tools_dir=`xcode-select -print-path`
171
+ tracetemplate="Automation"
172
+
173
+ # Check out the `unix_instruments.sh` script to see why we need this wrapper.
174
+ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
175
+ "$DIR"/unix_instruments.sh \
176
+ -w "$simulator" \
177
+ -D "$trace_results_dir/trace" \
178
+ -t "$tracetemplate" \
179
+ "$bundle_dir" \
180
+ -e UIARESULTSPATH "$trace_results_dir" \
181
+ -e UIASCRIPT "$automation_script" \
182
+ -AppleLanguages "($language)" \
183
+ -AppleLocale "$language"
184
+
185
+ find $trace_results_dir/Run\ 1/ -name *landscape*png -type f -exec sips -r -90 \{\} \;
186
+ }
187
+
188
+ function _copy_screenshots {
189
+ # Since we're always clearing out the trace results before every run, we can
190
+ # assume that any screenshots were saved in the "Run 1" directory. Copy them
191
+ # to the destination's language folder!
192
+
193
+ language="$1"
194
+
195
+ mkdir -p "$destination/$language"
196
+ cp $trace_results_dir/Run\ 1/*.png "$destination/$language"
197
+ }
198
+
199
+ function _close_sim {
200
+ # I know, I know. It says "iPhone Simulator". For some reason,
201
+ # that's the only way Applescript can identify it.
202
+ osascript -e "tell application \"iPhone Simulator\" to quit"
203
+ }
204
+
205
+ main
206
+