diff --git a/Sources/CLI/Commands+Generate.swift b/Sources/CLI/Commands+Generate.swift index 821a59a..9cfffdb 100644 --- a/Sources/CLI/Commands+Generate.swift +++ b/Sources/CLI/Commands+Generate.swift @@ -18,22 +18,25 @@ struct Generate: ParsableCommand { commandName: "generate", abstract: "Generate text style and colors definitions from a set of templates and store the resulting output to the provided paths" ) - + @Option(name: .shortAndLong, help: "Zeplin Project ID to generate text styles and colors from. Overrides any config files.") var projectId: Project.ID? @Option(name: .shortAndLong, help: "Zeplin Styleguide ID to generate text styles and colors from. Overrides any config files.") var styleguideId: Styleguide.ID? - + @Option(name: .shortAndLong, help: "Path to a folder containing *.prism template files. Overrides any config files.") var templatesPath: String? - + @Option(name: .shortAndLong, help: "Path to save generated files to. Overrides any config files.") var outputPath: String? - + @Option(name: .shortAndLong, help: "Path to YAML configuration file") var configFile: String? - + + @Option(name: .shortAndLong, help: "Zeplin Styleguide IDs to be ignored, comma separated (e.g. a parent styleguide)") + var ignoredStyleGuides: String? + func run() throws { let prismFolder = ".prism" var configPath = configFile @@ -56,7 +59,7 @@ struct Generate: ParsableCommand { } let decoder = YAMLDecoder() - + do { config = try decoder.decode(Configuration.self, from: configString) } catch { @@ -86,7 +89,7 @@ struct Generate: ParsableCommand { let rawTemplatesPath = templatesPath ?? config?.templatesPath ?? prismFolder let templatesPath = rawTemplatesPath == "/" ? String(rawTemplatesPath.dropLast()) : rawTemplatesPath - + guard let rawOutputPath = outputPath ?? config?.outputPath else { throw CommandError.outputFolderMissing } @@ -94,15 +97,15 @@ struct Generate: ParsableCommand { let fileManager = FileManager.default let outputPath = (rawOutputPath.last == "/" ? String(rawOutputPath.dropLast()) : rawOutputPath) .replacingOccurrences(of: "~", with: fileManager.homeDirectoryForCurrentUser.path) - + guard fileManager.folderExists(at: outputPath) else { throw CommandError.outputFolderDoesntExist(path: outputPath) } - - prism.getAssets(for: owner) { result in + + prism.getAssets(for: owner, ignoredStyleGuides: config?.ignoredStyleGuides ?? ignoredStyleGuides?.components(separatedBy: ",") ?? []) { result in do { let project = try result.get() - + let enumerator = fileManager.enumerator(atPath: templatesPath) var isFolder: ObjCBool = false diff --git a/Sources/PrismCore/Models/Configuration.swift b/Sources/PrismCore/Models/Configuration.swift index 6256e34..f255796 100644 --- a/Sources/PrismCore/Models/Configuration.swift +++ b/Sources/PrismCore/Models/Configuration.swift @@ -26,6 +26,9 @@ public struct Configuration { /// A list of reserved text style identities that cannot be used. public let reservedTextStyles: [String] + + /// A list of ignored Style Guide IDs, that will not be fetched. + public let ignoredStyleGuides: [String] } extension Configuration: Codable { @@ -37,6 +40,7 @@ extension Configuration: Codable { self.outputPath = try? container.decode(String.self, forKey: .outputPath) self.reservedColors = (try? container.decode([String].self, forKey: .reservedColors)) ?? [] self.reservedTextStyles = (try? container.decode([String].self, forKey: .reservedTextStyles)) ?? [] + self.ignoredStyleGuides = (try? container.decode([String].self, forKey: .ignoredStyleGuides)) ?? [] } enum CodingKeys: String, CodingKey { @@ -46,5 +50,6 @@ extension Configuration: Codable { case outputPath = "output_path" case reservedColors = "reserved_colors" case reservedTextStyles = "reserved_textstyles" + case ignoredStyleGuides = "ignored_styleguides" } } diff --git a/Sources/PrismCore/Prism.swift b/Sources/PrismCore/Prism.swift index f152d3f..8c9445d 100644 --- a/Sources/PrismCore/Prism.swift +++ b/Sources/PrismCore/Prism.swift @@ -34,9 +34,11 @@ public class Prism { /// e.g. for a Project with 2 linked styleguides, Prism performs 7 API calls /// /// - parameter owner: Assets owner, e.g. a project or styleguide + /// - parameter ignoredStyleGuides: Additional style guide id's which should be ignored /// - parameter completion: A completion handler which can result in a successful `Assets` /// object, or a `ZeplinAPI.Error` error public func getAssets(for owner: AssetOwner, + ignoredStyleGuides: [String] = [], completion: @escaping (Result) -> Void) { let group = DispatchGroup() var colors = [Color]() @@ -49,12 +51,15 @@ public class Prism { }() // Wait for styleguide IDs we wish to query - let (styleguideIDs, styleguideErrors) = getStyleguideIDs(for: owner) + let (allStyleguideIds, styleguideErrors) = getStyleguideIDs(for: owner) errors.append(contentsOf: styleguideErrors) // Get text styles, colors and spacing separately // for each styleguide + + let styleguideIDs = allStyleguideIds.filter { id in !ignoredStyleGuides.contains(id) } + for styleguideID in styleguideIDs { group.enter() api.getPagedItems( diff --git a/Tests/ConfigurationSpec.swift b/Tests/ConfigurationSpec.swift index 08f2e04..12dff2c 100644 --- a/Tests/ConfigurationSpec.swift +++ b/Tests/ConfigurationSpec.swift @@ -41,12 +41,16 @@ class ConfigurationSpec: QuickSpec { reserved_textstyles: - fake3 - fake4 + ignored_styleguides: + - fake5 + - fake6 """ let config = try! decoder.decode(PrismCore.Configuration.self, from: yaml) - + expect(config.reservedColors) == ["fake1", "fake2"] expect(config.reservedTextStyles) == ["fake3", "fake4"] + expect(config.ignoredStyleGuides) == ["fake5", "fake6"] } } } diff --git a/Tests/TemplateParserSpec.swift b/Tests/TemplateParserSpec.swift index 20e820a..c57fb44 100644 --- a/Tests/TemplateParserSpec.swift +++ b/Tests/TemplateParserSpec.swift @@ -489,7 +489,8 @@ class TemplateParserSpec: QuickSpec { templatesPath: "./", outputPath: "./", reservedColors: ["blueSky", "clearReddish"], - reservedTextStyles: ["body", "largeHeading"]) + reservedTextStyles: ["body", "largeHeading"], + ignoredStyleGuides: []) let parser = TemplateParser(project: project, configuration: configuration) expect { try parser.parse(template: "") } @@ -504,7 +505,8 @@ class TemplateParserSpec: QuickSpec { templatesPath: "./", outputPath: "./", reservedColors: ["blue_sky", "clear_reddish"], - reservedTextStyles: ["body", "large_heading"]) + reservedTextStyles: ["body", "large_heading"], + ignoredStyleGuides: []) let parser = TemplateParser(project: project, configuration: configuration) expect { try parser.parse(template: "") }