161 lines
5.5 KiB
Diff
161 lines
5.5 KiB
Diff
|
commit caea53ad329a79fce2ac2b3eadf7c8ba92b903fa
|
||
|
Author: Gwen Mittertreiner <gwen.mittertreiner@gmail.com>
|
||
|
Date: Sun Apr 7 13:23:17 2019 -0700
|
||
|
|
||
|
Remove use of fts
|
||
|
|
||
|
Replace the use of fts with Foundation's Directory Enumerator, which (on
|
||
|
Darwin/Linux), calls fts instead, but is cross platform for Windows.
|
||
|
|
||
|
diff --git a/swiftpm/Sources/Basic/FileSystem.swift b/swiftpm/Sources/Basic/FileSystem.swift
|
||
|
index 958eaaf4..1b9e01a0 100644
|
||
|
--- a/swiftpm/Sources/Basic/FileSystem.swift
|
||
|
+++ b/swiftpm/Sources/Basic/FileSystem.swift
|
||
|
@@ -88,16 +88,18 @@ public enum FileMode {
|
||
|
case userUnWritable
|
||
|
case userWritable
|
||
|
case executable
|
||
|
-
|
||
|
- /// File mode as it would be passed to `chmod`.
|
||
|
- public var cliArgument: String {
|
||
|
+
|
||
|
+ internal var setMode: (Int16) -> Int16 {
|
||
|
switch self {
|
||
|
case .userUnWritable:
|
||
|
- return "u-w"
|
||
|
+ // r-x rwx rwx
|
||
|
+ return {$0 & 0o577}
|
||
|
case .userWritable:
|
||
|
- return "u+w"
|
||
|
+ // -w- --- ---
|
||
|
+ return {$0 | 0o200}
|
||
|
case .executable:
|
||
|
- return "+x"
|
||
|
+ // --x --x --x
|
||
|
+ return {$0 | 0o111}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
@@ -375,86 +377,39 @@ private class LocalFileSystem: FileSystem {
|
||
|
}
|
||
|
|
||
|
func chmod(_ mode: FileMode, path: AbsolutePath, options: Set<FileMode.Option>) throws {
|
||
|
- #if os(macOS)
|
||
|
- // Get the mode we need to set.
|
||
|
- guard let setMode = setmode(mode.cliArgument) else {
|
||
|
- throw FileSystemError(errno: errno)
|
||
|
- }
|
||
|
- defer { setMode.deallocate() }
|
||
|
+ guard exists(path) else { return }
|
||
|
+ func setMode(path: String) throws {
|
||
|
+ // Skip if only files should be changed.
|
||
|
+ if options.contains(.onlyFiles) && isDirectory(AbsolutePath(path)) {
|
||
|
+ return
|
||
|
+ }
|
||
|
|
||
|
- let recursive = options.contains(.recursive)
|
||
|
- // If we're in recursive mode, do physical walk otherwise logical.
|
||
|
- let ftsOptions = recursive ? FTS_PHYSICAL : FTS_LOGICAL
|
||
|
+ let attrs = try FileManager.default.attributesOfItem(atPath: path)
|
||
|
|
||
|
- // Get handle to the file hierarchy we want to traverse.
|
||
|
- let paths = CStringArray([path.pathString])
|
||
|
- guard let ftsp = fts_open(paths.cArray, ftsOptions, nil) else {
|
||
|
- throw FileSystemError(errno: errno)
|
||
|
+ // Compute the new mode for this file.
|
||
|
+ let currentMode = attrs[.posixPermissions] as! Int16
|
||
|
+ let newMode = mode.setMode(currentMode)
|
||
|
+ guard newMode != currentMode else { return }
|
||
|
+ try FileManager.default.setAttributes([.posixPermissions : newMode],
|
||
|
+ ofItemAtPath: path)
|
||
|
}
|
||
|
- defer { fts_close(ftsp) }
|
||
|
-
|
||
|
- // Start traversing.
|
||
|
- while let p = fts_read(ftsp) {
|
||
|
-
|
||
|
- switch Int32(p.pointee.fts_info) {
|
||
|
-
|
||
|
- // A directory being visited in pre-order.
|
||
|
- case FTS_D:
|
||
|
- // If we're not recursing, skip the contents of the directory.
|
||
|
- if !recursive {
|
||
|
- fts_set(ftsp, p, FTS_SKIP)
|
||
|
- }
|
||
|
- continue
|
||
|
-
|
||
|
- // A directory couldn't be read.
|
||
|
- case FTS_DNR:
|
||
|
- // FIXME: We should warn here.
|
||
|
- break
|
||
|
-
|
||
|
- // There was an error.
|
||
|
- case FTS_ERR:
|
||
|
- fallthrough
|
||
|
|
||
|
- // No stat(2) information was available.
|
||
|
- case FTS_NS:
|
||
|
- // FIXME: We should warn here.
|
||
|
- continue
|
||
|
+ try setMode(path: path.pathString)
|
||
|
+ guard isDirectory(path) else { return }
|
||
|
|
||
|
- // A symbolic link.
|
||
|
- case FTS_SL:
|
||
|
- fallthrough
|
||
|
-
|
||
|
- // A symbolic link with a non-existent target.
|
||
|
- case FTS_SLNONE:
|
||
|
- // The only symlinks that end up here are ones that don't point
|
||
|
- // to anything and ones that we found doing a physical walk.
|
||
|
- continue
|
||
|
-
|
||
|
- default:
|
||
|
- break
|
||
|
- }
|
||
|
-
|
||
|
- // Compute the new mode for this file.
|
||
|
- let currentMode = mode_t(p.pointee.fts_statp.pointee.st_mode)
|
||
|
-
|
||
|
- // Skip if only files should be changed.
|
||
|
- if options.contains(.onlyFiles) && (currentMode & S_IFMT) == S_IFDIR {
|
||
|
- continue
|
||
|
- }
|
||
|
+ guard let traverse = FileManager.default.enumerator(
|
||
|
+ at: URL(fileURLWithPath: path.pathString),
|
||
|
+ includingPropertiesForKeys: nil) else {
|
||
|
+ throw FileSystemError.noEntry
|
||
|
+ }
|
||
|
|
||
|
- // Compute the new mode.
|
||
|
- let newMode = getmode(setMode, currentMode)
|
||
|
- if newMode == currentMode {
|
||
|
- continue
|
||
|
- }
|
||
|
+ if !options.contains(.recursive) {
|
||
|
+ traverse.skipDescendants()
|
||
|
+ }
|
||
|
|
||
|
- // Update the mode.
|
||
|
- //
|
||
|
- // We ignore the errors for now but we should have a way to report back.
|
||
|
- _ = SPMLibc.chmod(p.pointee.fts_accpath, newMode)
|
||
|
+ while let path = traverse.nextObject() {
|
||
|
+ try setMode(path: (path as! URL).path)
|
||
|
}
|
||
|
- #endif
|
||
|
- // FIXME: We only support macOS right now.
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff --git a/swiftpm/Sources/clibc/include/clibc.h b/swiftpm/Sources/clibc/include/clibc.h
|
||
|
index 7cf808c1..8a90bffa 100644
|
||
|
--- a/swiftpm/Sources/clibc/include/clibc.h
|
||
|
+++ b/swiftpm/Sources/clibc/include/clibc.h
|
||
|
@@ -1,5 +1,3 @@
|
||
|
-#include <fts.h>
|
||
|
-
|
||
|
#if defined(__linux__)
|
||
|
#include <sys/inotify.h>
|
||
|
#endif
|