diff --git a/README.md b/README.md index 67bf0ef..7a89896 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ That will launch a local web server you should use to preview your site, and als | Website | Repository | |------------------------|-------------------------------------------| | [jcalderita Portfolio](https://jcalderita.com) | [GitHub](https://github.com/jcalderita/portfolio-web-ignite) | +| [Fotogroep de Gender](http://www.vdhamer.com/fgDeGender) | [GitHub](https://github.com/vdhamer/Photo-Club-Hub-HTML) | ## Contributing diff --git a/Sources/Ignite/Extensions/URL-SelectDirectories.swift b/Sources/Ignite/Extensions/URL-SelectDirectories.swift new file mode 100644 index 0000000..32049be --- /dev/null +++ b/Sources/Ignite/Extensions/URL-SelectDirectories.swift @@ -0,0 +1,45 @@ +// +// URL-selectDirectories.swift +// Ignite +// https://www.github.com/twostraws/Ignite +// See LICENSE for license information. +// + +import Foundation + +extension URL { + /// Returns URL where to find Assets/Content/Includes and URL where to generate the static web site. + /// When building a package, the website is built at the source URL (and both URLs are equal). + /// When building a MacOS app, the website is built in a subdirectory of the app's sandbox. + /// - Parameter file: path of a Swift source file to find source root directory by scanning path upwards. + /// - Returns tupple containing source URL and URL where output is built. + public static func selectDirectories(from file: StaticString) throws -> SourceBuildDirectories { + var currentURL = URL(filePath: file.description) + + repeat { + currentURL = currentURL.deletingLastPathComponent() + + let packageURL = currentURL.appending(path: "Package.swift") + if FileManager.default.fileExists(atPath: packageURL.path) { + return SourceBuildDirectories(source: packageURL.deletingLastPathComponent(), + build: packageURL.deletingLastPathComponent()) + } + } while currentURL.path() != "/" + + let buildDirectory: String = NSHomeDirectory() // app's home directory for a sandboxed MacOS app + if buildDirectory.contains("/Library/Containers/") { + let buildDirectoryURL: URL = URL(filePath: buildDirectory) + return SourceBuildDirectories(source: buildDirectoryURL, + build: buildDirectoryURL) + } + + throw PublishingError.missingPackageDirectory + } + +} + +/// Provides URL to where to find Assets/Content/Includes input directories and Build output directory +public struct SourceBuildDirectories { + public let source: URL + public let build: URL +} diff --git a/Sources/Ignite/Extensions/URL-SelectSiteRootDirectory.swift b/Sources/Ignite/Extensions/URL-SelectSiteRootDirectory.swift deleted file mode 100644 index eb31dbe..0000000 --- a/Sources/Ignite/Extensions/URL-SelectSiteRootDirectory.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// URL-SelectSiteRootDirectory.swift -// Ignite -// https://www.github.com/twostraws/Ignite -// See LICENSE for license information. -// - -import Foundation - -extension URL { - /// Locates the source of a Swift package, regardless of how deep - /// in a subfolder we currently are. - public static func selectSiteRootDirectory(from file: StaticString) throws -> URL { - var currentURL = URL(filePath: file.description) - - repeat { - currentURL = currentURL.deletingLastPathComponent() - - let packageURL = currentURL.appending(path: "Package.swift") - if FileManager.default.fileExists(atPath: packageURL.path) { - return packageURL.deletingLastPathComponent() - } - } while currentURL.path() != "/" - - let homeDir: String = NSHomeDirectory() // on a sandboxed MacOS app, this is the app's home directory - if homeDir.contains("/Library/Containers/") { - do { - return try URL("file://" + homeDir, strategy: .url) - } catch { - throw PublishingError.missingSandboxHomeDirectory - } - } - - throw PublishingError.missingPackageDirectory - } - -} diff --git a/Sources/Ignite/Publishing/PublishingContext-ResourceLoading.swift b/Sources/Ignite/Publishing/PublishingContext-ResourceLoading.swift index 0a2052c..59c50e6 100644 --- a/Sources/Ignite/Publishing/PublishingContext-ResourceLoading.swift +++ b/Sources/Ignite/Publishing/PublishingContext-ResourceLoading.swift @@ -12,7 +12,7 @@ extension PublishingContext { /// - Parameter resource: The file to look for, e.g. "quotes.json" /// - Returns: The URL, if the file can be found. public func url(forResource resource: String) -> URL? { - let fullURL = rootDirectory.appending(path: "Resources/\(resource)") + let fullURL = sourceDirectory.appending(path: "Resources/\(resource)") if FileManager.default.fileExists(atPath: fullURL.path()) { return fullURL diff --git a/Sources/Ignite/Publishing/PublishingContext.swift b/Sources/Ignite/Publishing/PublishingContext.swift index a1e2010..a03cb2a 100644 --- a/Sources/Ignite/Publishing/PublishingContext.swift +++ b/Sources/Ignite/Publishing/PublishingContext.swift @@ -15,7 +15,7 @@ public class PublishingContext { public var site: any Site /// The root directory for the user's website package. - var rootDirectory: URL + var sourceDirectory: URL /// The directory containing their custom assets. var assetsDirectory: URL @@ -45,25 +45,6 @@ public class PublishingContext { /// control!) private(set) var siteMap = [Location]() - /// Creates a new publishing context for a specific site, setting a root URL. - /// - Parameters: - /// - site: The site we're currently publishing. - /// - rootURL: The URL of the root directory, where other key - /// folders are located. - /// - buildDirectoryPath: The path where the artifacts are generated. - /// The default is "Build". - init(for site: any Site, rootURL: URL, buildDirectoryPath: String = "Build") throws { - self.site = site - - self.rootDirectory = rootURL - assetsDirectory = rootDirectory.appending(path: "Assets") - contentDirectory = rootDirectory.appending(path: "Content") - includesDirectory = rootDirectory.appending(path: "Includes") - buildDirectory = rootDirectory.appending(path: buildDirectoryPath) - - try parseContent() - } - /// Creates a new publishing context for a specific site, providing the path to /// one of the user's file. This then navigates upwards to find the root directory. /// - Parameters: @@ -74,11 +55,13 @@ public class PublishingContext { init(for site: any Site, from file: StaticString, buildDirectoryPath: String = "Build") throws { self.site = site - rootDirectory = try URL.selectSiteRootDirectory(from: file) - assetsDirectory = rootDirectory.appending(path: "Assets") - contentDirectory = rootDirectory.appending(path: "Content") - includesDirectory = rootDirectory.appending(path: "Includes") - buildDirectory = rootDirectory.appending(path: buildDirectoryPath) + let sourceBuildDirectories = try URL.selectDirectories(from: file) + sourceDirectory = sourceBuildDirectories.source + buildDirectory = sourceBuildDirectories.build.appending(path: buildDirectoryPath) + + assetsDirectory = sourceDirectory.appending(path: "Assets") + contentDirectory = sourceDirectory.appending(path: "Content") + includesDirectory = sourceDirectory.appending(path: "Includes") try parseContent() } @@ -179,16 +162,21 @@ public class PublishingContext { /// and CSS, icons CSS and fonts if enabled, and syntax highlighters /// if enabled. func copyResources() throws { - let assets = try FileManager.default.contentsOfDirectory( - at: assetsDirectory, - includingPropertiesForKeys: nil - ) - - for asset in assets { - try FileManager.default.copyItem( - at: assetsDirectory.appending(path: asset.lastPathComponent), - to: buildDirectory.appending(path: asset.lastPathComponent) + do { + let assets = try FileManager.default.contentsOfDirectory( + at: assetsDirectory, + includingPropertiesForKeys: nil ) + + for asset in assets { + try FileManager.default.copyItem( + at: assetsDirectory.appending(path: asset.lastPathComponent), + to: buildDirectory.appending(path: asset.lastPathComponent) + ) + } + } catch { + print("Could not copy assets from \(assetsDirectory) to \(buildDirectory): \(error).") + throw error } if site.useDefaultBootstrapURLs == .localBootstrap { diff --git a/Tests/IgniteTests/TestSite.swift b/Tests/IgniteTests/TestSite.swift index d32abb5..4b97e8b 100644 --- a/Tests/IgniteTests/TestSite.swift +++ b/Tests/IgniteTests/TestSite.swift @@ -12,7 +12,7 @@ import Ignite struct TestSite: Site { var name = "My Test Site" var titleSuffix = " - My Test Site" - var url = URL("https://www.yoursite.com") + var url: URL = URL("https://www.yoursite.com") var builtInIconsEnabled: BootstrapOptions = .localBootstrap var syntaxHighlighters = [SyntaxHighlighter.objectiveC] diff --git a/Tests/IgniteTests/TestSubsite.swift b/Tests/IgniteTests/TestSubsite.swift index cfd679c..ad77e5e 100644 --- a/Tests/IgniteTests/TestSubsite.swift +++ b/Tests/IgniteTests/TestSubsite.swift @@ -12,7 +12,7 @@ import Ignite struct TestSubsite: Site { var name = "My Test Subsite" var titleSuffix = " - My Test Subsite" - var url = URL("https://www.yoursite.com/subsite") + var url: URL = URL("https://www.yoursite.com/subsite") var builtInIconsEnabled: BootstrapOptions = .localBootstrap var syntaxHighlighters = [SyntaxHighlighter.objectiveC]