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:
Jim Roepcke
2018-05-07 02:27:12 -07:00
committed by Krzysztof Zabłocki
parent fc767e0f7f
commit 31c6a17e54
14 changed files with 76 additions and 19 deletions
+1
View File
@@ -1,3 +1,4 @@
---
BUNDLE_DISABLE_SHARED_GEMS: "true"
BUNDLE_PATH: "Vendor/bundle"
BUNDLE_WITHOUT: "test:development"
+1
View File
@@ -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
+14 -1
View File
@@ -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
View File
@@ -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(),
+13 -3
View File
@@ -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)
+2
View File
@@ -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(
+16
View File
@@ -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