mirror of
https://github.com/krzysztofzablocki/Sourcery.git
synced 2026-04-07 19:17:40 +00:00
Cache base path configurable via yaml file (#612)
* chore: .bundle/config updated by bundler * feat: configurable cacheBasePath via YAML file * chore: updated generated files * chore: update CHANGELOG.md
This commit is contained in:
committed by
Krzysztof Zabłocki
parent
fc767e0f7f
commit
31c6a17e54
@@ -1,3 +1,4 @@
|
||||
---
|
||||
BUNDLE_DISABLE_SHARED_GEMS: "true"
|
||||
BUNDLE_PATH: "Vendor/bundle"
|
||||
BUNDLE_WITHOUT: "test:development"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
### New Features
|
||||
|
||||
- Added support for enums in AutoCodable template
|
||||
- You can now specify the base path for the Sourcery cache directory with a `cacheBasePath` key in the yaml
|
||||
|
||||
## 0.13.0
|
||||
|
||||
|
||||
@@ -179,6 +179,7 @@ struct Configuration {
|
||||
case invalidSources(message: String)
|
||||
case invalidTemplates(message: String)
|
||||
case invalidOutput(message: String)
|
||||
case invalidCacheBasePath(message: String)
|
||||
case invalidPaths(message: String)
|
||||
|
||||
var description: String {
|
||||
@@ -191,6 +192,8 @@ struct Configuration {
|
||||
return "Invalid templates. \(message)"
|
||||
case .invalidOutput(let message):
|
||||
return "Invalid output. \(message)"
|
||||
case .invalidCacheBasePath(let message):
|
||||
return "Invalid cacheBasePath. \(message)"
|
||||
case .invalidPaths(let message):
|
||||
return "\(message)"
|
||||
}
|
||||
@@ -200,6 +203,7 @@ struct Configuration {
|
||||
let source: Source
|
||||
let templates: Paths
|
||||
let output: Output
|
||||
let cacheBasePath: Path
|
||||
let forceParse: [String]
|
||||
let args: [String: NSObject]
|
||||
|
||||
@@ -242,13 +246,22 @@ struct Configuration {
|
||||
throw Configuration.Error.invalidOutput(message: "'output' key is missing or is not a string or object.")
|
||||
}
|
||||
|
||||
if let cacheBasePath = dict["cacheBasePath"] as? String {
|
||||
self.cacheBasePath = Path(cacheBasePath, relativeTo: relativePath)
|
||||
} else if dict["cacheBasePath"] != nil {
|
||||
throw Configuration.Error.invalidCacheBasePath(message: "'cacheBasePath' key is not a string.")
|
||||
} else {
|
||||
self.cacheBasePath = Path.defaultBaseCachePath
|
||||
}
|
||||
|
||||
self.args = dict["args"] as? [String: NSObject] ?? [:]
|
||||
}
|
||||
|
||||
init(sources: Paths, templates: Paths, output: Path, forceParse: [String], args: [String: NSObject]) {
|
||||
init(sources: Paths, templates: Paths, output: Path, cacheBasePath: Path, forceParse: [String], args: [String: NSObject]) {
|
||||
self.source = .sources(sources)
|
||||
self.templates = templates
|
||||
self.output = Output(output, linkTo: nil)
|
||||
self.cacheBasePath = cacheBasePath
|
||||
self.forceParse = forceParse
|
||||
self.args = args
|
||||
}
|
||||
|
||||
+22
-8
@@ -28,6 +28,7 @@ class Sourcery {
|
||||
fileprivate let watcherEnabled: Bool
|
||||
fileprivate let arguments: [String: NSObject]
|
||||
fileprivate let cacheDisabled: Bool
|
||||
fileprivate let cacheBasePath: Path?
|
||||
fileprivate let prune: Bool
|
||||
|
||||
fileprivate var status = ""
|
||||
@@ -38,11 +39,12 @@ class Sourcery {
|
||||
///
|
||||
/// - Parameter verbose: Whether to turn on verbose logs.
|
||||
/// - Parameter arguments: Additional arguments to pass to templates.
|
||||
init(verbose: Bool = false, watcherEnabled: Bool = false, cacheDisabled: Bool = false, prune: Bool = false, arguments: [String: NSObject] = [:]) {
|
||||
init(verbose: Bool = false, watcherEnabled: Bool = false, cacheDisabled: Bool = false, cacheBasePath: Path? = nil, prune: Bool = false, arguments: [String: NSObject] = [:]) {
|
||||
self.verbose = verbose
|
||||
self.arguments = arguments
|
||||
self.watcherEnabled = watcherEnabled
|
||||
self.cacheDisabled = cacheDisabled
|
||||
self.cacheBasePath = cacheBasePath
|
||||
self.prune = prune
|
||||
}
|
||||
|
||||
@@ -181,12 +183,24 @@ class Sourcery {
|
||||
return top.map { $0.0 }
|
||||
}
|
||||
|
||||
/// This function should be used to retrieve the path to the cache instead of `Path.cachesDir`,
|
||||
/// as it considers the `--cacheDisabled` and `--cacheBasePath` command line parameters.
|
||||
fileprivate func cachesDir(sourcePath: Path, createIfMissing: Bool = true) -> Path? {
|
||||
return cacheDisabled
|
||||
? nil
|
||||
: Path.cachesDir(sourcePath: sourcePath, basePath: cacheBasePath, createIfMissing: createIfMissing)
|
||||
}
|
||||
|
||||
/// Remove the existing cache artifacts if it exists.
|
||||
/// Currently this is only called from tests, and the `--cacheDisabled` and `--cacheBasePath` command line parameters are not considered.
|
||||
///
|
||||
/// - Parameter sources: paths of the sources you want to delete the
|
||||
static func removeCache(for sources: [Path]) {
|
||||
static func removeCache(for sources: [Path], cacheDisabled: Bool = false, cacheBasePath: Path? = nil) {
|
||||
if cacheDisabled {
|
||||
return
|
||||
}
|
||||
sources.forEach { path in
|
||||
let cacheDir = Path.cachesDir(sourcePath: path, createIfMissing: false)
|
||||
let cacheDir = Path.cachesDir(sourcePath: path, basePath: cacheBasePath, createIfMissing: false)
|
||||
_ = try? cacheDir.delete()
|
||||
}
|
||||
}
|
||||
@@ -198,7 +212,7 @@ class Sourcery {
|
||||
Log.warning("Skipping template \($0). Swift templates are not supported when using Sourcery built with Swift Package Manager yet. Please use only Stencil or EJS templates. See https://github.com/krzysztofzablocki/Sourcery/issues/244 for details.")
|
||||
return nil
|
||||
#else
|
||||
let cachePath = cacheDisabled ? nil : Path.cachesDir(sourcePath: $0)
|
||||
let cachePath = cachesDir(sourcePath: $0)
|
||||
return try SwiftTemplate(path: $0, cachePath: cachePath)
|
||||
#endif
|
||||
} else if $0.extension == "ejs" {
|
||||
@@ -270,7 +284,7 @@ extension Sourcery {
|
||||
var accumulator = 0
|
||||
let step = sources.count / 10 // every 10%
|
||||
|
||||
let results = try sources.parallelMap({ try self.loadOrParse(parser: $0, cachesPath: Path.cachesDir(sourcePath: from)) }, progress: !(verbose || watcherEnabled) ? nil : { _ in
|
||||
let results = try sources.parallelMap({ try self.loadOrParse(parser: $0, cachesPath: cachesDir(sourcePath: from)) }, progress: !(verbose || watcherEnabled) ? nil : { _ in
|
||||
if accumulator > previousUpdate + step {
|
||||
previousUpdate = accumulator
|
||||
let percentage = accumulator * 100 / sources.count
|
||||
@@ -298,15 +312,15 @@ extension Sourcery {
|
||||
return (Types(types: types), inlineRanges)
|
||||
}
|
||||
|
||||
private func loadOrParse(parser: FileParser, cachesPath: @autoclosure () -> Path) throws -> FileParserResult {
|
||||
private func loadOrParse(parser: FileParser, cachesPath: @autoclosure () -> Path?) throws -> FileParserResult {
|
||||
guard let pathString = parser.path else { fatalError("Unable to retrieve \(String(describing: parser.path))") }
|
||||
|
||||
if cacheDisabled {
|
||||
guard let cachesPath = cachesPath() else {
|
||||
return try parser.parse()
|
||||
}
|
||||
|
||||
let path = Path(pathString)
|
||||
let artifacts = cachesPath() + "\(pathString.hash).srf"
|
||||
let artifacts = cachesPath + "\(pathString.hash).srf"
|
||||
|
||||
guard artifacts.exists,
|
||||
let contentSha = parser.initialContents.sha256(),
|
||||
|
||||
@@ -20,9 +20,19 @@ extension Path {
|
||||
return Path(tempDirURL.path)
|
||||
}
|
||||
|
||||
static func cachesDir(sourcePath: Path, createIfMissing: Bool = true) -> Path {
|
||||
var paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true) as [String]
|
||||
let path = Path(paths[0]) + "Sourcery" + sourcePath.lastComponent
|
||||
/// - returns: The `.cachesDirectory` search path in the user domain, as a `Path`.
|
||||
static var defaultBaseCachePath: Path {
|
||||
let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true) as [String]
|
||||
let path = paths[0]
|
||||
return Path(path)
|
||||
}
|
||||
|
||||
/// - parameter _basePath: The value of the `--cachePath` command line parameter, if any.
|
||||
/// - note: This function does not consider the `--disableCache` command line parameter.
|
||||
/// It is considered programmer error to call this function when `--disableCache` is specified.
|
||||
static func cachesDir(sourcePath: Path, basePath _basePath: Path?, createIfMissing: Bool = true) -> Path {
|
||||
let basePath = _basePath ?? defaultBaseCachePath
|
||||
let path = basePath + "Sourcery" + sourcePath.lastComponent
|
||||
if !path.exists && createIfMissing {
|
||||
// swiftlint:disable:next force_try
|
||||
try! FileManager.default.createDirectory(at: path.url, withIntermediateDirectories: true, attributes: nil)
|
||||
|
||||
@@ -118,6 +118,7 @@ func runCLI() {
|
||||
configuration = Configuration(sources: Paths(include: sources, exclude: excludeSources) ,
|
||||
templates: Paths(include: templates, exclude: excludeTemplates),
|
||||
output: output.string.isEmpty ? "." : output,
|
||||
cacheBasePath: Path.defaultBaseCachePath,
|
||||
forceParse: forceParse,
|
||||
args: arguments)
|
||||
} else {
|
||||
@@ -157,6 +158,7 @@ func runCLI() {
|
||||
let sourcery = Sourcery(verbose: verboseLogging,
|
||||
watcherEnabled: watcherEnabled,
|
||||
cacheDisabled: disableCache,
|
||||
cacheBasePath: configuration.cacheBasePath,
|
||||
prune: prune,
|
||||
arguments: configuration.args)
|
||||
if let keepAlive = try sourcery.processFiles(
|
||||
|
||||
@@ -109,6 +109,11 @@ class ConfigurationSpec: QuickSpec {
|
||||
expect(configError(config)).to(equal("Invalid output. 'output' key is missing or is not a string or object."))
|
||||
}
|
||||
|
||||
it("throws error on invalid cacheBasePath format") {
|
||||
let config: [String: Any] = ["sources": ["."], "templates": ["."], "output": ".", "cacheBasePath": ["."]]
|
||||
expect(configError(config)).to(equal("Invalid cacheBasePath. 'cacheBasePath' key is not a string."))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -162,6 +167,17 @@ class ConfigurationSpec: QuickSpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe("Cache Base Path") {
|
||||
context("provided with cacheBasePath") {
|
||||
it("has the correct cacheBasePath") {
|
||||
let config: [String: Any] = ["sources": ["."], "templates": ["."], "output": ".", "cacheBasePath": "test-base-path"]
|
||||
let cacheBasePath = try? Configuration(dict: config, relativePath: relativePath).cacheBasePath
|
||||
let expected = Path("test-base-path", relativeTo: relativePath)
|
||||
expect(cacheBasePath).to(equal(expected))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated using Sourcery 0.12.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 0.13.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated using Sourcery 0.12.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 0.13.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated using Sourcery 0.12.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 0.13.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
// swiftlint:disable file_length
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated using Sourcery 0.12.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 0.13.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
// swiftlint:disable file_length
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated using Sourcery 0.12.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 0.13.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
// swiftlint:disable variable_name
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated using Sourcery 0.12.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 0.13.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
// swiftlint:disable line_length
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated using Sourcery 0.12.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 0.13.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
import XCTest
|
||||
|
||||
Reference in New Issue
Block a user