Skip to content

Commit 84456dc

Browse files
Prevent duplicate property names in generated Swift code
1 parent 64bdc52 commit 84456dc

File tree

7 files changed

+48
-21
lines changed

7 files changed

+48
-21
lines changed

XCAssetPacker.xcodeproj/project.pbxproj

+10-4
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,13 @@
194194
4A56D1461DE5B573000B40D8 = {
195195
CreatedOnToolsVersion = 8.1;
196196
DevelopmentTeam = D92MT22EX5;
197+
LastSwiftMigration = 0900;
197198
ProvisioningStyle = Automatic;
198199
};
199200
4AD71E7B1EA4CCBA00016A1A = {
200201
CreatedOnToolsVersion = 8.3.1;
201202
DevelopmentTeam = D92MT22EX5;
203+
LastSwiftMigration = 0900;
202204
ProvisioningStyle = Automatic;
203205
};
204206
};
@@ -372,7 +374,8 @@
372374
buildSettings = {
373375
DEVELOPMENT_TEAM = D92MT22EX5;
374376
PRODUCT_NAME = "$(TARGET_NAME)";
375-
SWIFT_VERSION = 3.0;
377+
SWIFT_SWIFT3_OBJC_INFERENCE = On;
378+
SWIFT_VERSION = 4.0;
376379
};
377380
name = Debug;
378381
};
@@ -381,7 +384,8 @@
381384
buildSettings = {
382385
DEVELOPMENT_TEAM = D92MT22EX5;
383386
PRODUCT_NAME = "$(TARGET_NAME)";
384-
SWIFT_VERSION = 3.0;
387+
SWIFT_SWIFT3_OBJC_INFERENCE = On;
388+
SWIFT_VERSION = 4.0;
385389
};
386390
name = Release;
387391
};
@@ -397,7 +401,8 @@
397401
PRODUCT_BUNDLE_IDENTIFIER = "com.inquisitiveSoftware.XCAssetPacker-Tests";
398402
PRODUCT_NAME = "$(TARGET_NAME)";
399403
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
400-
SWIFT_VERSION = 3.0;
404+
SWIFT_SWIFT3_OBJC_INFERENCE = On;
405+
SWIFT_VERSION = 4.0;
401406
};
402407
name = Debug;
403408
};
@@ -412,7 +417,8 @@
412417
MACOSX_DEPLOYMENT_TARGET = 10.12;
413418
PRODUCT_BUNDLE_IDENTIFIER = "com.inquisitiveSoftware.XCAssetPacker-Tests";
414419
PRODUCT_NAME = "$(TARGET_NAME)";
415-
SWIFT_VERSION = 3.0;
420+
SWIFT_SWIFT3_OBJC_INFERENCE = On;
421+
SWIFT_VERSION = 4.0;
416422
};
417423
name = Release;
418424
};

XCAssetPacker/AssetCatalogGenerator.swift

+10-7
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,21 @@ class AssetCatalogGenerator {
239239
}
240240

241241

242-
// Create the folder structure, the metadata and copy the images across
243-
var result = try applyChanges(forNode: rootNode, dryRun: dryRun, logLevel: logLevel)
244-
245-
246242
// Generate Swift code
243+
let generatedCode: String?
244+
247245
if let swiftFileURL = swiftFileURL {
248246
let code = try swiftCode(forTarget: swiftTarget, rootNode: rootNode)
249-
result.code = code
250-
251247
try code.write(to: swiftFileURL, atomically: true, encoding: .utf8)
248+
generatedCode = code
249+
} else {
250+
generatedCode = nil
252251
}
253-
252+
253+
// Create the folder structure, the metadata and copy the images across
254+
var result = try applyChanges(forNode: rootNode, dryRun: dryRun, logLevel: logLevel)
255+
result.code = generatedCode
256+
254257
return result
255258
}
256259

XCAssetPacker/CommandLine/CommandLineKit/CommandLine.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,10 @@ public class CommandLine {
316316
}
317317

318318
/* Remove attached argument from flag */
319-
let splitFlag = flagWithArg.split(by: argumentAttacher, maxSplits: 1)
320-
let flag = splitFlag[0]
321-
let attachedArg: String? = splitFlag.count == 2 ? splitFlag[1] : nil
322-
319+
let splitFlag = flagWithArg.split(separator: argumentAttacher, maxSplits: 1)
320+
let flag = String(splitFlag[0])
321+
let attachedArg: String? = splitFlag.count == 2 ? String(splitFlag[1]) : nil
322+
323323
var flagMatched = false
324324
for option in _options where option.flagMatch(flag) {
325325
let vals = self._getFlagValues(idx, attachedArg)

XCAssetPacker/CommandLine/CommandLineKit/StringExtensions.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,14 @@ internal extension String {
9595
for i in self.characters.indices {
9696
let c = self[i]
9797
if c == by && (maxSplits == 0 || numSplits < maxSplits) {
98-
s.append(self[curIdx..<i])
98+
s.append(String(self[curIdx..<i]))
9999
curIdx = self.index(after: i)
100100
numSplits += 1
101101
}
102102
}
103103

104104
if curIdx != self.endIndex {
105-
s.append(self[curIdx..<self.endIndex])
105+
s.append(String(self[curIdx..<self.endIndex]))
106106
}
107107

108108
return s

XCAssetPacker/ImageProperties.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//
55
// Created by Harry Jordan on 23/11/2016.
66
// Copyright © 2016 Inquisitive Software. All rights reserved.
7-
//
7+
//
88
// Licensed under the Apache License, Version 2.0 (the "License");
99
// you may not use this file except in compliance with the License.
1010
// You may obtain a copy of the License at
@@ -38,7 +38,7 @@ struct ImageProperties {
3838

3939
// Look for an image scale e.g. @2x or @3x
4040
if let match = ImageProperties.scaleRegularExpression.firstMatch(in: adaptedName, range: adaptedName.asNSRange), match.numberOfRanges >= 2 {
41-
let rangeOfDigits = match.rangeAt(1)
41+
let rangeOfDigits = match.range(at: 1)
4242
let digitString = (adaptedName as NSString).substring(with: rangeOfDigits)
4343

4444
if let scaleNumber = Int(digitString) {

XCAssetPacker/SwiftGeneration.swift

+13-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
import Foundation
2222

2323

24+
enum SwiftGenerationError: Error {
25+
case duplicateProperty(name: String, originalFileName: String)
26+
}
27+
28+
29+
2430
enum SwiftTarget {
2531
case cocoa, iOS, watch
2632

@@ -108,9 +114,14 @@ extension AssetCatalogGenerator {
108114

109115
for child in childNodes where child.isDirectory && child.isImageSet && !child.isAppIcon {
110116
let propertyName = child.swiftPropertyName(withinGroup: groupPropertyName)
111-
propertyNames.append(propertyName)
112117

113-
generatedCode += firstIndent + "var \(propertyName): \(target.imageClassName) { return image(named: \"\(child.swiftCatalogName)\") }\n"
118+
if propertyNames.contains(propertyName) {
119+
throw SwiftGenerationError.duplicateProperty(name: propertyName, originalFileName: child.name)
120+
} else {
121+
propertyNames.append(propertyName)
122+
123+
generatedCode += firstIndent + "var \(propertyName): \(target.imageClassName) { return image(named: \"\(child.swiftCatalogName)\") }\n"
124+
}
114125
}
115126

116127
for child in node.children where child.isDirectory && !child.isImageSet && !child.isAppIcon {

XCAssetPacker/main.swift

+7
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ do {
146146
print(description)
147147
exit(EX_IOERR)
148148
}
149+
} catch let error as SwiftGenerationError {
150+
switch error {
151+
case .duplicateProperty(let name, originalFileName: let originalFileName):
152+
print("Conflicting property '\(name)' for \(originalFileName)")
153+
print("Images need to have distinct llama case representations")
154+
exit(EX_IOERR)
155+
}
149156
} catch let error {
150157
print("Unexpected error: \(String(describing: error))")
151158
exit(EX_IOERR)

0 commit comments

Comments
 (0)