Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clean/rc argument parser #23

Merged
merged 29 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3bd789e
drafting arguments parser adoption
elfenlaid Jun 21, 2020
3af86b6
support named colors arguments cli
elfenlaid Jun 21, 2020
2f7ed29
streamline processing by stripping factory completions
elfenlaid Jun 21, 2020
7f7920e
support icon set in arguments parser
elfenlaid Jun 21, 2020
cc3c7aa
switch to iconset struct
elfenlaid Jun 21, 2020
176892d
fix path extension handling
elfenlaid Jun 21, 2020
a98ea71
extract commands' process to a pipeline
elfenlaid Jun 21, 2020
f2c87ed
shuffle cli model files to helpers directory
elfenlaid Jun 21, 2020
389470f
use pipeline in arguments CLI
elfenlaid Jun 21, 2020
511f4a6
hack around logger's verbose flag
elfenlaid Jun 21, 2020
d675b46
add compilation flag to swift on to arguments parser
elfenlaid Jun 21, 2020
c617498
add initial execution log
elfenlaid Jun 21, 2020
adc5a14
match logging with original cli
elfenlaid Jun 21, 2020
49fb264
tweak colors help section
elfenlaid Jun 21, 2020
27e0733
replace colors order misspell
elfenlaid Jun 22, 2020
9953f2b
tweak angle option flag comments
elfenlaid Jun 22, 2020
2a2345d
redo CLI position argument handling
elfenlaid Jun 22, 2020
75fec0c
trim a detailed explanation of hex regexp
elfenlaid Jun 22, 2020
b733332
by command position argument handling
elfenlaid Jun 22, 2020
8efb0a6
fix validation error misspell
elfenlaid Jun 22, 2020
cf0957d
cleaned up header comments
elfenlaid Jun 22, 2020
c89b0f1
Merge pull request #14 from elfenlaid/argument-parser
arthurpalves Jun 26, 2020
577b54a
drop SwiftCLI arguments handling
elfenlaid Jun 27, 2020
1b43752
explicitly specify default values for color arguments
elfenlaid Jun 27, 2020
22e6e36
close default bracket
elfenlaid Jun 27, 2020
916da00
Merge pull request #18 from elfenlaid/drop-swiftcli-arguments-handling
arthurpalves Jun 29, 2020
80a7411
Merge pull request #19 from elfenlaid/default-color-values
arthurpalves Jun 29, 2020
807bd37
merge: merge master back
arthurpalves Jul 14, 2020
f32222e
formatting: SwiftFormat adjustments
arthurpalves Jul 14, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
"version": "0.9.0"
}
},
{
"package": "swift-argument-parser",
"repositoryURL": "https://github.com/apple/swift-argument-parser",
"state": {
"branch": null,
"revision": "3d79b2b5a2e5af52c14e462044702ea7728f5770",
"version": "0.1.0"
}
},
{
"package": "SwiftCLI",
"repositoryURL": "https://github.com/jakeheis/SwiftCLI",
Expand Down
10 changes: 9 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ let package = Package(
from: "1.0.0"
),
.package(
url: "https://github.com/apple/swift-argument-parser",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Danger: This can cause Xcode to not even want to start building: https://stackoverflow.com/q/63079909/3939277

adding .git to the end of the URL will solve that, and also might fix the thing down below where you had to use .product

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, a nice catch :)
Converted into an issue #24

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to help 😁

from: "0.1.0"
),
.package(
url: "https://github.com/nicklockwood/SwiftFormat",
from: "0.44.17"
)
Expand All @@ -27,7 +31,11 @@ let package = Package(
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "Badgy",
dependencies: ["SwiftCLI", "PathKit"]),
dependencies: [
"SwiftCLI",
"PathKit",
.product(name: "ArgumentParser", package: "swift-argument-parser")
]),
.testTarget(
name: "BadgyTests",
dependencies: ["Badgy"]),
Expand Down
174 changes: 174 additions & 0 deletions Sources/Badgy/Commands/Badgy.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
//
// Badgy.swift
// Badgy
//
// MIT License
//
// Copyright (c) 2020 Arthur Alves
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import ArgumentParser
import Foundation
import PathKit

struct Badgy: ParsableCommand {
static var configuration = CommandConfiguration(
abstract: "A command-line tool to add labels to your app icon",
version: "0.1.4",
subcommands: [Long.self, Small.self],
defaultSubcommand: Long.self
)
}

extension Badgy {
struct Options: ParsableArguments {
@Argument(help: "Specify badge text")
var label: String

@Argument(help: "Specify path to icon with format .png | .jpg | .jpeg | .appiconset", transform: Icon.init(path:))
var icon: Icon

@Option(help: """
Specify a valid hex color code in a case insensitive format: '#rrggbb' | '#rrggbbaa'
or
Provide a named color: 'snow' | 'snow1' | ...
Complete list of named colors: https://imagemagick.org/script/color.php#color_names
(default: randomly selected from \(Factory.colors.joined(separator: " | ")))
""")
var color: ColorCode?

@Option(default: "white", help: """
Specify a valid hex color code in a case insensitive format: '#rrggbb' | '#rrggbbaa'
or
Provide a named color: 'snow' | 'snow1' | ...
Complete list of named colors: https://imagemagick.org/script/color.php#color_names
""")
var tintColor: ColorCode

@Flag(help: "Indicates Badgy should replace the input icon")
var replace: Bool

@Flag(help: "Log tech details for nerds")
var verbose: Bool

func validate() throws {
guard DependencyManager().areDependenciesInstalled() else {
throw ValidationError("Missing dependencies. Run: 'brew install imagemagick'")
}

Logger.shared.verbose = verbose
}
}
}

extension Badgy {
struct Long: ParsableCommand {
static var configuration = CommandConfiguration(
abstract: "Add rectangular label to app icon"
)

@OptionGroup()
var options: Badgy.Options

@Option(default: .bottom, help: "Position on which to place the badge. Supported positions: \(Position.longLabelPositions.formatted())")
var position: Position

@Option(default: 0, help: "The rotation angle of the badge in degrees range of -180 ... 180")
var angle: Int

func validate() throws {
guard options.label.count <= 4 else {
throw ValidationError("Label should contain maximum 4 characters")
}

guard position.isValidForLongLabels else {
throw ValidationError("Invalid provided position, supported positions are: \(Position.longLabelPositions.formatted())")
}

let validAngleRange = -180 ... 180
guard validAngleRange.contains(angle) else {
throw ValidationError("Angle should be within range: \(validAngleRange)")
}
}

func run() throws {
Logger.shared.logSection("$ ", item: "badgy long \"\(options.label)\" \"\(options.icon.path)\"", color: .ios)

var pipeline = IconSignPipeline.make(withOptions: options)
pipeline.position = position
pipeline.angle = angle

try pipeline.execute()
}
}
}

extension Badgy {
struct Small: ParsableCommand {
static var configuration = CommandConfiguration(
abstract: "Add small square label to app icon"
)

@OptionGroup()
var options: Badgy.Options

@Option(default: .bottomLeft, help: "Position on which to place the badge. Supported positions: \(Position.allCases.formatted())")
var position: Position

func validate() throws {
guard options.label.count <= 1 else {
throw ValidationError("Label should contain maximum 1 character")
}
}

func run() throws {
Logger.shared.logSection("$ ", item: "badgy small \"\(options.label)\" \"\(options.icon.path)\"", color: .ios)

var pipeline = IconSignPipeline.make(withOptions: options)
pipeline.position = position

try pipeline.execute()
}
}
}

extension Position: ExpressibleByArgument {}

private extension IconSignPipeline {
static func make(withOptions options: Badgy.Options) -> IconSignPipeline {
var pipeline = IconSignPipeline(icon: options.icon, label: options.label)

pipeline.color = options.color?.value
pipeline.tintColor = options.tintColor.value
pipeline.replace = options.replace

return pipeline
}
}

private extension Position {
static let longLabelPositions: Set<Position> = Set([
.top, .left, .bottom, .right, .center
])

var isValidForLongLabels: Bool {
Position.longLabelPositions.contains(self)
}
}
176 changes: 0 additions & 176 deletions Sources/Badgy/Commands/Long.swift

This file was deleted.

Loading