From b0848b4a8dee1604309dd0d24cd02c9645f72d10 Mon Sep 17 00:00:00 2001 From: Mark Lacey Date: Tue, 12 Jun 2018 09:35:40 -0700 Subject: [PATCH] =?UTF-8?q?Revert=20"Implement=20FileManager.url{s,}(for:?= =?UTF-8?q?=E2=80=A6)=20and=20NSSearchPathForDirectoriesInDomains."?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Foundation.xcodeproj/project.pbxproj | 6 - Foundation/FileManager.swift | 325 +----------------------- Foundation/FileManager_XDG.swift | 125 --------- Foundation/NSPathUtilities.swift | 24 +- TestFoundation/TestFileManager.swift | 202 +-------------- TestFoundation/TestProcess.swift | 2 +- TestFoundation/xdgTestHelper/main.swift | 98 +------ build.py | 7 +- lib/phases.py | 7 +- 9 files changed, 19 insertions(+), 777 deletions(-) delete mode 100644 Foundation/FileManager_XDG.swift diff --git a/Foundation.xcodeproj/project.pbxproj b/Foundation.xcodeproj/project.pbxproj index d840b0608b..af4835a0db 100644 --- a/Foundation.xcodeproj/project.pbxproj +++ b/Foundation.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 0383A1751D2E558A0052E5D1 /* TestStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0383A1741D2E558A0052E5D1 /* TestStream.swift */; }; 03B6F5841F15F339004F25AF /* TestURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B6F5831F15F339004F25AF /* TestURLProtocol.swift */; }; - 1513A8432044893F00539722 /* FileManager_XDG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1513A8422044893F00539722 /* FileManager_XDG.swift */; }; 1520469B1D8AEABE00D02E36 /* HTTPServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1520469A1D8AEABE00D02E36 /* HTTPServer.swift */; }; 153E951120111DC500F250BE /* CFKnownLocations.h in Headers */ = {isa = PBXBuildFile; fileRef = 153E950F20111DC500F250BE /* CFKnownLocations.h */; settings = {ATTRIBUTES = (Private, ); }; }; 153E951220111DC500F250BE /* CFKnownLocations.c in Sources */ = {isa = PBXBuildFile; fileRef = 153E951020111DC500F250BE /* CFKnownLocations.c */; }; @@ -516,7 +515,6 @@ /* Begin PBXFileReference section */ 0383A1741D2E558A0052E5D1 /* TestStream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestStream.swift; sourceTree = ""; }; 03B6F5831F15F339004F25AF /* TestURLProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestURLProtocol.swift; sourceTree = ""; }; - 1513A8422044893F00539722 /* FileManager_XDG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager_XDG.swift; sourceTree = ""; }; 1520469A1D8AEABE00D02E36 /* HTTPServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPServer.swift; sourceTree = ""; }; 153E950F20111DC500F250BE /* CFKnownLocations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFKnownLocations.h; sourceTree = ""; }; 153E951020111DC500F250BE /* CFKnownLocations.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = CFKnownLocations.c; sourceTree = ""; }; @@ -1824,7 +1822,6 @@ children = ( EADE0B5D1BD15DFF00C49C64 /* FileHandle.swift */, EADE0B5E1BD15DFF00C49C64 /* FileManager.swift */, - 1513A8422044893F00539722 /* FileManager_XDG.swift */, EADE0B7A1BD15DFF00C49C64 /* Process.swift */, 5BDC3F2F1BCC5DCB00ED97BB /* Bundle.swift */, 5BDC3F411BCC5DCB00ED97BB /* ProcessInfo.swift */, @@ -2347,7 +2344,6 @@ 5BECBA3A1D1CAE9A00B39B1F /* NSMeasurement.swift in Sources */, 5BF7AEB21BCD51F9008F214A /* NSNumber.swift in Sources */, 61D2F9AF1FECFB3E0033306A /* NativeProtocol.swift in Sources */, - 1513A8432044893F00539722 /* FileManager_XDG.swift in Sources */, B9974B991EDF4A22007F15B8 /* HTTPURLProtocol.swift in Sources */, 5BCD03821D3EE35C00E3FF9B /* TimeZone.swift in Sources */, EADE0BBC1BD15E0000C49C64 /* URLCache.swift in Sources */, @@ -2717,7 +2713,6 @@ DYLIB_COMPATIBILITY_VERSION = 150; DYLIB_CURRENT_VERSION = 1303; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_TESTABILITY = YES; FRAMEWORK_VERSION = A; GCC_PREFIX_HEADER = CoreFoundation/Base.subproj/CoreFoundation_Prefix.h; HEADER_SEARCH_PATHS = ( @@ -2791,7 +2786,6 @@ DYLIB_COMPATIBILITY_VERSION = 150; DYLIB_CURRENT_VERSION = 1303; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_TESTABILITY = YES; FRAMEWORK_VERSION = A; GCC_PREFIX_HEADER = CoreFoundation/Base.subproj/CoreFoundation_Prefix.h; HEADER_SEARCH_PATHS = ( diff --git a/Foundation/FileManager.swift b/Foundation/FileManager.swift index 116c8fa3b9..752cb07300 100644 --- a/Foundation/FileManager.swift +++ b/Foundation/FileManager.swift @@ -7,11 +7,9 @@ // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // -#if canImport(Darwin) +#if os(macOS) || os(iOS) import Darwin -#endif - -#if canImport(Glibc) +#elseif os(Linux) || CYGWIN import Glibc #endif @@ -122,297 +120,10 @@ open class FileManager : NSObject { return result } - private enum _SearchPathDomain { - case system - case local - case network - case user - - init?(_ domainMask: SearchPathDomainMask) { - if domainMask == .systemDomainMask { - self = .system; return - } - if domainMask == .localDomainMask { - self = .local; return - } - if domainMask == .networkDomainMask { - self = .network; return - } - if domainMask == .userDomainMask { - self = .user; return - } - - return nil - } - } - - private func darwinPathURLs(for domain: _SearchPathDomain, system: String?, local: String?, network: String?, userHomeSubpath: String?) -> [URL] { - switch domain { - case .system: - guard let path = system else { return [] } - return [ URL(fileURLWithPath: path, isDirectory: true) ] - case .local: - guard let path = local else { return [] } - return [ URL(fileURLWithPath: path, isDirectory: true) ] - case .network: - guard let path = network else { return [] } - return [ URL(fileURLWithPath: path, isDirectory: true) ] - case .user: - guard let path = userHomeSubpath else { return [] } - return [ URL(fileURLWithPath: path, isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - } - } - - private func darwinPathURLs(for domain: _SearchPathDomain, all: String, useLocalDirectoryForSystem: Bool = false) -> [URL] { - switch domain { - case .system: - return [ URL(fileURLWithPath: useLocalDirectoryForSystem ? "/\(all)" : "/System/\(all)", isDirectory: true) ] - case .local: - return [ URL(fileURLWithPath: "/\(all)", isDirectory: true) ] - case .network: - return [ URL(fileURLWithPath: "/Network/\(all)", isDirectory: true) ] - case .user: - return [ URL(fileURLWithPath: all, isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - } - } - - #if os(Windows) // Non-Apple OSes that do not implement FHS/XDG are not currently supported. - @available(*, unavailable, message: "Not implemented for this OS") - open func urls(for directory: SearchPathDirectory, in domainMask: SearchPathDomainMask) -> [URL] { - NSUnimplemented() - } - #else /* -URLsForDirectory:inDomains: is analogous to NSSearchPathForDirectoriesInDomains(), but returns an array of NSURL instances for use with URL-taking APIs. This API is suitable when you need to search for a file or files which may live in one of a variety of locations in the domains specified. */ open func urls(for directory: SearchPathDirectory, in domainMask: SearchPathDomainMask) -> [URL] { - guard let domain = _SearchPathDomain(domainMask) else { - fatalError("Values other than .systemDomainMask, .localDomainMask, .userDomainMask, .networkDomainMask are unsupported") - } - - // We are going to return appropriate paths on Darwin, but [] on platforms that do not have comparable locations. - // For example, on FHS/XDG systems, applications are not installed in a single path. - - let useDarwinPaths: Bool - if let envVar = ProcessInfo.processInfo.environment["_NSFileManagerUseXDGPathsForDirectoryDomains"] { - useDarwinPaths = !NSString(string: envVar).boolValue - } else { - #if canImport(Darwin) - useDarwinPaths = true - #else - useDarwinPaths = false - #endif - } - - if useDarwinPaths { - return darwinURLs(for: directory, in: domain) - } else { - return xdgURLs(for: directory, in: domain) - } - } - #endif - - private func xdgURLs(for directory: SearchPathDirectory, in domain: _SearchPathDomain) -> [URL] { - // FHS/XDG-compliant OSes: - switch directory { - case .autosavedInformationDirectory: - let runtimePath = _SwiftValue.fetch(nonOptional: _CFXDGCreateDataHomePath()) as! String - return [ URL(fileURLWithPath: "Autosave Information", isDirectory: true, relativeTo: URL(fileURLWithPath: runtimePath, isDirectory: true)) ] - - case .desktopDirectory: - guard domain == .user else { return [] } - return [ _XDGUserDirectory.desktop.url ] - - case .documentDirectory: - guard domain == .user else { return [] } - return [ _XDGUserDirectory.documents.url ] - - case .cachesDirectory: - guard domain == .user else { return [] } - let path = _SwiftValue.fetch(nonOptional: _CFXDGCreateCacheDirectoryPath()) as! String - return [ URL(fileURLWithPath: path, isDirectory: true) ] - - case .applicationSupportDirectory: - guard domain == .user else { return [] } - let path = _SwiftValue.fetch(nonOptional: _CFXDGCreateDataHomePath()) as! String - return [ URL(fileURLWithPath: path, isDirectory: true) ] - - case .downloadsDirectory: - guard domain == .user else { return [] } - return [ _XDGUserDirectory.download.url ] - - case .userDirectory: - guard domain == .local else { return [] } - return [ URL(fileURLWithPath: "/home", isDirectory: true) ] - - case .moviesDirectory: - return [ _XDGUserDirectory.videos.url ] - - case .musicDirectory: - guard domain == .user else { return [] } - return [ _XDGUserDirectory.music.url ] - - case .picturesDirectory: - guard domain == .user else { return [] } - return [ _XDGUserDirectory.pictures.url ] - - case .sharedPublicDirectory: - guard domain == .user else { return [] } - return [ _XDGUserDirectory.publicShare.url ] - - case .trashDirectory: - let userTrashURL = URL(fileURLWithPath: ".Trash", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) - if domain == .user || domain == .local { - return [ userTrashURL ] - } else { - return [] - } - - // None of these are supported outside of Darwin: - case .applicationDirectory: - fallthrough - case .demoApplicationDirectory: - fallthrough - case .developerApplicationDirectory: - fallthrough - case .adminApplicationDirectory: - fallthrough - case .libraryDirectory: - fallthrough - case .developerDirectory: - fallthrough - case .documentationDirectory: - fallthrough - case .coreServiceDirectory: - fallthrough - case .inputMethodsDirectory: - fallthrough - case .preferencePanesDirectory: - fallthrough - case .applicationScriptsDirectory: - fallthrough - case .allApplicationsDirectory: - fallthrough - case .allLibrariesDirectory: - fallthrough - case .printerDescriptionDirectory: - fallthrough - case .itemReplacementDirectory: - return [] - } - } - - private func darwinURLs(for directory: SearchPathDirectory, in domain: _SearchPathDomain) -> [URL] { - switch directory { - case .applicationDirectory: - return darwinPathURLs(for: domain, all: "Applications", useLocalDirectoryForSystem: true) - - case .demoApplicationDirectory: - return darwinPathURLs(for: domain, all: "Demos", useLocalDirectoryForSystem: true) - - case .developerApplicationDirectory: - return darwinPathURLs(for: domain, all: "Developer/Applications", useLocalDirectoryForSystem: true) - - case .adminApplicationDirectory: - return darwinPathURLs(for: domain, all: "Applications/Utilities", useLocalDirectoryForSystem: true) - - case .libraryDirectory: - return darwinPathURLs(for: domain, all: "Library") - - case .developerDirectory: - return darwinPathURLs(for: domain, all: "Developer", useLocalDirectoryForSystem: true) - - case .documentationDirectory: - return darwinPathURLs(for: domain, all: "Library/Documentation") - - case .coreServiceDirectory: - return darwinPathURLs(for: domain, system: "/System/Library/CoreServices", local: nil, network: nil, userHomeSubpath: nil) - - case .autosavedInformationDirectory: - return darwinPathURLs(for: domain, system: nil, local: nil, network: nil, userHomeSubpath: "Library/Autosave Information") - - case .inputMethodsDirectory: - return darwinPathURLs(for: domain, all: "Library/Input Methods") - - case .preferencePanesDirectory: - return darwinPathURLs(for: domain, system: "/System/Library/PreferencePanes", local: "/Library/PreferencePanes", network: nil, userHomeSubpath: "Library/PreferencePanes") - - case .applicationScriptsDirectory: - // Only the ObjC Foundation can know where this is. - return [] - - case .allApplicationsDirectory: - var directories: [URL] = [] - directories.append(contentsOf: darwinPathURLs(for: domain, all: "Applications", useLocalDirectoryForSystem: true)) - directories.append(contentsOf: darwinPathURLs(for: domain, all: "Demos", useLocalDirectoryForSystem: true)) - directories.append(contentsOf: darwinPathURLs(for: domain, all: "Developer/Applications", useLocalDirectoryForSystem: true)) - directories.append(contentsOf: darwinPathURLs(for: domain, all: "Applications/Utilities", useLocalDirectoryForSystem: true)) - return directories - - case .allLibrariesDirectory: - var directories: [URL] = [] - directories.append(contentsOf: darwinPathURLs(for: domain, all: "Library")) - directories.append(contentsOf: darwinPathURLs(for: domain, all: "Developer")) - return directories - - case .printerDescriptionDirectory: - guard domain == .system else { return [] } - return [ URL(fileURLWithPath: "/System/Library/Printers/PPD", isDirectory: true) ] - - case .desktopDirectory: - guard domain == .user else { return [] } - return [ URL(fileURLWithPath: "Desktop", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - - case .documentDirectory: - guard domain == .user else { return [] } - return [ URL(fileURLWithPath: "Documents", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - - case .cachesDirectory: - guard domain == .user else { return [] } - return [ URL(fileURLWithPath: "Library/Caches", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - - case .applicationSupportDirectory: - guard domain == .user else { return [] } - return [ URL(fileURLWithPath: "Library/Application Support", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - - case .downloadsDirectory: - guard domain == .user else { return [] } - return [ URL(fileURLWithPath: "Downloads", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - - case .userDirectory: - return darwinPathURLs(for: domain, system: nil, local: "/Users", network: "/Network/Users", userHomeSubpath: nil) - - case .moviesDirectory: - guard domain == .user else { return [] } - return [ URL(fileURLWithPath: "Movies", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - - case .musicDirectory: - guard domain == .user else { return [] } - return [ URL(fileURLWithPath: "Music", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - - case .picturesDirectory: - guard domain == .user else { return [] } - return [ URL(fileURLWithPath: "Pictures", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - - case .sharedPublicDirectory: - guard domain == .user else { return [] } - return [ URL(fileURLWithPath: "Public", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) ] - - case .trashDirectory: - let userTrashURL = URL(fileURLWithPath: ".Trash", isDirectory: true, relativeTo: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)) - if domain == .user || domain == .local { - return [ userTrashURL ] - } else { - return [] - } - - case .itemReplacementDirectory: - // This directory is only returned by url(for:in:appropriateFor:create:) - return [] - } - } - - private enum URLForDirectoryError: Error { - case directoryUnknown + NSUnimplemented() } /* -URLForDirectory:inDomain:appropriateForURL:create:error: is a URL-based replacement for FSFindFolder(). It allows for the specification and (optional) creation of a specific directory for a particular purpose (e.g. the replacement of a particular item on disk, or a particular Library directory. @@ -420,35 +131,7 @@ open class FileManager : NSObject { You may pass only one of the values from the NSSearchPathDomainMask enumeration, and you may not pass NSAllDomainsMask. */ open func url(for directory: SearchPathDirectory, in domain: SearchPathDomainMask, appropriateFor url: URL?, create shouldCreate: Bool) throws -> URL { - let urls = self.urls(for: directory, in: domain) - guard let url = urls.first else { - // On Apple OSes, this case returns nil without filling in the error parameter; Swift then synthesizes an error rather than trap. - // We simulate that behavior by throwing a private error. - throw URLForDirectoryError.directoryUnknown - } - - if shouldCreate { - var attributes: [FileAttributeKey : Any] = [:] - - switch _SearchPathDomain(domain) { - case .some(.user): - attributes[.posixPermissions] = 0700 - - case .some(.system): - attributes[.posixPermissions] = 0755 - attributes[.ownerAccountID] = 0 // root - #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) - attributes[.ownerAccountID] = 80 // on Darwin, the admin group's fixed ID. - #endif - - default: - break - } - - try createDirectory(at: url, withIntermediateDirectories: true, attributes: attributes) - } - - return url + NSUnimplemented() } /* Sets 'outRelationship' to NSURLRelationshipContains if the directory at 'directoryURL' directly or indirectly contains the item at 'otherURL', meaning 'directoryURL' is found while enumerating parent URLs starting from 'otherURL'. Sets 'outRelationship' to NSURLRelationshipSame if 'directoryURL' and 'otherURL' locate the same item, meaning they have the same NSURLFileResourceIdentifierKey value. If 'directoryURL' is not a directory, or does not contain 'otherURL' and they do not locate the same file, then sets 'outRelationship' to NSURLRelationshipOther. If an error occurs, returns NO and sets 'error'. diff --git a/Foundation/FileManager_XDG.swift b/Foundation/FileManager_XDG.swift deleted file mode 100644 index e44e9b0be7..0000000000 --- a/Foundation/FileManager_XDG.swift +++ /dev/null @@ -1,125 +0,0 @@ -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// - -import CoreFoundation - -enum _XDGUserDirectory: String { - case desktop = "DESKTOP" - case download = "DOWNLOAD" - case publicShare = "PUBLICSHARE" - case documents = "DOCUMENTS" - case music = "MUSIC" - case pictures = "PICTURES" - case videos = "VIDEOS" - - static let allDirectories: [_XDGUserDirectory] = [ - .desktop, - .download, - .publicShare, - .documents, - .music, - .pictures, - .videos, - ] - - var url: URL { - return url(userConfiguration: _XDGUserDirectory.configuredDirectoryURLs, - osDefaultConfiguration: _XDGUserDirectory.osDefaultDirectoryURLs, - stopgaps: _XDGUserDirectory.stopgapDefaultDirectoryURLs) - } - - func url(userConfiguration: [_XDGUserDirectory: URL], - osDefaultConfiguration: [_XDGUserDirectory: URL], - stopgaps: [_XDGUserDirectory: URL]) -> URL { - if let url = userConfiguration[self] { - return url - } else if let url = osDefaultConfiguration[self] { - return url - } else { - return stopgaps[self]! - } - } - - static let stopgapDefaultDirectoryURLs: [_XDGUserDirectory: URL] = { - let home = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true) - return [ - .desktop: home.appendingPathComponent("Desktop"), - .download: home.appendingPathComponent("Downloads"), - .publicShare: home.appendingPathComponent("Public"), - .documents: home.appendingPathComponent("Documents"), - .music: home.appendingPathComponent("Music"), - .pictures: home.appendingPathComponent("Pictures"), - .videos: home.appendingPathComponent("Videos"), - ] - }() - - static func userDirectories(fromConfigurationFileAt url: URL) -> [_XDGUserDirectory: URL]? { - if let configuration = try? String(contentsOf: url, encoding: .utf8) { - return userDirectories(fromConfiguration: configuration) - } else { - return nil - } - } - - static func userDirectories(fromConfiguration configuration: String) -> [_XDGUserDirectory: URL] { - var entries: [_XDGUserDirectory: URL] = [:] - let home = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true) - - // Parse it: - let lines = configuration.split(separator: "\n") - for line in lines { - if let range = line.range(of: "=") { - var variable = String(line[line.startIndex ..< range.lowerBound].trimmingCharacters(in: .whitespaces)) - - let prefix = "XDG_" - let suffix = "_DIR" - if variable.hasPrefix(prefix) && variable.hasSuffix(suffix) { - let endOfPrefix = variable.index(variable.startIndex, offsetBy: prefix.length) - let startOfSuffix = variable.index(variable.endIndex, offsetBy: -suffix.length) - - variable = String(variable[endOfPrefix ..< startOfSuffix]) - } - - guard let directory = _XDGUserDirectory(rawValue: variable) else { - continue - } - - let path = String(line[range.upperBound ..< line.endIndex]).trimmingCharacters(in: .whitespaces) - if !path.isEmpty { - entries[directory] = URL(fileURLWithPath: path, isDirectory: true, relativeTo: home) - } - } else { - return [:] // Incorrect syntax. - } - } - - return entries - } - - static let configuredDirectoryURLs: [_XDGUserDirectory: URL] = { - let configurationHome = _SwiftValue.fetch(nonOptional: _CFXDGCreateConfigHomePath()) as! String - let configurationFile = URL(fileURLWithPath: "user-dirs.dirs", isDirectory: false, relativeTo: URL(fileURLWithPath: configurationHome, isDirectory: true)) - - return userDirectories(fromConfigurationFileAt: configurationFile) ?? [:] - }() - - static let osDefaultDirectoryURLs: [_XDGUserDirectory: URL] = { - let configurationDirs = _SwiftValue.fetch(nonOptional: _CFXDGCreateConfigDirectoriesPaths()) as! [String] - - for directory in configurationDirs { - let configurationFile = URL(fileURLWithPath: directory, isDirectory: true).appendingPathComponent("user-dirs.defaults") - - if let result = userDirectories(fromConfigurationFileAt: configurationFile) { - return result - } - } - - return [:] - }() -} diff --git a/Foundation/NSPathUtilities.swift b/Foundation/NSPathUtilities.swift index 659611b7f7..a7ea0ed446 100755 --- a/Foundation/NSPathUtilities.swift +++ b/Foundation/NSPathUtilities.swift @@ -562,29 +562,7 @@ extension FileManager { } public func NSSearchPathForDirectoriesInDomains(_ directory: FileManager.SearchPathDirectory, _ domainMask: FileManager.SearchPathDomainMask, _ expandTilde: Bool) -> [String] { - let knownDomains: [FileManager.SearchPathDomainMask] = [ - .userDomainMask, - .networkDomainMask, - .localDomainMask, - .systemDomainMask, - ] - - var result: [URL] = [] - - for domain in knownDomains { - if domainMask.contains(domain) { - result.append(contentsOf: FileManager.default.urls(for: directory, in: domain)) - } - } - - return result.map { (url) in - var path = url.absoluteURL.path - if expandTilde { - path = NSString(string: path).expandingTildeInPath - } - - return path - } + NSUnimplemented() } public func NSHomeDirectory() -> String { diff --git a/TestFoundation/TestFileManager.swift b/TestFoundation/TestFileManager.swift index 9d7ab2963b..8c8295d7d3 100644 --- a/TestFoundation/TestFileManager.swift +++ b/TestFoundation/TestFileManager.swift @@ -7,16 +7,10 @@ // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // -#if !DEPLOYMENT_RUNTIME_OBJC && (os(Linux) || os(Android)) -@testable import Foundation -#else -@testable import SwiftFoundation -#endif - class TestFileManager : XCTestCase { static var allTests: [(String, (TestFileManager) -> () throws -> Void)] { - var tests: [(String, (TestFileManager) -> () throws -> Void)] = [ + return [ ("test_createDirectory", test_createDirectory ), ("test_createFile", test_createFile ), ("test_moveFile", test_moveFile), @@ -35,18 +29,8 @@ class TestFileManager : XCTestCase { ("test_temporaryDirectoryForUser", test_temporaryDirectoryForUser), ("test_creatingDirectoryWithShortIntermediatePath", test_creatingDirectoryWithShortIntermediatePath), ("test_mountedVolumeURLs", test_mountedVolumeURLs), - ("test_XDGStopgapsCoverAllConstants", test_XDGStopgapsCoverAllConstants), + ("test_contentsEqual", test_contentsEqual) ] - -#if !DEPLOYMENT_RUNTIME_OBJC - tests.append(contentsOf: [ - ("test_parseXDGConfiguration", test_parseXDGConfiguration), - ("test_xdgURLSelection", test_xdgURLSelection), - ("test_fetchXDGPathsFromHelper", test_fetchXDGPathsFromHelper), - ]) -#endif - - return tests } func ignoreError(_ block: () throws -> Void) { @@ -963,186 +947,4 @@ class TestFileManager : XCTestCase { XCTAssertFalse(fm.contentsEqual(atPath: dataFile1.path, andPath: dataFile2.path)) XCTAssertFalse(fm.contentsEqual(atPath: testDir1.path, andPath: testDir2.path)) } - -#if !DEPLOYMENT_RUNTIME_OBJC // XDG tests require swift-corelibs-foundation - func test_XDGStopgapsCoverAllConstants() { - let stopgaps = _XDGUserDirectory.stopgapDefaultDirectoryURLs - for directory in _XDGUserDirectory.allDirectories { - XCTAssertNotNil(stopgaps[directory]) - } - } - - func test_parseXDGConfiguration() { - let home = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true) - - let assertConfigurationProduces = { (configuration: String, paths: [_XDGUserDirectory: String]) in - XCTAssertEqual(_XDGUserDirectory.userDirectories(fromConfiguration: configuration).mapValues({ $0.absoluteURL.path }), - paths.mapValues({ URL(fileURLWithPath: $0, isDirectory: true, relativeTo: home).absoluteURL.path })) - } - - assertConfigurationProduces("", [:]) - - // Test partial configuration and paths relative to home. - assertConfigurationProduces( -""" -DESKTOP=/xdg_test/Desktop -MUSIC=/xdg_test/Music -PICTURES=Pictures -""", [ .desktop: "/xdg_test/Desktop", - .music: "/xdg_test/Music", - .pictures: "Pictures" ]) - - // Test full configuration with XDG_…_DIR syntax, duplicate keys and varying indentation - // 'XDG_MUSIC_DIR' is duplicated, below. - assertConfigurationProduces( -""" - XDG_MUSIC_DIR=ShouldNotBeUsedUseTheOneBelowInstead - - XDG_DESKTOP_DIR=Desktop - XDG_DOWNLOAD_DIR=Download - XDG_PUBLICSHARE_DIR=Public -XDG_DOCUMENTS_DIR=Documents - XDG_MUSIC_DIR=Music -XDG_PICTURES_DIR=Pictures - XDG_VIDEOS_DIR=Videos -""", [ .desktop: "Desktop", - .download: "Download", - .publicShare: "Public", - .documents: "Documents", - .music: "Music", - .pictures: "Pictures", - .videos: "Videos" ]) - - // Same, without XDG…DIR. - assertConfigurationProduces( -""" - MUSIC=ShouldNotBeUsedUseTheOneBelowInstead - - DESKTOP=Desktop - DOWNLOAD=Download - PUBLICSHARE=Public -DOCUMENTS=Documents - MUSIC=Music -PICTURES=Pictures - VIDEOS=Videos -""", [ .desktop: "Desktop", - .download: "Download", - .publicShare: "Public", - .documents: "Documents", - .music: "Music", - .pictures: "Pictures", - .videos: "Videos" ]) - - assertConfigurationProduces( -""" - DESKTOP=/home/Desktop -This configuration file has an invalid syntax. -""", [:]) - } - - func test_xdgURLSelection() { - let home = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true) - - let configuration = _XDGUserDirectory.userDirectories(fromConfiguration: -""" -DESKTOP=UserDesktop -""" - ) - - let osDefaults = _XDGUserDirectory.userDirectories(fromConfiguration: -""" -DESKTOP=SystemDesktop -PUBLICSHARE=SystemPublicShare -""" - ) - - let stopgaps = _XDGUserDirectory.userDirectories(fromConfiguration: -""" -DESKTOP=StopgapDesktop -DOWNLOAD=StopgapDownload -PUBLICSHARE=StopgapPublicShare -DOCUMENTS=StopgapDocuments -MUSIC=StopgapMusic -PICTURES=StopgapPictures -VIDEOS=StopgapVideos -""" - ) - - let assertSameAbsolutePath = { (lhs: URL, rhs: URL) in - XCTAssertEqual(lhs.absoluteURL.path, rhs.absoluteURL.path) - } - - assertSameAbsolutePath(_XDGUserDirectory.desktop.url(userConfiguration: configuration, osDefaultConfiguration: osDefaults, stopgaps: stopgaps), home.appendingPathComponent("UserDesktop")) - assertSameAbsolutePath(_XDGUserDirectory.publicShare.url(userConfiguration: configuration, osDefaultConfiguration: osDefaults, stopgaps: stopgaps), home.appendingPathComponent("SystemPublicShare")) - assertSameAbsolutePath(_XDGUserDirectory.music.url(userConfiguration: configuration, osDefaultConfiguration: osDefaults, stopgaps: stopgaps), home.appendingPathComponent("StopgapMusic")) - } - - enum TestError: Error { - case notImplementedOnThisPlatform - } - - func printPathByRunningHelper(withConfiguration config: String, method: String, identifier: String) throws -> String { - #if os(Android) - throw TestError.notImplementedOnThisPlatform - #endif - - let uuid = UUID().uuidString - let path = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("org.swift.Foundation.XDGTestHelper").appendingPathComponent(uuid) - try FileManager.default.createDirectory(at: path, withIntermediateDirectories: true) - - let configFilePath = path.appendingPathComponent("user-dirs.dirs") - try config.write(to: configFilePath, atomically: true, encoding: .utf8) - defer { - try? FileManager.default.removeItem(at: path) - } - - var environment = [ "XDG_CONFIG_HOME": path.path, - "_NSFileManagerUseXDGPathsForDirectoryDomains": "YES" ] - - // Copy all LD_* and DYLD_* variables over, in case we're running with altered paths (e.g. from ninja test on Linux) - for entry in ProcessInfo.processInfo.environment.lazy.filter({ $0.key.hasPrefix("DYLD_") || $0.key.hasPrefix("LD_") }) { - environment[entry.key] = entry.value - } - - let helper = xdgTestHelperURL() - let (stdout, _) = try runTask([ helper.path, "--nspathfor", method, identifier ], - environment: environment) - - return stdout.trimmingCharacters(in: CharacterSet.newlines) - } - - func assertFetchingPath(withConfiguration config: String, identifier: String, yields path: String) { - for method in [ "NSSearchPath", "FileManagerDotURLFor", "FileManagerDotURLsFor" ] { - do { - let found = try printPathByRunningHelper(withConfiguration: config, method: method, identifier: identifier) - XCTAssertEqual(found, path) - } catch let error { - XCTFail("Failed with method \(method), configuration \(config), identifier \(identifier), equal to \(path), error \(error)") - } - } - } - - func test_fetchXDGPathsFromHelper() { - let prefix = NSHomeDirectory() + "/_Foundation_Test_" - - let configuration = """ - DESKTOP=\(prefix)/Desktop - DOWNLOAD=\(prefix)/Download - PUBLICSHARE=\(prefix)/PublicShare - DOCUMENTS=\(prefix)/Documents - MUSIC=\(prefix)/Music - PICTURES=\(prefix)/Pictures - VIDEOS=\(prefix)/Videos - """ - - assertFetchingPath(withConfiguration: configuration, identifier: "desktop", yields: "\(prefix)/Desktop") - assertFetchingPath(withConfiguration: configuration, identifier: "download", yields: "\(prefix)/Download") - assertFetchingPath(withConfiguration: configuration, identifier: "publicShare", yields: "\(prefix)/PublicShare") - assertFetchingPath(withConfiguration: configuration, identifier: "documents", yields: "\(prefix)/Documents") - assertFetchingPath(withConfiguration: configuration, identifier: "music", yields: "\(prefix)/Music") - assertFetchingPath(withConfiguration: configuration, identifier: "pictures", yields: "\(prefix)/Pictures") - assertFetchingPath(withConfiguration: configuration, identifier: "videos", yields: "\(prefix)/Videos") - } -#endif // !DEPLOYMENT_RUNTIME_OBJC - } diff --git a/TestFoundation/TestProcess.swift b/TestFoundation/TestProcess.swift index 475d131611..4690f07c34 100644 --- a/TestFoundation/TestProcess.swift +++ b/TestFoundation/TestProcess.swift @@ -395,7 +395,7 @@ private enum Error: Swift.Error { } #if !os(Android) -internal func runTask(_ arguments: [String], environment: [String: String]? = nil, currentDirectoryPath: String? = nil) throws -> (String, String) { +private func runTask(_ arguments: [String], environment: [String: String]? = nil, currentDirectoryPath: String? = nil) throws -> (String, String) { let process = Process() var arguments = arguments diff --git a/TestFoundation/xdgTestHelper/main.swift b/TestFoundation/xdgTestHelper/main.swift index 2aa185c67a..86faf742b1 100644 --- a/TestFoundation/xdgTestHelper/main.swift +++ b/TestFoundation/xdgTestHelper/main.swift @@ -7,12 +7,10 @@ // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // -#if DEPLOYMENT_RUNTIME_OBJC +#if DEPLOYMENT_RUNTIME_OBJC || os(Linux) || os(Android) import Foundation -#elseif os(Linux) || os(Android) -@testable import Foundation #else -@testable import SwiftFoundation +import SwiftFoundation #endif enum HelperCheckStatus : Int32 { @@ -57,93 +55,15 @@ class XDGCheck { } } -// ----- - -#if !DEPLOYMENT_RUNTIME_OBJC -struct NSURLForPrintTest { - enum Method: String { - case NSSearchPath - case FileManagerDotURLFor - case FileManagerDotURLsFor +if let arg = ProcessInfo.processInfo.arguments.last { + if arg == "--xdgcheck" { + XDGCheck.run() } - - enum Identifier: String { - case desktop - case download - case publicShare - case documents - case music - case pictures - case videos + if arg == "--getcwd" { + print(FileManager.default.currentDirectoryPath) } - - let method: Method - let identifier: Identifier - - func run() { - let directory: FileManager.SearchPathDirectory - - switch identifier { - case .desktop: - directory = .desktopDirectory - case .download: - directory = .downloadsDirectory - case .publicShare: - directory = .sharedPublicDirectory - case .documents: - directory = .documentDirectory - case .music: - directory = .musicDirectory - case .pictures: - directory = .picturesDirectory - case .videos: - directory = .moviesDirectory - } - - switch method { - case .NSSearchPath: - print(NSSearchPathForDirectoriesInDomains(directory, .userDomainMask, true).first!) - case .FileManagerDotURLFor: - print(try! FileManager.default.url(for: directory, in: .userDomainMask, appropriateFor: nil, create: false).path) - case .FileManagerDotURLsFor: - print(FileManager.default.urls(for: directory, in: .userDomainMask).first!.path) - } + if arg == "--echo-PWD" { + print(ProcessInfo.processInfo.environment["PWD"] ?? "") } } -#endif - -// ----- - -var arguments = ProcessInfo.processInfo.arguments.dropFirst().makeIterator() - -guard let arg = arguments.next() else { - fatalError("The unit test must specify the correct number of flags and arguments.") -} - -switch arg { -case "--xdgcheck": - XDGCheck.run() - -case "--getcwd": - print(FileManager.default.currentDirectoryPath) - -case "--echo-PWD": - print(ProcessInfo.processInfo.environment["PWD"] ?? "") - -#if !DEPLOYMENT_RUNTIME_OBJC -case "--nspathfor": - guard let methodString = arguments.next(), - let method = NSURLForPrintTest.Method(rawValue: methodString), - let identifierString = arguments.next(), - let identifier = NSURLForPrintTest.Identifier(rawValue: identifierString) else { - fatalError("Usage: --nspathfor ") - } - - let test = NSURLForPrintTest(method: method, identifier: identifier) - test.run() -#endif - -default: - fatalError("These arguments are not recognized. Only run this from a unit test.") -} diff --git a/build.py b/build.py index 78c6611122..341f539e0c 100755 --- a/build.py +++ b/build.py @@ -30,8 +30,7 @@ swift_cflags += ['-DCYGWIN'] if Configuration.current.build_mode == Configuration.Debug: - foundation.LDFLAGS += ' -lswiftSwiftOnoneSupport ' - swift_cflags += ['-enable-testing'] + foundation.LDFLAGS += ' -lswiftSwiftOnoneSupport ' foundation.ASFLAGS = " ".join([ '-DCF_CHARACTERSET_BITMAP=\\"CoreFoundation/CharacterSets/CFCharacterSetBitmaps.bitmap\\"', @@ -368,7 +367,6 @@ 'Foundation/NSExpression.swift', 'Foundation/FileHandle.swift', 'Foundation/FileManager.swift', - 'Foundation/FileManager_XDG.swift', 'Foundation/Formatter.swift', 'Foundation/NSGeometry.swift', 'Foundation/Host.swift', @@ -491,9 +489,6 @@ 'Foundation/JSONEncoder.swift', ]) -if Configuration.current.build_mode == Configuration.Debug: - swift_sources.enable_testable_import = True - swift_sources.add_dependency(headers) foundation.add_phase(swift_sources) diff --git a/lib/phases.py b/lib/phases.py index 921e8eef1a..ab46998670 100644 --- a/lib/phases.py +++ b/lib/phases.py @@ -348,7 +348,6 @@ def __init__(self, sources): BuildPhase.__init__(self, "CompileSwiftSources") if sources is not None: self._sources = sources - self.enable_testable_import = False @property def product(self): @@ -397,15 +396,11 @@ def generate(self): partial_modules += compiled.relative() + ".~partial.swiftmodule " partial_docs += compiled.relative() + ".~partial.swiftdoc " - testable_import_flags = "" - if self.enable_testable_import: - testable_import_flags = "-enable-testing" - generated += """ build """ + self._module.relative() + ": MergeSwiftModule " + objects + """ partials = """ + partial_modules + """ module_name = """ + self.product.name + """ - flags = """ + testable_import_flags + " -I" + self.product.public_module_path.relative() + """ """ + TargetConditional.value(self.product.SWIFTCFLAGS) + """ -emit-module-doc-path """ + self._module.parent().path_by_appending(self.product.name).relative() + """.swiftdoc + flags = -I""" + self.product.public_module_path.relative() + """ """ + TargetConditional.value(self.product.SWIFTCFLAGS) + """ -emit-module-doc-path """ + self._module.parent().path_by_appending(self.product.name).relative() + """.swiftdoc """ return generated