Skip to content

Commit

Permalink
lessons learned
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianKienle authored and Christian Kienle committed Oct 22, 2017
1 parent 9edbb93 commit 82823ad
Show file tree
Hide file tree
Showing 291 changed files with 8,522 additions and 2,264 deletions.
84 changes: 71 additions & 13 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,88 @@ import PackageDescription
let package = Package(
name: "highway",
products: [
// Used by highway projects, aggregates lots of dependencies and offers a nicer api
.library(name: "HighwayProject", targets: ["HighwayProject"]),
.library(name: "POSIX", targets: ["POSIX"]),
.library(name: "Deliver", targets: ["Deliver"]),
.library(name: "Arguments", targets: ["Arguments"]),
.library(name: "Errors", targets: ["Errors"]),
.library(name: "FileSystem", targets: ["FileSystem"]),
.library(name: "Url", targets: ["Url"]),
.library(name: "Result", targets: ["Result"]),
.library(name: "Task", targets: ["Task"]),
.library(name: "XCBuild", targets: ["XCBuild"]),
.library(name: "HighwayCore", targets: ["HighwayCore"]),
.library(name: "HWKit", targets: ["HWKit"]),
.library(name: "Keychain", targets: ["Keychain"]),
.library(name: "Terminal", targets: ["Terminal"]),
.library(name: "TestKit", targets: ["TestKit"]),
.library(name: "FSKit", targets: ["FSKit"]),
.library(name: "All",
type: .dynamic,
targets: ["HWKit", "HighwayCore", "highway", "Terminal", "TestKit", "FSKit"]
targets: [
"HighwayProject",
"POSIX",
"Deliver",
"Arguments",
"Errors",
"FileSystem",
"Url",
"Result",
"Task",
"XCBuild",
"HighwayCore",
"HWKit",
"Terminal",
"TestKit", "Keychain"]
)
],
dependencies: [],
targets: [
.target(name: "HWKit", dependencies: ["HighwayCore", "Terminal", "FSKit"]),
.target(name: "HighwayCore", dependencies: ["Terminal", "FSKit"]),
.target(name: "highway", dependencies: ["HWKit", "HighwayCore", "Terminal", "FSKit"]),
.target(name: "Terminal", dependencies: []),
.target(name: "TestKit", dependencies: ["HighwayCore"]),
.target(name: "FSKit", dependencies: []),
.target(name: "HighwayProject", dependencies: ["POSIX", "Deliver", "HighwayCore", "Terminal", "FileSystem", "XCBuild", "Url", "Task"], path: "./Sources/HighwayProject"),

// Task: We use the security command line tool to talk to the Keychain.
// Arguments: Task => Arguments
// Errors: We want to throw Errors
.target(name: "Keychain", dependencies: ["Task", "Arguments", "Errors"]),
.target(name: "Url"),
.target(name: "Errors"),
.target(name: "Arguments", dependencies: ["Errors"]),
.target(name: "Result"),
.target(name: "Terminal"),
.target(name: "POSIX", dependencies: ["Url"]),

.target(name: "Deliver", dependencies: ["POSIX", "Task", "Url", "Result", "Errors", "Arguments", "FileSystem"]),

// Url: Needs to have a concept of absolute/relative files/urls.
// Result: SHOULD return Results instead of throwing. FIXME!
// Errors: Throws Errors.
.target(name: "FileSystem", dependencies: ["POSIX", "Url", "Result", "Errors"]),
.target(name: "HWKit", dependencies: ["POSIX", "HighwayCore", "Terminal", "FileSystem", "Arguments"]),
.target(name: "HighwayCore", dependencies: ["POSIX", "Terminal", "FileSystem", "Task", "Url", "Arguments"]),
.target(name: "highway", dependencies: ["POSIX", "HighwayProject", "HWKit", "HighwayCore", "Terminal", "FileSystem", "Arguments"]),
.target(name: "XCBuild", dependencies: ["POSIX", "Url", "FileSystem", "Task", "Arguments"]),

// Url: In the end, a Task is always using some kind of files on disk.
// FileSystem: The framework checks (in certain cases) the existence of files.
// For example the current working directory of a Task before it is executed.
// Arguments: A Task has Arguments.
// Terminal: We have to log
.target(name: "Task", dependencies: ["Terminal", "Url", "FileSystem", "Errors", "Result", "Arguments"]),
.target(name: "TestKit", dependencies: ["POSIX", "HighwayCore", "Url", "Task"]),

// Tests
.testTarget(name: "HighwayCoreTests", dependencies: ["HighwayCore", "TestKit"]),
.testTarget(name: "HWKitTests", dependencies: ["HWKit", "TestKit"]),
.testTarget(name: "DeliverTests", dependencies: ["FileSystem", "Arguments"]),
.testTarget(name: "POSIXTests", dependencies: ["POSIX", "Url"]),
.testTarget(name: "FileSystemTests", dependencies: ["TestKit"]),
.testTarget(name: "HighwayCoreTests", dependencies: ["HighwayCore", "TestKit", "Arguments"]),
.testTarget(name: "HWKitTests", dependencies: ["HWKit", "TestKit", "Arguments"]),
.testTarget(name: "TerminalTests", dependencies: ["Terminal"]),
.testTarget(name: "FSKitTests", dependencies: ["FSKit"]),

// Deliver: We also test the delivery. FIXME: Should be done in another test.
// Keychain: We use the keychain to access the iTunesConnect password for the system tests.
.testTarget(name: "XCBuildTests", dependencies: ["TestKit", "Deliver", "XCBuild", "Keychain", "HighwayCore"], exclude: ["Fixtures"]),
.testTarget(name: "ResultTests", dependencies: ["Result"]),
.testTarget(name: "TaskTests", dependencies: ["Task", "FileSystem", "TestKit"]),
.testTarget(name: "UrlTests", dependencies: ["Url"]),
.testTarget(name: "ArgumentsTests", dependencies: ["Arguments"]),
],
swiftLanguageVersions: [4]
)
167 changes: 84 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Highway
=================

From zero to a new highway- + Swift Package Manager-project + an Xcode project + a build and test highway in 5 seconds.
From zero to a new highway- + Swift Package Manager-project + an Xcode project + a build and test highway in 5 seconds.

```
$ highway init_swift # ➤ new swift + highway project
Expand All @@ -16,24 +16,24 @@ Table of Contents
=================

* [Getting started](#getting-started)
* [Installing highway in 60 seconds (or less)](#installing-highway-in-60-seconds-or-less)
* [Setting up highway](#setting-up-highway)
* [Hello World (the fun part)](#hello-world-the-fun-part)
* [highway + Swift](#highway--swift)
* [Installing highway in 60 seconds (or less)](#installing-highway-in-60-seconds-or-less)
* [Setting up highway](#setting-up-highway)
* [Hello World (the fun part)](#hello-world-the-fun-part)
* [highway + Swift](#highway--swift)
* [Make your highway project useful](#make-your-highway-project-useful)
* [Creating a simple custom Highway](#creating-a-simple-custom-highway)
* [Highways with Dependencies](#highways-with-dependencies)
* [Highways with Results](#highways-with-results)
* [Special Highways](#special-highways)
* [Creating a simple custom Highway](#creating-a-simple-custom-highway)
* [Highways with Dependencies](#highways-with-dependencies)
* [Highways with Results](#highways-with-results)
* [Special Highways](#special-highways)
* [Included Frameworks](#included-frameworks)
* [Swift: build & test](#swift-build--test)
* [Xcode: build, archive, test (...) + xcpretty](#xcode-build-archive-test---xcpretty)
* [Keychain: Access Secrets](#keychain-access-secrets)
* [git: commit, push, (auto-) tag](#git-commit-push-auto--tag)
* [fastlane](#fastlane)
* [Swift: build & test](#swift-build--test)
* [Xcode: build, archive, test (...) + xcpretty](#xcode-build-archive-test---xcpretty)
* [Keychain: Access Secrets](#keychain-access-secrets)
* [git: commit, push, (auto-) tag](#git-commit-push-auto--tag)
* [fastlane](#fastlane)
* [Updating](#updating)
* [Dependencies](#dependencies)
* [CLI](#cli)
* [Dependencies](#dependencies)
* [CLI](#cli)

---
# Getting started
Expand Down Expand Up @@ -103,8 +103,8 @@ $ highway init_swift
Executing `highway init_swift` creates:
- a Swift Package Manager project (type: executable) named `my_new_app` and
- a highway project in the same directory (`./_highway`). The created highway project has two simple highways:
- `build`: Builds the created Swift project.
- `test`: Executes the tests of the Swift project.
- `build`: Builds the created Swift project.
- `test`: Executes the tests of the Swift project.


# Make your highway project useful
Expand All @@ -114,19 +114,19 @@ The `highway` command line tool can be executed with arguments - just like most

```
enum App: String, Highway {
case build
case test
case run
/// !!! Add more Highways by adding additional cases. !!!
var usage: String {
switch self {
case .build: return "Builds the project"
case .test: return "Executes tests"
case .run: return "Runs the project"
}
}
case build
case test
case run
/// !!! Add more Highways by adding additional cases. !!!
var usage: String {
switch self {
case .build: return "Builds the project"
case .test: return "Executes tests"
case .run: return "Runs the project"
}
}
}
```

Expand All @@ -153,19 +153,19 @@ You get the idea. Creating a custom highway is done in two steps:

```
enum App: String, Highway {
case build
case test
case run
case myHighway /// <---- here
var usage: String {
switch self {
case .build: return "Builds the project"
case .test: return "Executes tests"
case .run: return "Runs the project"
case .myHighway: return "I like snow" /// <---- and here
}
}
case build
case test
case run
case myHighway /// <---- here
var usage: String {
switch self {
case .build: return "Builds the project"
case .test: return "Executes tests"
case .run: return "Runs the project"
case .myHighway: return "I like snow" /// <---- and here
}
}
}
```

Expand All @@ -176,20 +176,20 @@ Still in `_highway/main.swift`: Scroll down and register your highway like this:
// MARK: - Setup your custom highways
highways
.highway(.build) {
.highway(.build) {
}
.highway(.test) {
}
.highway(.test) {
}
.highway(.run) {
}
.highway(.run) {
}
.highway(myHighway) {
print(">>> here <<<")
}
}
.highway(myHighway) {
print(">>> here <<<")
}
.go()
.go()
```
Now you can execute your highway like this:

Expand All @@ -205,19 +205,19 @@ A highway can depend on other highways. You specify dependencies between highway
```
highways
.highway(.build) {
// imagine code that actually builds your app/project.
}
.highway(.build) {
// imagine code that actually builds your app/project.
}
.highway(.test, dependsOn: [.build]) {
// imagine code that actually runs your tests.
}
.highway(.test, dependsOn: [.build]) {
// imagine code that actually runs your tests.
}
.highway(.run, dependsOn: [.test]) {
// imagine code that actually runs your app/project.
}
.highway(.run, dependsOn: [.test]) {
// imagine code that actually runs your app/project.
}
.go()
.go()
```

In the example above there are three highways, two of which depend on other highways.
Expand Down Expand Up @@ -245,19 +245,19 @@ let highways = Highways(App.self)
highways
.highway(.build) {
// image code that uses xcodebuild or swift (...)
// and returns the url to the build product.
return "./.build/release/my_app"
}
.highway(.build) {
// image code that uses xcodebuild or swift (...)
// and returns the url to the build product.
return "./.build/release/my_app"
}
.highway(.release, dependsOn: [.build]) {
let path: String = try highways.result(for: .build)
print(path)
// Now upload the file at path to a server.
}
.highway(.release, dependsOn: [.build]) {
let path: String = try highways.result(for: .build)
print(path)
// Now upload the file at path to a server.
}
.go()
.go()
```

## Special Highways
Expand All @@ -270,19 +270,19 @@ let highways = Highways(App.self)
highways
// specical highways
// specical highways
.onError { print($0) } // 1.
.onEmptyCommand { print("$ ./_highway") } // 2.
.onUnrecognizedCommand { print("args: \($0)")} // 3.
.onError { print($0) } // 1.
.onEmptyCommand { print("$ ./_highway") } // 2.
.onUnrecognizedCommand { print("args: \($0)")} // 3.
// regular custom highways, as usual
// regular custom highways, as usual
.highway(.build) { /*...*/ }
.highway(.release) { /*...*/ }
.highway(.build) { /*...*/ }
.highway(.release) { /*...*/ }
.go()
.go()
```

The code above registers for three special highways:
Expand Down Expand Up @@ -379,3 +379,4 @@ Update highway itself:
$ highway self_update
$ highway --version # verify
```

Loading

0 comments on commit 82823ad

Please sign in to comment.