Update mtime when copying files
Without updating the mtime of files when copied, the Bazel-built
version of Tulsi may not correctly run due to old *.pyc files being
used when *.py files change (because Bazel resets their timestamps).
PiperOrigin-RevId: 210111838
diff --git a/src/TulsiGenerator/XcodeProjectGenerator.swift b/src/TulsiGenerator/XcodeProjectGenerator.swift
index b4691b8..da09fa5 100644
--- a/src/TulsiGenerator/XcodeProjectGenerator.swift
+++ b/src/TulsiGenerator/XcodeProjectGenerator.swift
@@ -1353,6 +1353,8 @@
try fileManager.removeItem(at: targetURL)
}
try fileManager.copyItem(at: sourceURL, to: targetURL)
+ // Touch the file so Python knows to update the .pyc files.
+ try fileManager.setAttributes([.modificationDate: Date()], ofItemAtPath: targetURL.path)
errorInfo = nil
} catch let e as NSError {
errorInfo = e.localizedDescription
diff --git a/src/TulsiGeneratorTests/XcodeProjectGeneratorTests.swift b/src/TulsiGeneratorTests/XcodeProjectGeneratorTests.swift
index 2cb4874..48d6958 100644
--- a/src/TulsiGeneratorTests/XcodeProjectGeneratorTests.swift
+++ b/src/TulsiGeneratorTests/XcodeProjectGeneratorTests.swift
@@ -86,6 +86,10 @@
XCTAssert(mockFileManager.copyOperations.keys.contains(cacheReaderURL.path))
let xcp = "\(xcodeProjectPath)/xcuserdata/USER.xcuserdatad/xcschemes/xcschememanagement.plist"
+ XCTAssert(!mockFileManager.attributesMap.isEmpty)
+ mockFileManager.attributesMap.forEach { (path, attrs) in
+ XCTAssertNotNil(attrs[.modificationDate])
+ }
XCTAssert(mockFileManager.writeOperations.keys.contains(xcp))
} catch let e {
XCTFail("Unexpected exception \(e)")
@@ -382,6 +386,7 @@
var writeOperations = [String: Data]()
var removeOperations = [String]()
var mockContent = [String: Data]()
+ var attributesMap = [String: [FileAttributeKey: Any]]()
override open var homeDirectoryForCurrentUser: URL {
return URL(fileURLWithPath: "/Users/__MOCK_USER__", isDirectory: true)
@@ -392,10 +397,13 @@
}
override func createDirectory(at url: URL,
- withIntermediateDirectories createIntermediates: Bool,
- attributes: [FileAttributeKey:Any]?) throws {
+ withIntermediateDirectories createIntermediates: Bool,
+ attributes: [FileAttributeKey: Any]?) throws {
guard !allowedDirectoryCreates.contains(url.path) else {
directoryOperations.append(url.path)
+ if let attributes = attributes {
+ self.setAttributes(attributes, path: url.path)
+ }
return
}
throw NSError(domain: "MockFileManager: Directory creation disallowed",
@@ -404,10 +412,13 @@
}
override func createDirectory(atPath path: String,
- withIntermediateDirectories createIntermediates: Bool,
- attributes: [FileAttributeKey:Any]?) throws {
+ withIntermediateDirectories createIntermediates: Bool,
+ attributes: [FileAttributeKey: Any]?) throws {
guard !allowedDirectoryCreates.contains(path) else {
directoryOperations.append(path)
+ if let attributes = attributes {
+ self.setAttributes(attributes, path: path)
+ }
return
}
throw NSError(domain: "MockFileManager: Directory creation disallowed",
@@ -440,8 +451,23 @@
fatalError("Attempting to overwrite an existing file at \(path)")
}
writeOperations[path] = data
+ if let attr = attr {
+ self.setAttributes(attr, path: path)
+ }
return true
}
+
+ fileprivate func setAttributes(_ attributes: [FileAttributeKey : Any], path: String) {
+ var currentAttributes = attributesMap[path] ?? [FileAttributeKey : Any]()
+ attributes.forEach { (k, v) in
+ currentAttributes[k] = v
+ }
+ attributesMap[path] = currentAttributes
+ }
+
+ override func setAttributes(_ attributes: [FileAttributeKey : Any], ofItemAtPath path: String) throws {
+ self.setAttributes(attributes, path: path)
+ }
}