Skip to content

Commit

Permalink
Implement the new arguments parser framework (#14)
Browse files Browse the repository at this point in the history
* Make use of the new argument parser

* Add configuration description

* Fix tests and add extra options for arguments

* Add verbose logging

* Updated the readme

* Fix Danger error for trailing comma
  • Loading branch information
AvdLee authored Mar 2, 2020
1 parent d19112f commit e20def8
Show file tree
Hide file tree
Showing 12 changed files with 1,531 additions and 1,878 deletions.
17 changes: 4 additions & 13 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,12 @@
"object": {
"pins": [
{
"package": "llbuild",
"repositoryURL": "https://github.com/apple/swift-llbuild.git",
"package": "swift-argument-parser",
"repositoryURL": "https://github.com/apple/swift-argument-parser",
"state": {
"branch": null,
"revision": "f73b84bc1525998e5e267f9d830c1411487ac65e",
"version": "0.2.0"
}
},
{
"package": "SwiftPM",
"repositoryURL": "https://github.com/apple/swift-package-manager.git",
"state": {
"branch": null,
"revision": "9abcc2260438177cecd7cf5185b144d13e74122b",
"version": "0.5.0"
"revision": "f6ac7b8118ff5d1bc0faee7f37bf6f8fd8f95602",
"version": "0.0.1"
}
}
]
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ let package = Package(
dependencies: [
// dev .package(url: "https://github.com/danger/swift", from: "3.0.0"),
// dev .package(path: "Submodules/WeTransfer-iOS-CI/Danger-Swift"),
.package(url: "https://github.com/apple/swift-package-manager.git", from: "0.1.0")
.package(url: "https://github.com/apple/swift-argument-parser", from: "0.0.1")
],
targets: [
// dev .testTarget(name: "PoesTests", dependencies: ["PoesCore"]),
// dev .target(name: "DangerDependencies", dependencies: ["Danger", "WeTransferPRLinter"], path: "Submodules/WeTransfer-iOS-CI/Danger-Swift", sources: ["DangerFakeSource.swift"]),
.target(name: "Poes", dependencies: ["PoesCore"]),
.target(name: "PoesCore", dependencies: ["SPMUtility"])
.target(name: "PoesCore", dependencies: ["ArgumentParser"])
]
)
3,172 changes: 1,419 additions & 1,753 deletions Poes.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions Poes.xcodeproj/xcshareddata/xcschemes/Poes-Package.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Poes::PoesCore"
BuildableName = "PoesCore.framework"
BlueprintName = "PoesCore"
BlueprintIdentifier = "Poes::Poes"
BuildableName = "Poes"
BlueprintName = "Poes"
ReferencedContainer = "container:Poes.xcodeproj">
</BuildableReference>
</BuildActionEntry>
Expand All @@ -28,9 +28,9 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Poes::Poes"
BuildableName = "Poes"
BlueprintName = "Poes"
BlueprintIdentifier = "Poes::PoesCore"
BuildableName = "PoesCore.framework"
BlueprintName = "PoesCore"
ReferencedContainer = "container:Poes.xcodeproj">
</BuildableReference>
</BuildActionEntry>
Expand Down
44 changes: 33 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,48 @@ Poes helps you with:
- Xcode 11.4 beta 1 and up

### Usage

```
$ poes --help
OVERVIEW: A Swift command-line tool to easily test push notifications to the
iOS simulator
USAGE: poes <subcommand>
OPTIONS:
-h, --help Show help information.
SUBCOMMANDS:
send Send a push notification to an app installed on the
iOS Simulator
```
$ Poes --help
OVERVIEW: A Swift command-line tool to easily send push notifications to the iOS simulator

USAGE: Poes <options>


```
$ poes send --help
OVERVIEW: Send a push notification to an app installed on the iOS Simulator
USAGE: poes send <bundle-identifier> [--title <title>] [--body <body>] [--badge <badge>] [--is-mutable] [--verbose]
ARGUMENTS:
<bundle-identifier> The bundle identifier of the app to push to
OPTIONS:
--body, -b The body of the Push Notification
--bundle-identifier The bundle identifier to push to
--mutable, -m Adds the mutable-content key to the payload
--title, -t The title of the Push Notification
--badge The number to display in a badge on your app’s icon
--verbose Show extra logging for debugging purposes
--help Display available options
-t, --title <title> The title of the Push notification (default: Default
Title)
-b, --body <body> The body of the Push notification (default: Default
Body)
-b, --badge <badge> The number to display in a badge on your app’s icon
-i, --is-mutable Adds the mutable-content key to the payload
--verbose Show extra logging for debugging purposes
-h, --help Show help information.
```

The bundle identifier is mandatory, all others have a default value. The following command can be enough to send out a notification:

```
$ Poes --bundle-identifier com.wetransfer.app --verbose
$ poes send com.wetransfer.app --verbose
Generated payload:
{
Expand Down
6 changes: 1 addition & 5 deletions Sources/Poes/main.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import PoesCore

do {
try Poes.run()
} catch {
print("Pushing failed: \(error)")
}
Poes.main()
33 changes: 0 additions & 33 deletions Sources/PoesCore/PayloadFactory.swift

This file was deleted.

56 changes: 6 additions & 50 deletions Sources/PoesCore/Poes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,56 +7,12 @@
//

import Foundation
import SPMUtility
import ArgumentParser

public struct Poes: ShellInjectable {
enum Error: Swift.Error, CustomStringConvertible {
case missingBundleIdentifier
public struct Poes: ParsableCommand {
public static let configuration = CommandConfiguration(
abstract: "A Swift command-line tool to easily test push notifications to the iOS simulator",
subcommands: [Send.self])

var description: String {
switch self {
case .missingBundleIdentifier:
return "Pass in the bundle identifier with the --bundle-identifier argument"
}
}
}

static var usage: String = "<options>"
static var overview: String = "A Swift command-line tool to easily send push notifications to the iOS simulator"

public static func run(arguments: [String] = ProcessInfo.processInfo.arguments) throws {
Log.isVerbose = arguments.contains("--verbose")
let parser = ArgumentParser(usage: usage, overview: overview)
_ = parser.add(option: "--verbose", kind: Bool.self, usage: "Show extra logging for debugging purposes")

let bundleIdentifierArgument = parser.add(option: "--bundle-identifier", kind: String.self, usage: "The bundle identifier to push to")
let payloadFactory = PayloadFactory(parser: parser)

let parsedArguments = try parser.process(arguments: arguments)

guard let bundleIdentifier = parsedArguments.get(bundleIdentifierArgument) else {
throw Error.missingBundleIdentifier
}

let payload = payloadFactory.make(using: parsedArguments)
let jsonData = try JSONEncoder().encode(payload)

if Log.isVerbose, let object = try? JSONSerialization.jsonObject(with: jsonData, options: []), let jsonString = String(data: try! JSONSerialization.data(withJSONObject: object, options: .prettyPrinted), encoding: .utf8) {
Log.debug("Generated payload:\n\n\(jsonString)\n")
}

let url = Foundation.URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent("payload.json")
FileManager.default.createFile(atPath: url.path, contents: jsonData, attributes: nil)

Log.message("Sending push notification...")
shell.execute(.push(bundleIdentifier: bundleIdentifier, payloadPath: url.path))
Log.message("Push notification sent successfully")
}
}

private extension ArgumentParser {
@discardableResult func process(arguments: [String]) throws -> ArgumentParser.Result {
// We drop the first argument as this is always the execution path. In our case: "gitbuddy"
return try parse(Array(arguments.dropFirst()))
}
public init() { }
}
51 changes: 51 additions & 0 deletions Sources/PoesCore/Send.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// Send.swift
// PoesCore
//
// Created by Antoine van der Lee on 08/02/2020.
// Copyright © 2020 AvdLee. All rights reserved.
//

import Foundation
import ArgumentParser

struct Send: ParsableCommand, ShellInjectable {

public static let configuration = CommandConfiguration(abstract: "Send a push notification to an app installed on the iOS Simulator")

@Argument(help: "The bundle identifier of the app to push to")
private var bundleIdentifier: String

@Option(name: .shortAndLong, default: "Default Title", help: "The title of the Push notification")
private var title: String

@Option(name: .shortAndLong, default: "Default Body", help: "The body of the Push notification")
private var body: String

@Option(name: .shortAndLong, help: "The number to display in a badge on your app’s icon")
private var badge: Int?

@Flag(name: .shortAndLong, help: "Adds the mutable-content key to the payload")
private var isMutable: Bool

@Flag(name: .long, help: "Show extra logging for debugging purposes")
private var verbose: Bool

func run() throws {
Log.isVerbose = verbose

let payload = Payload(title: title, body: body, isMutable: isMutable, badge: badge)
let jsonData = try JSONEncoder().encode(payload)

if Log.isVerbose, let object = try? JSONSerialization.jsonObject(with: jsonData, options: []), let jsonString = String(data: try! JSONSerialization.data(withJSONObject: object, options: .prettyPrinted), encoding: .utf8) {
Log.debug("Generated payload:\n\n\(jsonString)\n")
}

let url = Foundation.URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent("payload.json")
FileManager.default.createFile(atPath: url.path, contents: jsonData, attributes: nil)

Log.message("Sending push notification...")
Self.shell.execute(.push(bundleIdentifier: bundleIdentifier, payloadPath: url.path))
Log.message("Push notification sent successfully")
}
}
2 changes: 1 addition & 1 deletion Submodules/WeTransfer-iOS-CI
10 changes: 7 additions & 3 deletions Tests/PoesTests/PoesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ final class PoesTests: XCTestCase {
ShellInjector.shell = MockedShell.self
}

/// It should correctly generate a JSON payload.
func testPayloadGeneration() throws {
/// It should correctly generate a JSON payload for sending push notifications.
func testSendCommand() throws {
let expectedBundleIdentifier = "com.example.app"
let title = "Notification title"
let body = "Notification body"
let badge = 2
let isMutable = true
try Poes.run(arguments: ["poes", "--bundle-identifier", expectedBundleIdentifier, "-t", title, "-b", body, "-m", "--badge", "\(badge)"])

let arguments = ["send", expectedBundleIdentifier, "--title", title, "--body", body, "--badge", "\(badge)", "--is-mutable"]

let poesCommand = try Poes.parseAsRoot(arguments)
try poesCommand.run()

let command = try XCTUnwrap(MockedShell.executedCommand)

Expand Down

0 comments on commit e20def8

Please sign in to comment.