A Look at Command Line Swi!
1
Intro
— Me
— I work at GMO Pepabo on "Minne"
— GitHub Contributions
— Danger-swift
— vim-xcode
— swiftformat-script
— LattnerBot
2
What is a script
— A program without a GUI that has a only a few set
options
— Not a Mac app (has a GUI)
— Not grep (too many options)
— Examples
— Release.swift
— Format.swift
3
When to use a shell script
— When covered with common Unix programs
When not to use a shell script
— External packages/libraries
— Long
— Frequent changes
4
Comparison of Swi! with Ruby and Python
— Type safety
— Concurrency
— Python has it
— Swift relies on GCD or lower level APIs
— Go seems like a good choice
— Documentation
5
Comparison continued
— Portability
— Pyenv
— Rbenv
— Swiftenv
— Tooling
— Reliance on Xcode
— Package management
6
SPM
— Strengths
— Similarity to Bundler and pip
— Weaknesses
— Commands are long
— swift package generate-xcodeproj
— Fixable w/ alias
— Package.swift is very verbose
7
Example of Package.swi! file
// swift-tools-version:4.0
import PackageDescription
let package = Package(
name: "LattnerBot",
products: [
.library(
name: "LattnerBot",
targets: ["LattnerBot"]),
],
dependencies: [
.package(url: "https://github.com/JohnSundell/ShellOut.git", from: "2.0.0"), // Shell commands
.package(url: "https://github.com/kylef/Commander.git", from: "0.8.0"), // CLI tool
.package(url: "https://github.com/SlackKit/SlackKit.git", from: "4.1.0") // Slack interaction
],
targets: [
.target(
name: "LattnerBot",
dependencies: ["Commander", "ClocWrapper", "Output"]),
// More targets
.testTarget(
name: "OutputTests",
dependencies: ["Output"]),
]
)
8
General good fits for Swi! cli
— iOS development team
— Shared language
— No whiplash from switching languages
— One person devs
— Don’t work with a scripting language often
9
Bad fits for Swi! cli
— Supporting a non-Swift codebase
— Shared flow w/ non-Swift team
— Lots of concurrency
— Cross platform portability
— No Windows support
— Unclear, undocumented Linux support
— SPM
— Lots of string manipulation
10
How to make a Swi! script or
cli app
11
Executable
#!/usr/bin/swift
import Foundation
// ...
12
Tasks/process
@discardableResult
func shell(_ command: String) -> Int32 {
let args = command.components(separatedBy: " ")
let process = Process()
process.launchPath = "/usr/bin/env"
process.arguments = args
process.launch()
process.waitUntilExit()
return process.terminationStatus
}
13
Arguments
var filePath: String?
var configFile: String?
let args = ProcessInfo.processInfo.arguments
args.enumerated().forEach { index, arg in
switch arg {
case "--path":
filePath = args[index + 1]
case "-p":
filePath = args[index + 1]
case "--config":
configFile = args[index + 1]
case "-c":
configFile = args[index + 1]
default:
break
}
}
14
Pu!ing it all together
let disabledRules: [String] = [
"consecutiveSpaces",
"trailingSpace",
]
guard let filePath = filePath else {
print("Missing --path/-p flag"); exit(1)
}
print("Running Swiftformat")
shell("swiftformat --disable (disabledRules.joined(separator: ",")) (filePath)")
guard let configFile = configFile else {
print("Missing --config/-c flag"); exit(1)
}
print("Running Swiftlint Autocorrect")
shell("fd . -0 --full-path (filePath) -e swift -x swiftlint autocorrect --config (configFile) --path")
15
Marathon
— Demo
16
SPM
— Demo of LattnerBot
— Discussion of convenient libraries
17
Predictions for the future
— A general shift from Ruby to Swift for iOS tools
— Cocoapods vs Carthage
— Fastlane
— Danger
— A community-led approach without much focus by
Apple
— Perhaps more documentation
— A potentially significant influx of community support
18
Swi! features
— Async-await
— Native regex
— Python and Ruby interop
— Better SPM
— Better string subscripting (never)
19
Resources
— Apple Docs
— Stack Overflow
— Blogs
Tools
— Swiftenv
— Marathon
20
Vim-related
— Sample Vimrc
— ALE
— Deoplete
— vim-xcode
— https://github.com/keith/swift.vim
21
Nice libraries
— https://github.com/Draveness/RbSwift
— https://github.com/kylef/Commander
— https://github.com/jakeheis/SwiftCLI
— https://github.com/JohnSundell/ShellOut
— https://github.com/JohnSundell/Files
— https://github.com/kareman/SwiftShell
22
Questions for audience
— Do you use Swift for anything other than iOS, what?
— Do you prefer a language other than Swift for
scripting or cli apps, which one?
23
Questions from audience
24

A Look at Command Line Swift

  • 1.
    A Look atCommand Line Swi! 1
  • 2.
    Intro — Me — Iwork at GMO Pepabo on "Minne" — GitHub Contributions — Danger-swift — vim-xcode — swiftformat-script — LattnerBot 2
  • 3.
    What is ascript — A program without a GUI that has a only a few set options — Not a Mac app (has a GUI) — Not grep (too many options) — Examples — Release.swift — Format.swift 3
  • 4.
    When to usea shell script — When covered with common Unix programs When not to use a shell script — External packages/libraries — Long — Frequent changes 4
  • 5.
    Comparison of Swi!with Ruby and Python — Type safety — Concurrency — Python has it — Swift relies on GCD or lower level APIs — Go seems like a good choice — Documentation 5
  • 6.
    Comparison continued — Portability —Pyenv — Rbenv — Swiftenv — Tooling — Reliance on Xcode — Package management 6
  • 7.
    SPM — Strengths — Similarityto Bundler and pip — Weaknesses — Commands are long — swift package generate-xcodeproj — Fixable w/ alias — Package.swift is very verbose 7
  • 8.
    Example of Package.swi!file // swift-tools-version:4.0 import PackageDescription let package = Package( name: "LattnerBot", products: [ .library( name: "LattnerBot", targets: ["LattnerBot"]), ], dependencies: [ .package(url: "https://github.com/JohnSundell/ShellOut.git", from: "2.0.0"), // Shell commands .package(url: "https://github.com/kylef/Commander.git", from: "0.8.0"), // CLI tool .package(url: "https://github.com/SlackKit/SlackKit.git", from: "4.1.0") // Slack interaction ], targets: [ .target( name: "LattnerBot", dependencies: ["Commander", "ClocWrapper", "Output"]), // More targets .testTarget( name: "OutputTests", dependencies: ["Output"]), ] ) 8
  • 9.
    General good fitsfor Swi! cli — iOS development team — Shared language — No whiplash from switching languages — One person devs — Don’t work with a scripting language often 9
  • 10.
    Bad fits forSwi! cli — Supporting a non-Swift codebase — Shared flow w/ non-Swift team — Lots of concurrency — Cross platform portability — No Windows support — Unclear, undocumented Linux support — SPM — Lots of string manipulation 10
  • 11.
    How to makea Swi! script or cli app 11
  • 12.
  • 13.
    Tasks/process @discardableResult func shell(_ command:String) -> Int32 { let args = command.components(separatedBy: " ") let process = Process() process.launchPath = "/usr/bin/env" process.arguments = args process.launch() process.waitUntilExit() return process.terminationStatus } 13
  • 14.
    Arguments var filePath: String? varconfigFile: String? let args = ProcessInfo.processInfo.arguments args.enumerated().forEach { index, arg in switch arg { case "--path": filePath = args[index + 1] case "-p": filePath = args[index + 1] case "--config": configFile = args[index + 1] case "-c": configFile = args[index + 1] default: break } } 14
  • 15.
    Pu!ing it alltogether let disabledRules: [String] = [ "consecutiveSpaces", "trailingSpace", ] guard let filePath = filePath else { print("Missing --path/-p flag"); exit(1) } print("Running Swiftformat") shell("swiftformat --disable (disabledRules.joined(separator: ",")) (filePath)") guard let configFile = configFile else { print("Missing --config/-c flag"); exit(1) } print("Running Swiftlint Autocorrect") shell("fd . -0 --full-path (filePath) -e swift -x swiftlint autocorrect --config (configFile) --path") 15
  • 16.
  • 17.
    SPM — Demo ofLattnerBot — Discussion of convenient libraries 17
  • 18.
    Predictions for thefuture — A general shift from Ruby to Swift for iOS tools — Cocoapods vs Carthage — Fastlane — Danger — A community-led approach without much focus by Apple — Perhaps more documentation — A potentially significant influx of community support 18
  • 19.
    Swi! features — Async-await —Native regex — Python and Ruby interop — Better SPM — Better string subscripting (never) 19
  • 20.
    Resources — Apple Docs —Stack Overflow — Blogs Tools — Swiftenv — Marathon 20
  • 21.
    Vim-related — Sample Vimrc —ALE — Deoplete — vim-xcode — https://github.com/keith/swift.vim 21
  • 22.
    Nice libraries — https://github.com/Draveness/RbSwift —https://github.com/kylef/Commander — https://github.com/jakeheis/SwiftCLI — https://github.com/JohnSundell/ShellOut — https://github.com/JohnSundell/Files — https://github.com/kareman/SwiftShell 22
  • 23.
    Questions for audience —Do you use Swift for anything other than iOS, what? — Do you prefer a language other than Swift for scripting or cli apps, which one? 23
  • 24.