Skip to content

Commit

Permalink
Merge pull request #14 from jjotaum/release/0.4
Browse files Browse the repository at this point in the history
Release 0.4

- Bump swift-tool-version to 5.5, package & project main structure clean up.
- Refactor chroma arguments to receive asset path and exported file path to make it work on a more standard and less risky way.
- Clean up on unit tests setup.
- Update swift-argument-parser version to 1.1.2.
- Update folder file creation method to throw an error instead of causing a fatal error.
- Update Chroma description on Readme file.
  • Loading branch information
jjotaum authored Jun 16, 2022
2 parents 0cd2919 + 5c2d9d6 commit 916b025
Show file tree
Hide file tree
Showing 16 changed files with 195 additions and 92 deletions.
19 changes: 5 additions & 14 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.3
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand All @@ -9,31 +9,22 @@ let package = Package(
.macOS(.v10_15)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.executable(name: "Chroma", targets: ["Chroma"]),
.library(name: "ChromaLibrary", targets: ["ChromaLibrary"])
.executable(name: "Chroma", targets: ["Chroma"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/apple/swift-argument-parser", .exact("0.1.0")),
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
.package(url: "https://github.com/JohnSundell/Files", from: "4.1.1")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
.executableTarget(
name: "Chroma",
dependencies: ["ChromaLibrary"]),
.target(
name: "ChromaLibrary",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "Files", package: "Files")
]),
.testTarget(
name: "ChromaTests",
dependencies: ["ChromaLibrary"],
dependencies: ["Chroma"],
resources: [.copy("Resources")]),
]
)
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# Chroma

A command line tool to generate swift colors definitions from .xcassets files.
A command line tool to auto generate .swift extensions or structs files from .xcassets on your iOS, macOS & SwiftUI projects.

### Usage

```
$ Chroma --help
USAGE: chroma [--name <name>] [--output <output>] [--platform <platform>]
USAGE: chroma --asset <asset> --path <path> [--type <type>] [--platform <platform>]
OPTIONS:
-n, --name <name> Defines the name of the generated file. (default:
Colors)
-o, --output <output> Specifies generated file type.
-a, --asset <asset> The path of .xcasset file.
-p, --path <path> The path of the generated .swift file.
-t, --type <type> Specifies generated file type.
Supported values: "extension","struct". (default:
extension)
-p, --platform <platform>
Specifies the platform compatibility of the exported
--platform <platform> Specifies the platform compatibility of the exported
file.
iOS, macOS, swiftUI (default: iOS)
-h, --help Show help information.
```

### Installation
Expand Down
72 changes: 72 additions & 0 deletions Sources/Chroma/App/Chroma.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//
// Chroma.swift
// Chroma
//
// Created by Jota Uribe on 7/06/20.
// Copyright © 2020 Jota Uribe. All rights reserved.
//

import ArgumentParser
import Files
import Foundation

public struct Chroma: ParsableCommand {
@Option(name: .shortAndLong, help: "The path of .xcasset file.")
private var asset: String

@Option(name: .shortAndLong, help: "The path of the generated .swift file.")
private var path: String

@Option(name: .shortAndLong, help: OutputType.help)
private var type: OutputType = .extension

@Option(name: .long, help: "Specifies the platform compatibility of the exported file.\niOS, macOS, swiftUI")
private var platform: Platform = .iOS

public init() {}

public func run() throws {
try generate()
}

}

extension Chroma {

private func generate() throws {
let outputFile = try outputFile()
let content = try getContentFromAssetsFile(outputFile: outputFile)
try outputFile.write(content)
print(
"""
\(outputFile.name) was generated successfully.
Can be found at \(outputFile.path)
"""
)
}

private func outputFile() throws -> File {
guard let pathURL = URL(string: path), !pathURL.hasDirectoryPath, pathURL.pathExtension == "swift" else {
throw ChromaError.invalidPath(path: path)
}


let folder = try Folder(path: pathURL.deletingLastPathComponent().path)
return try File(named: pathURL.lastPathComponent, at: folder)
}

private func getContentFromAssetsFile(outputFile: File) throws -> String {
let folder = try Folder(path: asset)
let body = folder.colorDefinitions(for: platform).sorted().joined(separator: "\n")
return platform.fileContent(header: header(file: outputFile), body: body)
}

private func header(file: File) -> String {
switch type {
case .extension:
return "\(type.rawValue) \(platform.variableType)"
case .struct:
return "\(type.rawValue) \(file.nameExcludingExtension)"
}
}
}
27 changes: 27 additions & 0 deletions Sources/Chroma/App/ChromaError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// ChromaError.swift
// Chroma
//
// Created by Jota Uribe on 9/06/22.
//

import Foundation

enum ChromaError: LocalizedError {
case fileCreationFailed(path: String)
case fileCreationFailedAtFolder(path: String, fileName: String)
case invalidPath(path: String)
}

extension ChromaError {
var errorDescription: String? {
switch self {
case .fileCreationFailed(let path):
return "Could not create file at \(path)"
case .fileCreationFailedAtFolder(let path, let fileName):
return "Could not create file '\(fileName)' at \(path)"
case .invalidPath(let path):
return "Invalid path: \(path)"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ import Foundation
import ArgumentParser

enum OutputType: String, CaseIterable, ExpressibleByArgument {

case `extension`
case `struct`

}

extension OutputType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ import Foundation
import ArgumentParser

enum Platform: String, ExpressibleByArgument {

case iOS
case macOS
case swiftUI

}

extension Platform {
Expand All @@ -37,7 +35,6 @@ extension Platform {

func colorVariable(name: String) -> String {
let formattedName = name.camelCased().removing(.punctuationCharacters.union(.symbols))
print(formattedName)
switch self {
case .iOS, .macOS:
return " static var \(formattedName): \(variableType) { return \(variableType)(named: \"\(name)\")! }"
Expand All @@ -64,5 +61,4 @@ extension Platform {
}
"""
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import Files

extension File {

init(named name: String, at folder: Folder) {
guard let file = try? folder.createFileIfNeeded(at: "\(name).swift") else {
fatalError("Error: Could not create file \(name).swift.")
init(named name: String, at folder: Folder) throws {
guard let file = try? folder.createFileIfNeeded(at: name) else {
throw ChromaError.fileCreationFailedAtFolder(path: folder.path, fileName: name)
}
self = file
}
Expand Down
File renamed without changes.
1 change: 0 additions & 1 deletion Sources/Chroma/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// Copyright © 2020 Jota Uribe. All rights reserved.
//

import ChromaLibrary
import Foundation

Chroma.main()
59 changes: 0 additions & 59 deletions Sources/ChromaLibrary/Chroma.swift

This file was deleted.

38 changes: 38 additions & 0 deletions Tests/ChromaTests/ChromaErrorTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// ChromaErrorTests.swift
// Chroma
//
// Created by Jota Uribe on 9/06/22.
//

import XCTest
@testable import Chroma

final class ChromaErrorTests: XCTestCase {
let mockPath = "/path/file.ext"

func testFileCreationFailedDescription() throws {
let error = ChromaError.fileCreationFailed(path: mockPath)
let expectedDesc = "Could not create file at /path/file.ext"
XCTAssertEqual(error.localizedDescription, expectedDesc)
}

func testFileCreationFailedAtFolder() throws {
let error = ChromaError.fileCreationFailedAtFolder(path: "/path", fileName: "file.ext")
let expectedDesc = "Could not create file 'file.ext' at /path"
XCTAssertEqual(error.localizedDescription, expectedDesc)
}

func testInvalidPathDescription() throws {
let error = ChromaError.invalidPath(path: mockPath)
let expectedDesc = "Invalid path: /path/file.ext"
XCTAssertEqual(error.localizedDescription, expectedDesc)
}


static var allTests = [
("testFileCreationFailedDescription", testFileCreationFailedDescription),
("testFileCreationFailedAtFolder", testFileCreationFailedAtFolder),
("testInvalidPathDescription", testInvalidPathDescription)
]
}
25 changes: 25 additions & 0 deletions Tests/ChromaTests/FileTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// FileTests.swift
// Chroma
//
// Created by Jota Uribe on 9/06/22.
//

import XCTest
import Files
@testable import Chroma

final class FileTests: XCTestCase {

func testNamedAtInitWithOutExtension() throws {
let path = Bundle.module.bundlePath
let folder = try Folder(path: path)
let fileName = "File"
let file = try File(named: fileName, at: folder)
XCTAssertEqual(file.path, "\(path)/\(fileName)")
}

static var allTests = [
("testNamedAtInitWithOutExtension", testNamedAtInitWithOutExtension)
]
}
9 changes: 8 additions & 1 deletion Tests/ChromaTests/FolderTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
//
// FileTests.swift
// Chroma
//
// Created by Jota Uribe on 9/06/22.
//

import XCTest
import Files
@testable import ChromaLibrary
@testable import Chroma

final class FolderTests: XCTestCase {
func testColorDefinitionsForiOS() throws {
Expand Down
9 changes: 8 additions & 1 deletion Tests/ChromaTests/PlatformTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
//
// FileTests.swift
// Chroma
//
// Created by Jota Uribe on 9/06/22.
//

import XCTest
import Files
@testable import ChromaLibrary
@testable import Chroma

final class PlatformTests: XCTestCase {
func testColorVariableForiOS() throws {
Expand Down
2 changes: 2 additions & 0 deletions Tests/ChromaTests/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import XCTest
#if !canImport(ObjectiveC)
public func allTests() -> [XCTestCaseEntry] {
return [
testCase(ChromaErrorTests.allTests),
testCase(FileTests.allTests),
testCase(FolderTests.allTests),
testCase(PlatformTests.allTests)
]
Expand Down

0 comments on commit 916b025

Please sign in to comment.