Skip to content

Instantly share code, notes, and snippets.

@PhilipDukhov
Last active November 27, 2020 04:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PhilipDukhov/3524c8bd8cea9419ced527504c5d5b21 to your computer and use it in GitHub Desktop.
Save PhilipDukhov/3524c8bd8cea9419ced527504c5d5b21 to your computer and use it in GitHub Desktop.
import Foundation
extension NSError {
convenience init(description: String, code: Int = 0) {
self.init(
domain: "plist script",
code: code,
userInfo: [NSLocalizedDescriptionKey: description]
)
}
}
let inputPlistURL = URL(
fileURLWithPath: CommandLine.arguments[1]
)
let outputPlistURL = URL(
fileURLWithPath: CommandLine.arguments[2]
)
try [inputPlistURL,
outputPlistURL
].forEach { url in
guard url.pathExtension == "plist" else
{ throw NSError(description: "invalid argument: \(url)") }
}
guard inputPlistURL != outputPlistURL else
{ throw NSError(description: "This will override input file!") }
let plist = try PropertyListSerialization.propertyList(
from: try Data(contentsOf: inputPlistURL),
format: nil
)
func replacePlistEnvironmentVariables(_ plist: Any) throws -> Any {
switch plist {
case let dictionary as [String: Any]:
return try dictionary.mapValues(replacePlistEnvironmentVariables)
case let array as [Any]:
return try array.map(replacePlistEnvironmentVariables)
case let string as String:
return try NSRegularExpression(
pattern: "\\$\\((\\w+)\\)"
).matches(
in: string,
range: NSRange(
string.startIndex..<string.endIndex,
in: string
)
).reversed().reduce(into: string) { result, match in
let replaceRange = Range(
match.range(at: 0),
in: string
)!
let variableRange = Range(
match.range(at: 1),
in: string
)!
let variable = String(string[variableRange])
result.replaceSubrange(
replaceRange,
with: ProcessInfo.processInfo.environment[variable]!
)
}
default: return plist
}
}
let resultPlist = try replacePlistEnvironmentVariables(plist)
try PropertyListSerialization.data(
fromPropertyList: resultPlist,
format: .xml,
options: .zero
).write(to: outputPlistURL)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment