Skip to content

Commit 9f5bc1a

Browse files
Fix shell escaping issues (#78)
Fixes #75 #76 #77
1 parent 0d20682 commit 9f5bc1a

File tree

13 files changed

+202
-13
lines changed

13 files changed

+202
-13
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ build_release:
1414
proj: build
1515
@rm -rf Periphery.xcodeproj
1616
@swift package generate-xcodeproj
17-
@cp Tests/Configs/RetentionFixtures.xcscheme Periphery.xcodeproj/xcshareddata/xcschemes/
17+
@cp Tests/Configs/*.xcscheme Periphery.xcodeproj/xcshareddata/xcschemes/
1818
@open Periphery.xcodeproj
1919

2020
lint:

Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ let package = Package(
3939
.testTarget(
4040
name: "RetentionFixtures"
4141
),
42+
.testTarget(
43+
name: "TestEmptyTarget"
44+
),
4245
.testTarget(
4346
name: "SyntaxFixtures"
4447
),

Sources/PeripheryKit/Xcode/BuildPlan.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ final class BuildPlan {
8888
if arg.starts(with: "@") {
8989
let filepath = String(arg.dropFirst())
9090
let content = try String(contentsOfFile: filepath)
91-
return content.split(separator: "\n").map(String.init)
91+
return content.split(separator: "\n").map(sanitizeFilePath)
9292
} else {
9393
return [arg]
9494
}

Sources/PeripheryKit/Xcode/Xcodebuild.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ public final class Xcodebuild: Injectable {
4040
let cmd = buildForTesting ? "build-for-testing" : "build"
4141

4242
var args = [
43-
"-\(project.type)", project.path.absolute().string,
44-
"-scheme", scheme,
43+
"-\(project.type)", "'\(project.path.absolute().string)'",
44+
"-scheme", "'\(scheme)'",
4545
"-parallelizeTargets",
4646
"-derivedDataPath", "'\(try derivedDataPath(for: project).string)'",
4747
]

Sources/PeripheryKit/Xcode/XcodebuildLogParser.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ final class XcodebuildLogParser {
5757
let range = $0.range(at: 1)
5858
let pair = String(command[Range(range, in: command)!])
5959
var (key, value) = splitArgumentPair(pair)
60-
value = sanitize(argValue: value)
60+
value = value.map(sanitizeFilePath)
6161
return BuildArgument(key: key, value: value)
6262
}
6363

@@ -115,11 +115,11 @@ final class XcodebuildLogParser {
115115

116116
return (key, value)
117117
}
118+
}
118119

119-
private func sanitize(argValue value: String?) -> String? {
120-
return value?
121-
.replacingOccurrences(of: "\\ ", with: " ")
122-
.replacingOccurrences(of: "\\'", with: "'")
123-
.replacingOccurrences(of: "\\\"", with: "\"")
124-
}
120+
func sanitizeFilePath<S: StringProtocol>(_ value: S) -> String {
121+
return value
122+
.replacingOccurrences(of: "\\ ", with: " ")
123+
.replacingOccurrences(of: "\\'", with: "'")
124+
.replacingOccurrences(of: "\\\"", with: "\"")
125125
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1140"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "NO"
13+
buildForArchiving = "NO"
14+
buildForAnalyzing = "NO">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "Periphery::TestEmptyTarget"
18+
BuildableName = "TestEmptyTarget.xctest"
19+
BlueprintName = "TestEmptyTarget"
20+
ReferencedContainer = "container:Periphery.xcodeproj">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
</BuildActionEntries>
24+
</BuildAction>
25+
<TestAction
26+
buildConfiguration = "Debug"
27+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
shouldUseLaunchSchemeArgsEnv = "YES">
30+
<Testables>
31+
<TestableReference
32+
skipped = "NO">
33+
<BuildableReference
34+
BuildableIdentifier = "primary"
35+
BlueprintIdentifier = "Periphery::TestEmptyTarget"
36+
BuildableName = "TestEmptyTarget.xctest"
37+
BlueprintName = "TestEmptyTarget"
38+
ReferencedContainer = "container:Periphery.xcodeproj">
39+
</BuildableReference>
40+
</TestableReference>
41+
</Testables>
42+
</TestAction>
43+
<LaunchAction
44+
buildConfiguration = "Debug"
45+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
46+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
47+
launchStyle = "0"
48+
useCustomWorkingDirectory = "NO"
49+
ignoresPersistentStateOnLaunch = "NO"
50+
debugDocumentVersioning = "YES"
51+
debugServiceExtension = "internal"
52+
allowLocationSimulation = "YES">
53+
</LaunchAction>
54+
<ProfileAction
55+
buildConfiguration = "Release"
56+
shouldUseLaunchSchemeArgsEnv = "YES"
57+
savedToolIdentifier = ""
58+
useCustomWorkingDirectory = "NO"
59+
debugDocumentVersioning = "YES">
60+
<MacroExpansion>
61+
<BuildableReference
62+
BuildableIdentifier = "primary"
63+
BlueprintIdentifier = "Periphery::TestEmptyTarget"
64+
BuildableName = "TestEmptyTarget.xctest"
65+
BlueprintName = "TestEmptyTarget"
66+
ReferencedContainer = "container:Periphery.xcodeproj">
67+
</BuildableReference>
68+
</MacroExpansion>
69+
</ProfileAction>
70+
<AnalyzeAction
71+
buildConfiguration = "Debug">
72+
</AnalyzeAction>
73+
<ArchiveAction
74+
buildConfiguration = "Release"
75+
revealArchiveInOrganizer = "YES">
76+
</ArchiveAction>
77+
</Scheme>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1140"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "Periphery::TestEmptyTarget"
18+
BuildableName = "TestEmptyTarget.xctest"
19+
BlueprintName = "TestEmptyTarget"
20+
ReferencedContainer = "container:Periphery.xcodeproj">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
</BuildActionEntries>
24+
</BuildAction>
25+
<TestAction
26+
buildConfiguration = "Debug"
27+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
shouldUseLaunchSchemeArgsEnv = "YES">
30+
<Testables>
31+
</Testables>
32+
</TestAction>
33+
<LaunchAction
34+
buildConfiguration = "Debug"
35+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37+
launchStyle = "0"
38+
useCustomWorkingDirectory = "NO"
39+
ignoresPersistentStateOnLaunch = "NO"
40+
debugDocumentVersioning = "YES"
41+
debugServiceExtension = "internal"
42+
allowLocationSimulation = "YES">
43+
</LaunchAction>
44+
<ProfileAction
45+
buildConfiguration = "Release"
46+
shouldUseLaunchSchemeArgsEnv = "YES"
47+
savedToolIdentifier = ""
48+
useCustomWorkingDirectory = "NO"
49+
debugDocumentVersioning = "YES">
50+
<MacroExpansion>
51+
<BuildableReference
52+
BuildableIdentifier = "primary"
53+
BlueprintIdentifier = "Periphery::TestEmptyTarget"
54+
BuildableName = "TestEmptyTarget.xctest"
55+
BlueprintName = "TestEmptyTarget"
56+
ReferencedContainer = "container:Periphery.xcodeproj">
57+
</BuildableReference>
58+
</MacroExpansion>
59+
</ProfileAction>
60+
<AnalyzeAction
61+
buildConfiguration = "Debug">
62+
</AnalyzeAction>
63+
<ArchiveAction
64+
buildConfiguration = "Release"
65+
revealArchiveInOrganizer = "YES">
66+
</ArchiveAction>
67+
</Scheme>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import XCTest
2+
import PathKit
3+
@testable import PeripheryKit
4+
5+
class SourceKitTest: XCTestCase {
6+
var project: Project!
7+
override func setUpWithError() throws {
8+
self.project = try Project.make(path: PeripheryProjectPath)
9+
}
10+
11+
func testWhitespacedFile() throws {
12+
let mockProjectPath = ProjectRootPath + "Tests/TestEmptyTarget"
13+
let whitespacedFilePath = mockProjectPath + "File name with space.swift"
14+
let xcodebuild = Xcodebuild.make()
15+
try xcodebuild.clearDerivedData(for: project)
16+
let buildLog = try xcodebuild.build(project: project, scheme: "TestEmptyTarget")
17+
let target = project.targets.first { $0.name == "TestEmptyTarget" }!
18+
let buildPlan = try BuildPlan.make(buildLog: buildLog, targets: [target])
19+
let arguments = try buildPlan.arguments(for: target)
20+
let sourcekit = SourceKit(arguments: arguments)
21+
_ = try sourcekit.requestIndex(SourceFile(path: whitespacedFilePath))
22+
}
23+
}

Tests/PeripheryKitTests/Xcode/SchemeTest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ class SchemeTest: XCTestCase {
1212

1313
func testTargets() throws {
1414
XCTAssertEqual(try scheme.buildTargets().sorted(), ["Periphery", "PeripheryKit"])
15-
XCTAssertEqual(try scheme.testTargets().sorted(), ["Periphery", "PeripheryKit", "PeripheryKitTests", "RetentionFixtures", "SyntaxFixtures"])
15+
XCTAssertEqual(try scheme.testTargets().sorted(), ["Periphery", "PeripheryKit", "PeripheryKitTests", "RetentionFixtures", "SyntaxFixtures", "TestEmptyTarget"])
1616
}
1717
}

Tests/PeripheryKitTests/Xcode/XcodebuildSettingsParserTest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class XcodebuildSettingsParserTest: XCTestCase {
2828
let pyKitParser = XcodebuildSettingsParser(settings: pyKitSettings)
2929

3030
XCTAssertEqual(pyKitParser.buildTargets(action: "build").sorted(), ["Periphery", "PeripheryKit"])
31-
XCTAssertEqual(pyKitParser.buildTargets(action: "test").sorted(), ["Periphery", "PeripheryKit", "PeripheryKitTests", "RetentionFixtures", "SyntaxFixtures"])
31+
XCTAssertEqual(pyKitParser.buildTargets(action: "test").sorted(), ["Periphery", "PeripheryKit", "PeripheryKitTests", "RetentionFixtures", "SyntaxFixtures", "TestEmptyTarget"])
3232

3333
let pySettings = try! xcodebuild.buildSettings(for: project, scheme: "Periphery")
3434
let pyParser = XcodebuildSettingsParser(settings: pySettings)

0 commit comments

Comments
 (0)