diff --git a/Package.resolved b/Package.resolved index 55495a06..e36d5fa6 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,15 +1,6 @@ { "object": { "pins": [ - { - "package": "PathKit", - "repositoryURL": "https://github.com/kylef/PathKit.git", - "state": { - "branch": null, - "revision": "3bfd2737b700b9a36565a8c94f4ad2b050a5e574", - "version": "1.0.1" - } - }, { "package": "Spectre", "repositoryURL": "https://github.com/kylef/Spectre.git", diff --git a/Package.swift b/Package.swift index 43d20196..41604242 100644 --- a/Package.swift +++ b/Package.swift @@ -7,13 +7,10 @@ let package = Package( .library(name: "Stencil", targets: ["Stencil"]) ], dependencies: [ - .package(url: "https://github.com/kylef/PathKit.git", from: "1.0.1"), .package(url: "https://github.com/kylef/Spectre.git", from: "0.10.1") ], targets: [ - .target(name: "Stencil", dependencies: [ - "PathKit" - ]), + .target(name: "Stencil"), .testTarget(name: "StencilTests", dependencies: [ "Stencil", "Spectre" diff --git a/Sources/Stencil/Include.swift b/Sources/Stencil/Include.swift index 65f2dc4a..2edfb582 100644 --- a/Sources/Stencil/Include.swift +++ b/Sources/Stencil/Include.swift @@ -4,8 +4,6 @@ // MIT Licence // -import PathKit - class IncludeNode: NodeType { let templateName: Variable let includeContext: String? diff --git a/Sources/Stencil/Loader.swift b/Sources/Stencil/Loader.swift index 76e96c80..8a3edf37 100644 --- a/Sources/Stencil/Loader.swift +++ b/Sources/Stencil/Loader.swift @@ -5,7 +5,6 @@ // import Foundation -import PathKit /// Type used for loading a template public protocol Loader { @@ -34,15 +33,17 @@ extension Loader { // A class for loading a template from disk public class FileSystemLoader: Loader, CustomStringConvertible { - public let paths: [Path] + public let paths: [String] - public init(paths: [Path]) { - self.paths = paths + public init(paths: [URL]) { + self.paths = paths.map { + $0.withUnsafeFileSystemRepresentation { String(cString: $0!) } + } } public init(bundle: [Bundle]) { - self.paths = bundle.map { bundle in - Path(bundle.bundlePath) + self.paths = bundle.map { + URL(fileURLWithPath: $0.bundlePath).withUnsafeFileSystemRepresentation { String(cString: $0!) } } } @@ -51,27 +52,19 @@ public class FileSystemLoader: Loader, CustomStringConvertible { } public func loadTemplate(name: String, environment: Environment) throws -> Template { - for path in paths { - let templatePath = try path.safeJoin(path: Path(name)) - - if !templatePath.exists { - continue - } - - let content: String = try templatePath.read() - return environment.templateClass.init(templateString: content, environment: environment, name: name) - } - - throw TemplateDoesNotExist(templateNames: [name], loader: self) + return try loadTemplate(names: [name], environment: environment) } public func loadTemplate(names: [String], environment: Environment) throws -> Template { for path in paths { for templateName in names { - let templatePath = try path.safeJoin(path: Path(templateName)) + let templatePath = URL(fileURLWithPath: templateName, relativeTo: URL(fileURLWithPath: path)) + if !templatePath.withUnsafeFileSystemRepresentation({ String(cString: $0!) }).hasPrefix(path) { + throw SuspiciousFileOperation(basePath: path, path: templateName) + } - if templatePath.exists { - let content: String = try templatePath.read() + if FileManager.default.fileExists(atPath: templatePath.path) { + let content = try String(contentsOf: templatePath) return environment.templateClass.init(templateString: content, environment: environment, name: templateName) } } @@ -107,23 +100,11 @@ public class DictionaryLoader: Loader { } } -extension Path { - func safeJoin(path: Path) throws -> Path { - let newPath = self + path - - if !newPath.absolute().description.hasPrefix(absolute().description) { - throw SuspiciousFileOperation(basePath: self, path: newPath) - } - - return newPath - } -} - class SuspiciousFileOperation: Error { - let basePath: Path - let path: Path + let basePath: String + let path: String - init(basePath: Path, path: Path) { + init(basePath: String, path: String) { self.basePath = basePath self.path = path } diff --git a/Sources/Stencil/Template.swift b/Sources/Stencil/Template.swift index 80619626..375291ac 100644 --- a/Sources/Stencil/Template.swift +++ b/Sources/Stencil/Template.swift @@ -5,7 +5,6 @@ // import Foundation -import PathKit #if os(Linux) // swiftlint:disable:next prefixed_toplevel_constant @@ -41,19 +40,7 @@ open class Template: ExpressibleByStringLiteral { throw NSError(domain: NSCocoaErrorDomain, code: NSFileNoSuchFileError, userInfo: nil) } - try self.init(URL: url) - } - - /// Create a template with a file found at the given URL - @available(*, deprecated, message: "Use Environment/FileSystemLoader instead") - public convenience init(URL: Foundation.URL) throws { - try self.init(path: Path(URL.path)) - } - - /// Create a template with a file found at the given path - @available(*, deprecated, message: "Use Environment/FileSystemLoader instead") - public convenience init(path: Path, environment: Environment? = nil, name: String? = nil) throws { - self.init(templateString: try path.read(), environment: environment, name: name) + try self.init(templateString: String(contentsOf: url)) } // MARK: ExpressibleByStringLiteral diff --git a/Sources/Stencil/Variable.swift b/Sources/Stencil/Variable.swift index 1948f4e3..75f0af7a 100644 --- a/Sources/Stencil/Variable.swift +++ b/Sources/Stencil/Variable.swift @@ -111,12 +111,12 @@ public struct Variable: Equatable, Resolvable { } else if let string = context as? String { return resolve(bit: bit, collection: string) } else if let object = context as? NSObject { // NSKeyValueCoding - #if os(Linux) - return nil - #else + #if _runtime(_ObjC) if object.responds(to: Selector(bit)) { return object.value(forKey: bit) } + #else + return nil #endif } else if let value = context as? DynamicMemberLookup { return value[dynamicMember: bit] diff --git a/Tests/StencilTests/EnvironmentBaseAndChildTemplateSpec.swift b/Tests/StencilTests/EnvironmentBaseAndChildTemplateSpec.swift index 036b986a..f02aebf1 100644 --- a/Tests/StencilTests/EnvironmentBaseAndChildTemplateSpec.swift +++ b/Tests/StencilTests/EnvironmentBaseAndChildTemplateSpec.swift @@ -4,7 +4,6 @@ // MIT Licence // -import PathKit import Spectre @testable import Stencil import XCTest @@ -17,7 +16,7 @@ final class EnvironmentBaseAndChildTemplateTests: XCTestCase { override func setUp() { super.setUp() - let path = Path(#file as String) + ".." + "fixtures" + let path = URL(fileURLWithPath: #file).deletingLastPathComponent().appendingPathComponent("fixtures") let loader = FileSystemLoader(paths: [path]) environment = Environment(loader: loader) childTemplate = "" diff --git a/Tests/StencilTests/EnvironmentIncludeTemplateSpec.swift b/Tests/StencilTests/EnvironmentIncludeTemplateSpec.swift index 67ec956e..9b237576 100644 --- a/Tests/StencilTests/EnvironmentIncludeTemplateSpec.swift +++ b/Tests/StencilTests/EnvironmentIncludeTemplateSpec.swift @@ -4,7 +4,6 @@ // MIT Licence // -import PathKit import Spectre @testable import Stencil import XCTest @@ -17,7 +16,7 @@ final class EnvironmentIncludeTemplateTests: XCTestCase { override func setUp() { super.setUp() - let path = Path(#file as String) + ".." + "fixtures" + let path = URL(fileURLWithPath: #file).deletingLastPathComponent().appendingPathComponent("fixtures") let loader = FileSystemLoader(paths: [path]) environment = Environment(loader: loader) template = "" diff --git a/Tests/StencilTests/IncludeSpec.swift b/Tests/StencilTests/IncludeSpec.swift index bb35954c..e41755c0 100644 --- a/Tests/StencilTests/IncludeSpec.swift +++ b/Tests/StencilTests/IncludeSpec.swift @@ -4,13 +4,12 @@ // MIT Licence // -import PathKit import Spectre @testable import Stencil import XCTest final class IncludeTests: XCTestCase { - private let path = Path(#file as String) + ".." + "fixtures" + private let path = URL(fileURLWithPath: #file).deletingLastPathComponent().appendingPathComponent("fixtures") private lazy var loader = FileSystemLoader(paths: [path]) private lazy var environment = Environment(loader: loader) diff --git a/Tests/StencilTests/InheritanceSpec.swift b/Tests/StencilTests/InheritanceSpec.swift index a586ffd8..fe7c76f4 100644 --- a/Tests/StencilTests/InheritanceSpec.swift +++ b/Tests/StencilTests/InheritanceSpec.swift @@ -4,13 +4,12 @@ // MIT Licence // -import PathKit import Spectre import Stencil import XCTest final class InheritanceTests: XCTestCase { - private let path = Path(#file as String) + ".." + "fixtures" + private let path = URL(fileURLWithPath: #file).deletingLastPathComponent().appendingPathComponent("fixtures") private lazy var loader = FileSystemLoader(paths: [path]) private lazy var environment = Environment(loader: loader) diff --git a/Tests/StencilTests/LexerSpec.swift b/Tests/StencilTests/LexerSpec.swift index 1ec364d0..f0335555 100644 --- a/Tests/StencilTests/LexerSpec.swift +++ b/Tests/StencilTests/LexerSpec.swift @@ -4,7 +4,6 @@ // MIT Licence // -import PathKit import Spectre @testable import Stencil import XCTest @@ -140,8 +139,11 @@ final class LexerTests: XCTestCase { } func testPerformance() throws { - let path = Path(#file as String) + ".." + "fixtures" + "huge.html" - let content: String = try path.read() + let path = URL(fileURLWithPath: #file) + .deletingLastPathComponent() + .appendingPathComponent("fixtures") + .appendingPathComponent("huge.html") + let content: String = try String(contentsOf: path) measure { let lexer = Lexer(templateString: content) diff --git a/Tests/StencilTests/LoaderSpec.swift b/Tests/StencilTests/LoaderSpec.swift index c2030bbb..4996f5c4 100644 --- a/Tests/StencilTests/LoaderSpec.swift +++ b/Tests/StencilTests/LoaderSpec.swift @@ -4,14 +4,13 @@ // MIT Licence // -import PathKit import Spectre import Stencil import XCTest final class TemplateLoaderTests: XCTestCase { func testFileSystemLoader() { - let path = Path(#file as String) + ".." + "fixtures" + let path = URL(fileURLWithPath: #file).deletingLastPathComponent().appendingPathComponent("fixtures") let loader = FileSystemLoader(paths: [path]) let environment = Environment(loader: loader)