snapshot 0.10.2 → 1.0.1
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.
- checksums.yaml +4 -4
- data/README.md +92 -333
- data/bin/snapshot +11 -28
- data/lib/assets/SnapfileTemplate +14 -33
- data/lib/assets/SnapshotHelper.swift +50 -0
- data/lib/snapshot.rb +23 -4
- data/lib/snapshot/collector.rb +72 -0
- data/lib/snapshot/dependency_checker.rb +14 -26
- data/lib/snapshot/detect_values.rb +33 -0
- data/lib/snapshot/error_handler.rb +31 -0
- data/lib/snapshot/latest_ios_version.rb +9 -4
- data/lib/snapshot/options.rb +98 -0
- data/lib/snapshot/page.html.erb +1 -1
- data/lib/snapshot/reports_generator.rb +33 -37
- data/lib/snapshot/reset_simulators.rb +4 -4
- data/lib/snapshot/runner.rb +59 -246
- data/lib/snapshot/screenshot_flatten.rb +2 -2
- data/lib/snapshot/screenshot_rotate.rb +7 -9
- data/lib/snapshot/setup.rb +33 -0
- data/lib/snapshot/test_command_generator.rb +93 -0
- data/lib/snapshot/version.rb +2 -1
- metadata +83 -13
- data/lib/assets/SnapshotHelper.js +0 -63
- data/lib/assets/snapshot.js +0 -9
- data/lib/snapshot/builder.rb +0 -85
- data/lib/snapshot/simulators.rb +0 -40
- data/lib/snapshot/snapfile_creator.rb +0 -21
- data/lib/snapshot/snapshot_config.rb +0 -233
- data/lib/snapshot/snapshot_file.rb +0 -87
data/bin/snapshot
CHANGED
|
@@ -4,12 +4,9 @@ $:.push File.expand_path("../../lib", __FILE__)
|
|
|
4
4
|
|
|
5
5
|
require 'snapshot'
|
|
6
6
|
require 'commander'
|
|
7
|
-
require 'snapshot/snapfile_creator'
|
|
8
|
-
require 'snapshot/snapshot_config'
|
|
9
7
|
|
|
10
8
|
HighLine.track_eof = false
|
|
11
9
|
|
|
12
|
-
|
|
13
10
|
class SnapshotApplication
|
|
14
11
|
include Commander::Methods
|
|
15
12
|
|
|
@@ -21,38 +18,23 @@ class SnapshotApplication
|
|
|
21
18
|
program :help, 'GitHub', 'https://github.com/krausefx/snapshot'
|
|
22
19
|
program :help_formatter, :compact
|
|
23
20
|
|
|
24
|
-
global_option
|
|
25
|
-
global_option '--nobuild', 'Skips the build process when running snapshot.'
|
|
26
|
-
global_option '--noclean', 'Skips the clean process of the build command when running snapshot.'
|
|
27
|
-
global_option('--verbose', 'Shows more output including all output printed by Instruments.') { $verbose = true }
|
|
21
|
+
global_option('--verbose', 'Shows a more verbose output') { $verbose = true }
|
|
28
22
|
|
|
29
23
|
always_trace!
|
|
30
24
|
|
|
25
|
+
FastlaneCore::CommanderGenerator.new.generate(Snapshot::Options.available_options)
|
|
26
|
+
|
|
31
27
|
command :run do |c|
|
|
32
28
|
c.syntax = 'snapshot'
|
|
33
29
|
c.description = 'Take new screenshots based on the Snapfile.'
|
|
34
30
|
|
|
35
31
|
c.action do |args, options|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Snapshot::SnapshotConfig.shared_instance(options.snapfile)
|
|
40
|
-
Snapshot::Runner.new.work(clean: !options.noclean, build: !options.nobuild)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
command :test do |c|
|
|
46
|
-
c.syntax = 'snapshot test'
|
|
47
|
-
c.description = 'Runs the automated tests.'
|
|
32
|
+
o = options.__hash__.dup
|
|
33
|
+
o.delete(:verbose)
|
|
34
|
+
Snapshot.config = FastlaneCore::Configuration.create(Snapshot::Options.available_options, o)
|
|
48
35
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Dir.chdir(path) do # switch the context
|
|
52
|
-
Snapshot::DependencyChecker.check_simulators
|
|
53
|
-
Snapshot::SnapshotConfig.shared_instance(options.snapfile)
|
|
54
|
-
Snapshot::Runner.new.work(clean: !options.noclean, build: !options.nobuild, take_snapshots: false)
|
|
55
|
-
end
|
|
36
|
+
Snapshot::DependencyChecker.check_simulators
|
|
37
|
+
Snapshot::Runner.new.work
|
|
56
38
|
end
|
|
57
39
|
end
|
|
58
40
|
|
|
@@ -61,8 +43,9 @@ class SnapshotApplication
|
|
|
61
43
|
c.description = "Creates a new Snapfile in the current directory"
|
|
62
44
|
|
|
63
45
|
c.action do |args, options|
|
|
64
|
-
|
|
65
|
-
Snapshot::
|
|
46
|
+
require 'snapshot/setup'
|
|
47
|
+
path = (Snapshot::Helper.fastlane_enabled? ? './fastlane' : '.')
|
|
48
|
+
Snapshot::Setup.create(path)
|
|
66
49
|
end
|
|
67
50
|
end
|
|
68
51
|
|
data/lib/assets/SnapfileTemplate
CHANGED
|
@@ -6,45 +6,26 @@ devices([
|
|
|
6
6
|
"iPhone 6 Plus",
|
|
7
7
|
"iPhone 5",
|
|
8
8
|
"iPhone 4s",
|
|
9
|
-
"iPad
|
|
9
|
+
"iPad Retina"
|
|
10
10
|
])
|
|
11
11
|
|
|
12
12
|
languages([
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
"en-US",
|
|
14
|
+
"de-DE",
|
|
15
|
+
"it-IT"
|
|
16
16
|
])
|
|
17
17
|
|
|
18
|
-
#
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# clear_previous_screenshots # remove the '#'' to clear all previously generated screenshots before creating new ones
|
|
22
|
-
|
|
23
|
-
# JavaScript UIAutomation file
|
|
24
|
-
# js_file './snapshot.js'
|
|
25
|
-
|
|
26
|
-
# The name of the project's scheme
|
|
27
|
-
# scheme 'SchemeName'
|
|
28
|
-
|
|
29
|
-
# Where is your project (or workspace)? Provide the full path here
|
|
30
|
-
# project_path './YourProject.xcworkspace'
|
|
31
|
-
|
|
32
|
-
# By default, the latest version should be used automatically. If you want to change it, do it here
|
|
33
|
-
# ios_version '8.1'
|
|
34
|
-
|
|
35
|
-
# Comment out the line below to add a `SNAPSHOT` preprocessor macro
|
|
36
|
-
# More information available: https://github.com/krausefx/snapshot#custom-args-for-the-build-command
|
|
37
|
-
# custom_build_args "GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SNAPSHOT=1' OTHER_SWIFT_FLAGS='$(inherited) -D SNAPSHOT'"
|
|
18
|
+
# The name of the scheme which contains the UI Tests
|
|
19
|
+
# scheme "SchemeName"
|
|
38
20
|
|
|
21
|
+
# Where should the resulting screenshots be stored?
|
|
22
|
+
# screenshots_path "./screenshots"
|
|
39
23
|
|
|
40
|
-
#
|
|
24
|
+
# clear_previous_screenshots # remove the '#' to clear all previously generated screenshots before creating new ones
|
|
41
25
|
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# end
|
|
26
|
+
# Choose which project/workspace to use
|
|
27
|
+
# project "./Project.xcodeproj"
|
|
28
|
+
# workspace "./Project.xcworkspace"
|
|
46
29
|
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# system("./cleanup.sh")
|
|
50
|
-
# end
|
|
30
|
+
# For more information about all available options run
|
|
31
|
+
# snapshot --help
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//
|
|
2
|
+
// SnapshotHelper.swift
|
|
3
|
+
// Example
|
|
4
|
+
//
|
|
5
|
+
// Created by Felix Krause on 10/8/15.
|
|
6
|
+
// Copyright © 2015 Felix Krause. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
import XCTest
|
|
11
|
+
|
|
12
|
+
var deviceLanguage = ""
|
|
13
|
+
|
|
14
|
+
func setLanguage(app: XCUIApplication)
|
|
15
|
+
{
|
|
16
|
+
let path = "/tmp/language.txt"
|
|
17
|
+
|
|
18
|
+
do {
|
|
19
|
+
let locale = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding) as String
|
|
20
|
+
deviceLanguage = locale
|
|
21
|
+
app.launchArguments = ["-AppleLanguages", "(\(locale))"]
|
|
22
|
+
} catch {
|
|
23
|
+
print("Couldn't detect/set language...")
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
func snapshot(name: String, waitForLoadingIndicator: Bool = true)
|
|
28
|
+
{
|
|
29
|
+
if (waitForLoadingIndicator)
|
|
30
|
+
{
|
|
31
|
+
waitForLoadingIndicatorToDisappear()
|
|
32
|
+
}
|
|
33
|
+
print("snapshot: \(name)") // more information about this, check out https://github.com/krausefx/snapshot
|
|
34
|
+
|
|
35
|
+
let view = XCUIApplication()
|
|
36
|
+
let start = view.coordinateWithNormalizedOffset(CGVectorMake(32.10, 30000))
|
|
37
|
+
let finish = view.coordinateWithNormalizedOffset(CGVectorMake(31, 30000))
|
|
38
|
+
start.pressForDuration(0, thenDragToCoordinate: finish)
|
|
39
|
+
sleep(1)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func waitForLoadingIndicatorToDisappear()
|
|
43
|
+
{
|
|
44
|
+
let query = XCUIApplication().statusBars.childrenMatchingType(.Other).elementBoundByIndex(1).childrenMatchingType(.Other)
|
|
45
|
+
|
|
46
|
+
while (query.count > 4) {
|
|
47
|
+
sleep(1)
|
|
48
|
+
print("Number of Elements in Status Bar: \(query.count)... waiting for status bar to disappear")
|
|
49
|
+
}
|
|
50
|
+
}
|
data/lib/snapshot.rb
CHANGED
|
@@ -1,18 +1,37 @@
|
|
|
1
1
|
require 'snapshot/version'
|
|
2
|
-
require 'snapshot/snapshot_config'
|
|
3
2
|
require 'snapshot/runner'
|
|
4
|
-
require 'snapshot/builder'
|
|
5
|
-
require 'snapshot/snapshot_file'
|
|
6
3
|
require 'snapshot/reports_generator'
|
|
4
|
+
require 'snapshot/detect_values'
|
|
7
5
|
require 'snapshot/screenshot_flatten'
|
|
8
6
|
require 'snapshot/screenshot_rotate'
|
|
9
|
-
require 'snapshot/simulators'
|
|
10
7
|
require 'snapshot/dependency_checker'
|
|
11
8
|
require 'snapshot/latest_ios_version'
|
|
9
|
+
require 'snapshot/test_command_generator'
|
|
10
|
+
require 'snapshot/error_handler'
|
|
11
|
+
require 'snapshot/collector'
|
|
12
|
+
require 'snapshot/options'
|
|
12
13
|
|
|
13
14
|
require 'fastlane_core'
|
|
14
15
|
|
|
16
|
+
require 'open3'
|
|
17
|
+
|
|
15
18
|
module Snapshot
|
|
19
|
+
# Use this to just setup the configuration attribute and set it later somewhere else
|
|
20
|
+
class << self
|
|
21
|
+
attr_accessor :config
|
|
22
|
+
|
|
23
|
+
attr_accessor :project
|
|
24
|
+
|
|
25
|
+
def config=(value)
|
|
26
|
+
@config = value
|
|
27
|
+
DetectValues.set_additional_default_values
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def snapfile_name
|
|
31
|
+
"Snapfile"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
16
35
|
Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
|
|
17
36
|
|
|
18
37
|
Snapshot::DependencyChecker.check_dependencies
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Snapshot
|
|
2
|
+
# Responsible for collecting the generated screenshots and copying them over to the output directory
|
|
3
|
+
class Collector
|
|
4
|
+
def self.fetch_screenshots(output, language, device_type)
|
|
5
|
+
# Documentation about how this works in the project README
|
|
6
|
+
containing = File.join(TestCommandGenerator.derived_data_path, "Logs", "Test")
|
|
7
|
+
attachments_path = File.join(containing, "Attachments")
|
|
8
|
+
|
|
9
|
+
to_store = attachments(containing)
|
|
10
|
+
matches = output.scan(/snapshot: (.*)/)
|
|
11
|
+
|
|
12
|
+
if matches.count != to_store.count
|
|
13
|
+
Helper.log.error "Looks like the number of screenshots (#{to_store.count}) doesn't match the number of names (#{matches.count})"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
matches.each_with_index do |current, index|
|
|
17
|
+
name = current[0]
|
|
18
|
+
filename = to_store[index]
|
|
19
|
+
|
|
20
|
+
language_folder = File.join(Snapshot.config[:output_directory], language)
|
|
21
|
+
FileUtils.mkdir_p(language_folder)
|
|
22
|
+
|
|
23
|
+
device_name = device_type.delete(" ")
|
|
24
|
+
output_path = File.join(language_folder, [device_name, name].join("-") + ".png")
|
|
25
|
+
from_path = File.join(attachments_path, filename)
|
|
26
|
+
if $verbose
|
|
27
|
+
Helper.log.info "Copying file '#{from_path}' to '#{output_path}'...".green
|
|
28
|
+
else
|
|
29
|
+
Helper.log.info "Copying '#{output_path}'...".green
|
|
30
|
+
end
|
|
31
|
+
FileUtils.cp(from_path, output_path)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.attachments(containing)
|
|
36
|
+
Helper.log.info "Collecting screenshots..."
|
|
37
|
+
|
|
38
|
+
plist_path = Dir[File.join(containing, "*.plist")].last # we clean the folder before each run
|
|
39
|
+
Helper.log.info "Loading up '#{plist_path}'..." if $verbose
|
|
40
|
+
report = Plist.parse_xml(plist_path)
|
|
41
|
+
|
|
42
|
+
activities = []
|
|
43
|
+
report["TestableSummaries"].each do |summary|
|
|
44
|
+
(summary["Tests"] || []).each do |test|
|
|
45
|
+
(test["Subtests"] || []).each do |subtest|
|
|
46
|
+
(subtest["Subtests"] || []).each do |subtest2|
|
|
47
|
+
(subtest2["Subtests"] || []).each do |subtest3|
|
|
48
|
+
(subtest3["ActivitySummaries"] || []).each do |activity|
|
|
49
|
+
# We now check if it's the drag gesture with a negative value
|
|
50
|
+
was_snapshot = activity["Title"].match(/Press and drag from Target Application.*\[32.10.*\].*/)
|
|
51
|
+
activities << activity if was_snapshot
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
Helper.log.info "Found #{activities.count} screenshots..."
|
|
60
|
+
|
|
61
|
+
to_store = [] # contains the names of all the attachments we want to use
|
|
62
|
+
activities.each do |activity|
|
|
63
|
+
# We do care about this, all "Long press Target" events mean screenshots
|
|
64
|
+
attachment_entry = activity["SubActivities"].last # the latest event is fine
|
|
65
|
+
to_store << attachment_entry["Attachments"].last["FileName"]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
Helper.log.info "Found #{to_store.join(', ')}" if $verbose
|
|
69
|
+
return to_store
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -2,13 +2,11 @@ module Snapshot
|
|
|
2
2
|
class DependencyChecker
|
|
3
3
|
def self.check_dependencies
|
|
4
4
|
self.check_xcode_select
|
|
5
|
-
self.check_xctool
|
|
6
|
-
self.check_for_automation_subfolder
|
|
7
5
|
self.check_simctl
|
|
8
6
|
end
|
|
9
7
|
|
|
10
8
|
def self.check_xcode_select
|
|
11
|
-
unless `xcode-select -v`.include?"xcode-select version
|
|
9
|
+
unless `xcode-select -v`.include? "xcode-select version"
|
|
12
10
|
Helper.log.fatal '#############################################################'
|
|
13
11
|
Helper.log.fatal "# You have to install the Xcode commdand line tools to use snapshot"
|
|
14
12
|
Helper.log.fatal "# Install the latest version of Xcode from the AppStore"
|
|
@@ -16,11 +14,21 @@ module Snapshot
|
|
|
16
14
|
Helper.log.fatal '#############################################################'
|
|
17
15
|
raise "Run 'xcode-select --install' and start snapshot again"
|
|
18
16
|
end
|
|
17
|
+
|
|
18
|
+
if Snapshot::LatestIosVersion.version.to_f < 9 # to_f is bad, but should be good enough
|
|
19
|
+
Helper.log.fatal '#############################################################'
|
|
20
|
+
Helper.log.fatal "# Your xcode-select Xcode version is below 9.0"
|
|
21
|
+
Helper.log.fatal "# To use snapshot 1.0 and above you need at leat iOS 9"
|
|
22
|
+
Helper.log.fatal "# Set the path to the Xcode version that supports UI Tests"
|
|
23
|
+
Helper.log.fatal "# or downgrade to versions older than snapshot 1.0"
|
|
24
|
+
Helper.log.fatal '#############################################################'
|
|
25
|
+
raise "Run 'sudo xcode-select -s /Applications/Xcode-beta.app'"
|
|
26
|
+
end
|
|
19
27
|
end
|
|
20
28
|
|
|
21
29
|
def self.check_simulators
|
|
22
|
-
Helper.log.debug "Found #{
|
|
23
|
-
if
|
|
30
|
+
Helper.log.debug "Found #{FastlaneCore::Simulator.all.count} simulators." if $verbose
|
|
31
|
+
if FastlaneCore::Simulator.all.count == 0
|
|
24
32
|
Helper.log.fatal '#############################################################'
|
|
25
33
|
Helper.log.fatal "# You have to add new simulators using Xcode"
|
|
26
34
|
Helper.log.fatal "# You can let snapshot create new simulators: 'snapshot reset_simulators'"
|
|
@@ -31,28 +39,8 @@ module Snapshot
|
|
|
31
39
|
end
|
|
32
40
|
end
|
|
33
41
|
|
|
34
|
-
def self.xctool_installed?
|
|
35
|
-
return `which xctool`.length > 1
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def self.check_xctool
|
|
39
|
-
if not self.xctool_installed?
|
|
40
|
-
Helper.log.info '#############################################################'
|
|
41
|
-
Helper.log.info "# xctool is recommended to build the apps"
|
|
42
|
-
Helper.log.info "# Install it using 'brew install xctool'"
|
|
43
|
-
Helper.log.info "# Falling back to xcodebuild instead "
|
|
44
|
-
Helper.log.info '#############################################################'
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def self.check_for_automation_subfolder
|
|
49
|
-
if File.directory?"./Automation" or File.exists?"./Automation"
|
|
50
|
-
raise "Seems like you have an 'Automation' folder in the current directory. You need to delete/rename it!".red
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
42
|
def self.check_simctl
|
|
55
|
-
unless `xcrun simctl`.include?"openurl"
|
|
43
|
+
unless `xcrun simctl`.include? "openurl"
|
|
56
44
|
raise "Could not find `xcrun simctl`. Make sure you have the latest version of Xcode and Mac OS installed.".red
|
|
57
45
|
end
|
|
58
46
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Snapshot
|
|
2
|
+
class DetectValues
|
|
3
|
+
# This is needed as these are more complex default values
|
|
4
|
+
def self.set_additional_default_values
|
|
5
|
+
config = Snapshot.config
|
|
6
|
+
|
|
7
|
+
FastlaneCore::Project.detect_projects(config)
|
|
8
|
+
|
|
9
|
+
Snapshot.project = FastlaneCore::Project.new(config)
|
|
10
|
+
|
|
11
|
+
# Go into the project's folder
|
|
12
|
+
Dir.chdir(File.expand_path("..", Snapshot.project.path)) do
|
|
13
|
+
config.load_configuration_file(Snapshot.snapfile_name)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Snapshot.project.select_scheme
|
|
17
|
+
|
|
18
|
+
# Devices
|
|
19
|
+
unless config[:devices]
|
|
20
|
+
config[:devices] = []
|
|
21
|
+
|
|
22
|
+
# We only care about a subset of the simulators
|
|
23
|
+
FastlaneCore::Simulator.all.each do |sim|
|
|
24
|
+
next if sim.name.include?("iPad") and !sim.name.include?("Retina") # we only need one iPad
|
|
25
|
+
next if sim.name.include?("6s") # same screen resolution
|
|
26
|
+
next if sim.name.include?("5s") # same screen resolution
|
|
27
|
+
|
|
28
|
+
config[:devices] << sim.name
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Snapshot
|
|
2
|
+
# This classes methods are called when something goes wrong in the building process
|
|
3
|
+
class ErrorHandler
|
|
4
|
+
class TestsFailedException < StandardError
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
# @param [Array] The output of the errored build (line by line)
|
|
9
|
+
# This method should raise an exception in any case, as the return code indicated a failed build
|
|
10
|
+
def handle_test_error(output, return_code)
|
|
11
|
+
# The order of the handling below is import
|
|
12
|
+
|
|
13
|
+
if return_code == 65
|
|
14
|
+
raise TestsFailedException.new, "Tests failed - check out the log above".red
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
case output
|
|
18
|
+
when /com\.apple\.CoreSimulator\.SimError/
|
|
19
|
+
print "The simulator failed to launch - retrying..."
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# Just to make things easier
|
|
26
|
+
def print(text)
|
|
27
|
+
Helper.log.error text.red
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -5,9 +5,14 @@ module Snapshot
|
|
|
5
5
|
return ENV["SNAPSHOT_IOS_VERSION"] if ENV["SNAPSHOT_IOS_VERSION"]
|
|
6
6
|
return @version if @version
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
# We do all this, because we would get all kind of crap output generated by xcodebuild
|
|
9
|
+
# so we need to ignore stderror
|
|
10
|
+
output = ''
|
|
11
|
+
Open3.popen3('xcodebuild -version -sdk') do |stdin, stdout, stderr, wait_thr|
|
|
12
|
+
output = stdout.read
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
matched = output.match(/iOS ([\d\.]+) \(.*/)
|
|
11
16
|
if matched.length > 1
|
|
12
17
|
return @version ||= matched[1]
|
|
13
18
|
else
|
|
@@ -15,4 +20,4 @@ module Snapshot
|
|
|
15
20
|
end
|
|
16
21
|
end
|
|
17
22
|
end
|
|
18
|
-
end
|
|
23
|
+
end
|