From 0dc02d90c3aee80b817af252a23e73b283321e4a Mon Sep 17 00:00:00 2001 From: Tom Lokhorst Date: Wed, 14 Jun 2017 20:38:47 +0200 Subject: [PATCH 1/5] Update to XcodeEdit release/2.0 branch --- Package.resolved | 6 +++--- Package.swift | 2 +- Sources/RswiftCore/ResourceTypes/Xcodeproj.swift | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Package.resolved b/Package.resolved index c80de824..bffd0b13 100644 --- a/Package.resolved +++ b/Package.resolved @@ -23,9 +23,9 @@ "package": "XcodeEdit", "repositoryURL": "https://github.com/tomlokhorst/XcodeEdit", "state": { - "branch": null, - "revision": "3262eff18497ae856eb4fb4b7506cd5c15d28dd4", - "version": "1.1.0" + "branch": "release/2.0", + "revision": "2a6ab33948312a4342269099b548fb19af4ad16d", + "version": null } } ] diff --git a/Package.swift b/Package.swift index c691f13b..0f7a5ddc 100644 --- a/Package.swift +++ b/Package.swift @@ -5,7 +5,7 @@ let package = Package( name: "rswift", dependencies: [ .package(url: "https://github.com/kylef/Commander.git", .upToNextMinor(from: "0.6.0")), - .package(url: "https://github.com/tomlokhorst/XcodeEdit", from: "1.0.0") + .package(url: "https://github.com/tomlokhorst/XcodeEdit", .branch("release/2.0")) ], targets: [ .target( diff --git a/Sources/RswiftCore/ResourceTypes/Xcodeproj.swift b/Sources/RswiftCore/ResourceTypes/Xcodeproj.swift index 8e3fb519..8a7f0b83 100644 --- a/Sources/RswiftCore/ResourceTypes/Xcodeproj.swift +++ b/Sources/RswiftCore/ResourceTypes/Xcodeproj.swift @@ -28,25 +28,25 @@ struct Xcodeproj: WhiteListedExtensionsResourceType { func resourcePathsForTarget(_ targetName: String) throws -> [Path] { // Look for target in project file - let allTargets = projectFile.project.targets + let allTargets = projectFile.project.targets.flatMap { $0.value } guard let target = allTargets.filter({ $0.name == targetName }).first else { - let availableTargets = allTargets.map { $0.name }.joined(separator: ", ") + let availableTargets = allTargets.flatMap { $0.name }.joined(separator: ", ") throw ResourceParsingError.parsingFailed("Target '\(targetName)' not found in project file, available targets are: \(availableTargets)") } let resourcesFileRefs = target.buildPhases - .flatMap { $0 as? PBXResourcesBuildPhase } + .flatMap { $0.value as? PBXResourcesBuildPhase } .flatMap { $0.files } - .map { $0.fileRef } + .flatMap { $0.value?.fileRef } let fileRefPaths = resourcesFileRefs - .flatMap { $0 as? PBXFileReference } - .map { $0.fullPath } + .flatMap { $0.value as? PBXFileReference } + .flatMap { $0.fullPath } let variantGroupPaths = resourcesFileRefs - .flatMap { $0 as? PBXVariantGroup } + .flatMap { $0.value as? PBXVariantGroup } .flatMap { $0.fileRefs } - .map { $0.fullPath } + .flatMap { $0.value?.fullPath } return fileRefPaths + variantGroupPaths } From 955c431ad5801bb6bf87e3acbfcf3927d90eebe9 Mon Sep 17 00:00:00 2001 From: Tom Lokhorst Date: Wed, 14 Jun 2017 23:20:48 +0200 Subject: [PATCH 2/5] Warn about corrupt project files, and try again --- Sources/RswiftCore/ResourceTypes/Xcodeproj.swift | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Sources/RswiftCore/ResourceTypes/Xcodeproj.swift b/Sources/RswiftCore/ResourceTypes/Xcodeproj.swift index 8a7f0b83..31b5c1e0 100644 --- a/Sources/RswiftCore/ResourceTypes/Xcodeproj.swift +++ b/Sources/RswiftCore/ResourceTypes/Xcodeproj.swift @@ -17,9 +17,20 @@ struct Xcodeproj: WhiteListedExtensionsResourceType { init(url: URL) throws { try Xcodeproj.throwIfUnsupportedExtension(url.pathExtension) + let projectFile: XCProjectFile // Parse project file - guard let projectFile = try? XCProjectFile(xcodeprojURL: url) else { + do { + do { + projectFile = try XCProjectFile(xcodeprojURL: url) + } + catch let error as ProjectFileError { + warn(error.description) + + projectFile = try XCProjectFile(xcodeprojURL: url, ignoreReferenceErrors: true) + } + } + catch { throw ResourceParsingError.parsingFailed("Project file at '\(url)' could not be parsed, is this a valid Xcode project file ending in *.xcodeproj?") } From 36edf47fcd669a61f7f0884bc15bbb20e86f5f35 Mon Sep 17 00:00:00 2001 From: Tom Lokhorst Date: Wed, 14 Jun 2017 23:22:07 +0200 Subject: [PATCH 3/5] Add broken references to ResourceApp --- ResourceApp/ResourceApp.xcodeproj/project.pbxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/ResourceApp/ResourceApp.xcodeproj/project.pbxproj b/ResourceApp/ResourceApp.xcodeproj/project.pbxproj index 7300ee84..f0a51f41 100644 --- a/ResourceApp/ResourceApp.xcodeproj/project.pbxproj +++ b/ResourceApp/ResourceApp.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + DEADBEEFDEADBEEFDEADBEEF /* Dummy build file that is'nt used */ = {isa = PBXBuildFile; fileRef = C0FEFEC0FEFEC0FEFEC0FEFE /* Localizable.strings */; }; 5D1AFAB11C858637003FE7AB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5D1AFAAF1C858637003FE7AB /* Localizable.strings */; }; 5D9E41341C96918E002172D3 /* StringsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D9E41331C96918E002172D3 /* StringsTests.swift */; }; 8A0FBCE6E8FF0950B8821B0B /* Pods_Shared_ResourceApp_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF513940333862726B930435 /* Pods_Shared_ResourceApp_tvOS.framework */; }; From 96cc099f4434bfbc4f52828ebeeaed04cf731d47 Mon Sep 17 00:00:00 2001 From: Tom Lokhorst Date: Wed, 14 Jun 2017 23:26:32 +0200 Subject: [PATCH 4/5] Add expected warnings to tests --- ResourceApp/ResourceAppTests/ResourceAppTests.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ResourceApp/ResourceAppTests/ResourceAppTests.swift b/ResourceApp/ResourceAppTests/ResourceAppTests.swift index 15be65ea..be988c45 100644 --- a/ResourceApp/ResourceAppTests/ResourceAppTests.swift +++ b/ResourceApp/ResourceAppTests/ResourceAppTests.swift @@ -13,6 +13,11 @@ import XCTest class ResourceAppTests: XCTestCase { let expectedWarnings = [ + "warning: [R.swift] project.pbxproj is internally inconsistent.", + " - PBXBuildFile (DEADBEEFDEADBEEFDEADBEEF) references missing fileRef C0FEFEC0FEFEC0FEFEC0FEFE", + " - PBXBuildFile (DEADBEEFDEADBEEFDEADBEEF) is not used", + "Perhaps a merge conflict?", + "warning: [R.swift] Skipping color 'Red' in 'Display P3.clr' because it is colorspace 'Display P3 colorspace', R.swift currently only supports colorspace RGB", "warning: [R.swift] Skipping color 'Green' in 'Display P3.clr' because it is colorspace 'Display P3 colorspace', R.swift currently only supports colorspace RGB", From 9c9d7bd59c512130cfb9a5fdcde6c2a546f97984 Mon Sep 17 00:00:00 2001 From: Tom Lokhorst Date: Wed, 14 Jun 2017 23:30:42 +0200 Subject: [PATCH 5/5] Use multiline string literal for warnings test --- .../ResourceAppTests/ResourceAppTests.swift | 87 ++++++++++--------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/ResourceApp/ResourceAppTests/ResourceAppTests.swift b/ResourceApp/ResourceAppTests/ResourceAppTests.swift index be988c45..91eca5c2 100644 --- a/ResourceApp/ResourceAppTests/ResourceAppTests.swift +++ b/ResourceApp/ResourceAppTests/ResourceAppTests.swift @@ -12,50 +12,51 @@ import XCTest class ResourceAppTests: XCTestCase { - let expectedWarnings = [ - "warning: [R.swift] project.pbxproj is internally inconsistent.", - " - PBXBuildFile (DEADBEEFDEADBEEFDEADBEEF) references missing fileRef C0FEFEC0FEFEC0FEFEC0FEFE", - " - PBXBuildFile (DEADBEEFDEADBEEFDEADBEEF) is not used", - "Perhaps a merge conflict?", + let expectedWarnings = """ + warning: [R.swift] project.pbxproj is internally inconsistent. - "warning: [R.swift] Skipping color 'Red' in 'Display P3.clr' because it is colorspace 'Display P3 colorspace', R.swift currently only supports colorspace RGB", - "warning: [R.swift] Skipping color 'Green' in 'Display P3.clr' because it is colorspace 'Display P3 colorspace', R.swift currently only supports colorspace RGB", + - PBXBuildFile (DEADBEEFDEADBEEFDEADBEEF) references missing fileRef C0FEFEC0FEFEC0FEFEC0FEFE + - PBXBuildFile (DEADBEEFDEADBEEFDEADBEEF) is not used - "warning: [R.swift] Skipping 2 images because symbol 'second' would be generated for all of these images: Second, second", - "warning: [R.swift] Skipping 2 xibs because symbol 'duplicate' would be generated for all of these files: Duplicate, duplicate", - "warning: [R.swift] Skipping 2 storyboards because symbol 'duplicate' would be generated for all of these files: Duplicate, duplicate", - "warning: [R.swift] Skipping 2 reuseIdentifiers because symbol 'duplicateCellView' would be generated for all of these reuseIdentifiers: DuplicateCellView, duplicateCellView", - "warning: [R.swift] Skipping 2 segues for 'SecondViewController' because symbol 'toFirst' would be generated for all of these segues: ToFirst, toFirst", - "warning: [R.swift] Skipping 2 images because symbol 'theAppIcon' would be generated for all of these images: The App Icon, TheAppIcon", - "warning: [R.swift] Skipping 2 images because symbol 'second' would be generated for all of these images: Second, second", - "warning: [R.swift] Skipping 2 resource files because symbol 'duplicateJson' would be generated for all of these files: Duplicate.json, duplicateJson", - "warning: [R.swift] Destination view controller with id Zbd-89-K73 for segue toUnknown in FirstViewController not found in storyboard References. Is this storyboard corrupt?", - "warning: [R.swift] Skipping 2 view controllers because symbol 'validationClash' would be generated for all of these view controller identifiers: Validation clash, ValidationClash", - "warning: [R.swift] Skipping 1 reuseIdentifier because no swift identifier can be generated for reuseIdentifier: ' '", - "warning: [R.swift] Skipping 2 colors in palette 'My R.swift colors' because symbol 'black' would be generated for all of these colors: Black, Black?", - "warning: [R.swift] Skipping 2 colors because symbol 'myRed' would be generated for all of these colors: My Red, My Red", + Perhaps a merge conflict? - "warning: [R.swift] Skipping 2 strings files because symbol 'duplicate' would be generated for all of these files: Duplicate, Duplicate#", - "warning: [R.swift] Skipping 1 strings file because no swift identifier can be generated for file: '@@'", - "warning: [R.swift] Skipping 1 string in 'Generic' because no swift identifier can be generated for key: '#'", - "warning: [R.swift] Strings file 'Localizable' (en) is missing translations for keys: 'japanese only'", - "warning: [R.swift] Strings file 'Localizable' (es) is missing translations for keys: 'japanese only'", - "warning: [R.swift] Strings file 'Settings' (nl) is missing translations for keys: 'Not translated', 'incorrect in dutch'", - "warning: [R.swift] Skipping string FormatSpecifiers2 in 'Settings' (nl), not all format specifiers are consecutive", - "warning: [R.swift] Skipping string FormatSpecifiers6 in 'Settings' (Base), not all format specifiers are consecutive", - "warning: [R.swift] Skipping string FormatSpecifiers6 in 'Settings' (nl), not all format specifiers are consecutive", - "warning: [R.swift] Skipping string for key FormatSpecifiers5 (Settings), format specifiers don't match for all locales: Base, nl", - "warning: [R.swift] Skipping string for key mismatch (Settings), format specifiers don't match for all locales: Base, nl", - - "warning: [R.swift] Missing reference 'missing' in 'fault delta' 'Generic.stringsdict'", - "warning: [R.swift] Can't unify 'first' in 'fault beta' 'Generic.stringsdict'", - "warning: [R.swift] Can't unify 'first' in 'fault gamma' 'Generic.stringsdict'", - "warning: [R.swift] Missing reference 'missing' in 'fault alpha' 'Generic.stringsdict'", - "warning: [R.swift] Missing reference 'first_one' in 'fault epsilon' 'Generic.stringsdict'", - "warning: [R.swift] Missing reference 'first' in 'incorrect in dutch' 'Settings.stringsdict' (nl)", - "warning: [R.swift] Skipping asset subfolder because symbol 'conflicting' would conflict with image: conflicting", - "warning: [R.swift] Skipping 2 images because symbol 'second' would be generated for all of these images: Second, Second" - ] + warning: [R.swift] Skipping color 'Red' in 'Display P3.clr' because it is colorspace 'Display P3 colorspace', R.swift currently only supports colorspace RGB + warning: [R.swift] Skipping color 'Green' in 'Display P3.clr' because it is colorspace 'Display P3 colorspace', R.swift currently only supports colorspace RGB + warning: [R.swift] Missing reference 'missing' in 'fault delta' 'Generic.stringsdict' + warning: [R.swift] Can't unify 'first' in 'fault beta' 'Generic.stringsdict' + warning: [R.swift] Can't unify 'first' in 'fault gamma' 'Generic.stringsdict' + warning: [R.swift] Missing reference 'missing' in 'fault alpha' 'Generic.stringsdict' + warning: [R.swift] Missing reference 'first_one' in 'fault epsilon' 'Generic.stringsdict' + warning: [R.swift] Missing reference 'first' in 'incorrect in dutch' 'Settings.stringsdict' (nl) + warning: [R.swift] Skipping 2 colors in palette 'My R.swift colors' because symbol 'black' would be generated for all of these colors: Black, Black? + warning: [R.swift] Skipping 2 images because symbol 'second' would be generated for all of these images: Second, second + warning: [R.swift] Skipping 2 images because symbol 'theAppIcon' would be generated for all of these images: The App Icon, TheAppIcon + warning: [R.swift] Skipping asset subfolder because symbol 'conflicting' would conflict with image: conflicting + warning: [R.swift] Skipping 2 images because symbol 'second' would be generated for all of these images: Second, Second + warning: [R.swift] Skipping 2 colors because symbol 'myRed' would be generated for all of these colors: My Red, My Red + warning: [R.swift] Destination view controller with id Zbd-89-K73 for segue toUnknown in FirstViewController not found in storyboard References. Is this storyboard corrupt? + warning: [R.swift] Skipping 2 segues for 'SecondViewController' because symbol 'toFirst' would be generated for all of these segues: ToFirst, toFirst + warning: [R.swift] Skipping 2 storyboards because symbol 'duplicate' would be generated for all of these files: Duplicate, duplicate + warning: [R.swift] Skipping 2 view controllers because symbol 'validationClash' would be generated for all of these view controller identifiers: Validation clash, ValidationClash + warning: [R.swift] Skipping 2 xibs because symbol 'duplicate' would be generated for all of these files: Duplicate, duplicate + warning: [R.swift] Skipping 2 reuseIdentifiers because symbol 'duplicateCellView' would be generated for all of these reuseIdentifiers: DuplicateCellView, duplicateCellView + warning: [R.swift] Skipping 1 reuseIdentifier because no swift identifier can be generated for reuseIdentifier: ' ' + warning: [R.swift] Skipping 2 resource files because symbol 'duplicateJson' would be generated for all of these files: Duplicate.json, duplicateJson + warning: [R.swift] Skipping 2 strings files because symbol 'duplicate' would be generated for all of these files: Duplicate, Duplicate# + warning: [R.swift] Skipping 1 strings file because no swift identifier can be generated for file: '@@' + warning: [R.swift] Strings file 'Localizable' (es) is missing translations for keys: 'japanese only' + warning: [R.swift] Strings file 'Localizable' (en) is missing translations for keys: 'japanese only' + warning: [R.swift] Strings file 'Settings' (nl) is missing translations for keys: 'Not translated', 'incorrect in dutch' + warning: [R.swift] Skipping string FormatSpecifiers2 in 'Settings' (nl), not all format specifiers are consecutive + warning: [R.swift] Skipping string FormatSpecifiers6 in 'Settings' (Base), not all format specifiers are consecutive + warning: [R.swift] Skipping string FormatSpecifiers6 in 'Settings' (nl), not all format specifiers are consecutive + warning: [R.swift] Skipping string for key FormatSpecifiers5 (Settings), format specifiers don't match for all locales: Base, nl + warning: [R.swift] Skipping string for key mismatch (Settings), format specifiers don't match for all locales: Base, nl + warning: [R.swift] Skipping 1 string in 'Generic' because no swift identifier can be generated for key: '#' + warning: [R.swift] Skipping 2 colors in palette 'My R.swift colors' because symbol 'black' would be generated for all of these colors: Black, Black? + """ + .trimmingCharacters(in: .whitespacesAndNewlines) + .components(separatedBy: "\n") func testWarningsAreLogged() { guard let logURL = Bundle(for: ResourceAppTests.self).url(forResource: "rswift", withExtension: "log") else { @@ -65,7 +66,9 @@ class ResourceAppTests: XCTestCase { do { let logContent = try String(contentsOf: logURL) - let logLines = logContent.components(separatedBy: "\n").filter { !$0.isEmpty } + let logLines = logContent + .trimmingCharacters(in: .whitespacesAndNewlines) + .components(separatedBy: "\n") for warning in expectedWarnings { XCTAssertTrue(logLines.contains(warning), "Warning is not logged: '\(warning)'")