Skip to content

Commit

Permalink
Using temporary directory as a working directory
Browse files Browse the repository at this point in the history
  • Loading branch information
viaszkadi committed Nov 20, 2024
1 parent 998fad6 commit 28a562b
Showing 1 changed file with 125 additions and 101 deletions.
226 changes: 125 additions & 101 deletions Sources/ToucanSDK/Toucan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@ public struct Toucan {
baseUrl: String?,
logger: Logger = .init(label: "toucan")
) {
let home = FileManager.default.homeDirectoryForCurrentUser.path
self.fileManager = FileManager.default

let home = fileManager.homeDirectoryForCurrentUser.path

func getSafeUrl(_ path: String, home: String) -> URL {
.init(
fileURLWithPath: path.replacingOccurrences(["~": home])
)
.standardized
}

self.inputUrl = getSafeUrl(input, home: home)
self.outputUrl = getSafeUrl(output, home: home)
self.baseUrl = baseUrl
Expand All @@ -45,118 +49,138 @@ public struct Toucan {

// MARK: - file management

let fileManager = FileManager.default
let fileManager: FileManager

// MARK: - directory management

func resetOutputDirectory() throws {
if fileManager.exists(at: outputUrl) {
try fileManager.delete(at: outputUrl)
func resetDirectory(at url: URL) throws {
if fileManager.exists(at: url) {
try fileManager.delete(at: url)
}
try fileManager.createDirectory(at: outputUrl)
try fileManager.createDirectory(at: url)
}

/// generates the static site
public func generate() throws {
let loader = SourceLoader(
baseUrl: baseUrl,
sourceUrl: inputUrl,
yamlFileLoader: .yaml,
fileManager: fileManager,
frontMatterParser: .init(),
logger: logger
)
let source = try loader.load()
source.validate(dateFormatter: DateFormatters.baseFormatter)

// TODO: output url is completely wiped, check if it's safe to delete everything
try resetOutputDirectory()

// theme assets
try fileManager.copyRecursively(
from: source.sourceConfig.currentThemeAssetsUrl,
to: outputUrl
)
// theme override assets
try fileManager.copyRecursively(
from: source.sourceConfig.currentThemeOverrideAssetsUrl,
to: outputUrl
)
// copy global site assets
try fileManager.copyRecursively(
from: source.sourceConfig.assetsUrl,
to: outputUrl
)

// MARK: copy assets

for pageBundle in source.pageBundles {
let assetsUrl = pageBundle.url
.appendingPathComponent(pageBundle.config.assets.folder)

guard
fileManager.directoryExists(at: assetsUrl),
!fileManager.listDirectory(at: assetsUrl).isEmpty
else {
continue
let processId = UUID()
let workDirUrl = fileManager
.temporaryDirectory
.appendingPathComponent("toucan")
.appendingPathComponent(processId.uuidString)

try resetDirectory(at: workDirUrl)

logger.debug("Working at: `\(workDirUrl.absoluteString)`.")

do {
let loader = SourceLoader(
baseUrl: baseUrl,
sourceUrl: inputUrl,
yamlFileLoader: .yaml,
fileManager: fileManager,
frontMatterParser: .init(),
logger: logger
)
let source = try loader.load()
source.validate(dateFormatter: DateFormatters.baseFormatter)

// theme assets
try fileManager.copyRecursively(
from: source.sourceConfig.currentThemeAssetsUrl,
to: workDirUrl
)
// theme override assets
try fileManager.copyRecursively(
from: source.sourceConfig.currentThemeOverrideAssetsUrl,
to: workDirUrl
)
// copy global site assets
try fileManager.copyRecursively(
from: source.sourceConfig.assetsUrl,
to: workDirUrl
)

// MARK: copy assets

for pageBundle in source.pageBundles {
let assetsUrl = pageBundle.url
.appendingPathComponent(pageBundle.config.assets.folder)

guard
fileManager.directoryExists(at: assetsUrl),
!fileManager.listDirectory(at: assetsUrl).isEmpty
else {
continue
}

let workDirUrl =
workDirUrl
.appendingPathComponent(pageBundle.config.assets.folder)
.appendingPathComponent(pageBundle.assetsLocation)

try fileManager.copyRecursively(
from: assetsUrl,
to: workDirUrl
)
}

let outputUrl =
outputUrl
.appendingPathComponent(pageBundle.config.assets.folder)
.appendingPathComponent(pageBundle.assetsLocation)
let templateRenderer = try MustacheToHTMLRenderer(
templatesUrl: source.sourceConfig.currentThemeTemplatesUrl,
overridesUrl: source
.sourceConfig
.currentThemeOverrideTemplatesUrl,
logger: logger
)

try fileManager.copyRecursively(
from: assetsUrl,
to: outputUrl
let redirectRenderer = RedirectRenderer(
destinationUrl: workDirUrl,
fileManager: .default,
templateRenderer: templateRenderer,
pageBundles: source.pageBundles
)
}
try redirectRenderer.render()

let sitemapRenderer = SitemapRenderer(
destinationUrl: workDirUrl,
fileManager: .default,
templateRenderer: templateRenderer,
pageBundles: source.sitemapPageBundles()
)
try sitemapRenderer.render()

let rssRenderer = RSSRenderer(
site: source.sourceConfig.site,
destinationUrl: workDirUrl,
fileManager: .default,
templateRenderer: templateRenderer,
pageBundles: source.rssPageBundles()
)
try rssRenderer.render()

let templateRenderer = try MustacheToHTMLRenderer(
templatesUrl: source.sourceConfig.currentThemeTemplatesUrl,
overridesUrl: source.sourceConfig.currentThemeOverrideTemplatesUrl,
logger: logger
)

let redirectRenderer = RedirectRenderer(
destinationUrl: outputUrl,
fileManager: .default,
templateRenderer: templateRenderer,
pageBundles: source.pageBundles
)
try redirectRenderer.render()

let sitemapRenderer = SitemapRenderer(
destinationUrl: outputUrl,
fileManager: .default,
templateRenderer: templateRenderer,
pageBundles: source.sitemapPageBundles()
)
try sitemapRenderer.render()

let rssRenderer = RSSRenderer(
site: source.sourceConfig.site,
destinationUrl: outputUrl,
fileManager: .default,
templateRenderer: templateRenderer,
pageBundles: source.rssPageBundles()
)
try rssRenderer.render()

let htmlRenderer = try HTMLRenderer(
source: source,
destinationUrl: outputUrl,
templateRenderer: templateRenderer,
logger: logger
)

try htmlRenderer.render()

let apiRenderer = try APIRenderer(
source: source,
destinationUrl: outputUrl,
logger: logger
)
try apiRenderer.render()
let htmlRenderer = try HTMLRenderer(
source: source,
destinationUrl: workDirUrl,
templateRenderer: templateRenderer,
logger: logger
)

try htmlRenderer.render()

let apiRenderer = try APIRenderer(
source: source,
destinationUrl: workDirUrl,
logger: logger
)
try apiRenderer.render()

try resetDirectory(at: outputUrl)
try fileManager.copyRecursively(from: workDirUrl, to: outputUrl)

try? fileManager.removeItem(at: workDirUrl)
}
catch {
try? fileManager.removeItem(at: workDirUrl)
throw error
}
}
}

0 comments on commit 28a562b

Please sign in to comment.