Skip to content

Commit 6b79fce

Browse files
authored
add cli and library getting started guides (#192)
motivation: getting started guides changes: * add a cli guide * add a library guide + link from index page * share install instructions across pages
1 parent 849016a commit 6b79fce

File tree

6 files changed

+382
-22
lines changed

6 files changed

+382
-22
lines changed

getting-started/_installing.md renamed to _includes/getting-started/_installing.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
## Installing Swift
22

3-
If you don't have Swift installed, [install it first](/install). To test that you have Swift installed, run `swift --version` in the terminal.
3+
If you don't have Swift installed, [install it first](/install).
4+
5+
To test that you have Swift installed, run `swift --version` in the terminal.
46

57
### Swift Package Manager
68

getting-started/_use-cases.html

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,42 @@
33
Below are some examples of the many use cases of Swift.
44

55
<ul class="use-case-list">
6+
67
<li class="use-case">
7-
<h3>Build a Web Server (Vapor)</h3>
8+
<h3>Command-line Tool</h3>
89
<p class="description">
9-
Use the open-source Vapor framework to build a web API entirely with Swift.
10-
Requires macOS or Linux.
10+
Build a command-line tool using SwiftPM.
1111
</p>
12-
13-
<a href="/getting-started/vapor-web-server" class="cta-secondary">Start tutorial</a>
12+
13+
<a href="/getting-started/cli-swiftpm" class="cta-secondary">Start tutorial</a>
1414
</li>
15-
15+
1616
<li class="use-case">
17-
<h3>Build a Command-line Tool</h3>
17+
<h3>Library</h3>
1818
<p class="description">
19-
Build a command-line tool using Swift and SwiftPM.
19+
Build a library using SwiftPM.
2020
</p>
2121

22-
<a href="/getting-started/cli-tool" class="cta-secondary">Start tutorial</a>
22+
<a href="/getting-started/library-swiftpm" class="cta-secondary">Start tutorial</a>
2323
</li>
24-
24+
2525
<li class="use-case">
26-
<h3>Build an app for Apple platforms</h3>
26+
<h3>Web Server with Vapor</h3>
27+
<p class="description">
28+
Use the open-source Vapor framework to build a web service using SwiftPM.
29+
Requires macOS or Linux.
30+
</p>
31+
32+
<a href="/getting-started/vapor-web-server" class="cta-secondary">Start tutorial</a>
33+
</li>
34+
35+
<li class="use-case">
36+
<h3>App for Apple platforms</h3>
2737
<p class="description">
2838
Use Swift and SwiftUI to build an app that works on iOS and macOS.
2939
Requires macOS 12 and Xcode 14.
3040
</p>
31-
41+
3242
<a href="/" class="cta-secondary">Start tutorial</a>
3343
</li>
34-
</ul>
44+
</ul>
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
---
2+
layout: page
3+
title: Build a Command-line Tool
4+
---
5+
6+
{% include getting-started/_installing.md %}
7+
8+
## Bootstrapping
9+
10+
Let’s write a small application with our new Swift development environment.
11+
To start, we’ll use SwiftPM to make a new project for us. In your terminal of choice run:
12+
13+
~~~bash
14+
❯ mkdir MyCLI
15+
cd MyCLI
16+
❯ swift package init --name MyCLI --type executable
17+
~~~
18+
19+
This will generate a new directory called MyCLI with the following files:
20+
21+
~~~no-highlight
22+
.
23+
├── Package.swift
24+
├── README.md
25+
├── Sources
26+
│   └── MyCLI
27+
│   └── MyCLI.swift
28+
└── Tests
29+
└── MyCLITests
30+
└── MyCLITests.swift
31+
~~~
32+
33+
`Package.swift` is the manifest file for Swift. It’s where you keep metadata for your project, as well as dependencies.
34+
35+
`Sources/MyCLI/MyCLI.swift` is the application entry point and where we’ll write our application code.
36+
`Test/MyCLITests/MyCLITests.swift` is where we can write tests for our application.
37+
38+
In fact, SwiftPM generated a "Hello, world!" project for us, including some unit tests!
39+
40+
We can run the tests by running `swift test` in our terminal.
41+
42+
~~~bash
43+
❯ swift test
44+
Building for debugging...
45+
[6/6] Linking MyCLIPackageTests
46+
Build complete! (16.53s)
47+
Test Suite 'All tests' started at 2023-01-12 13:38:22.393
48+
Test Suite 'MyCLIPackageTests.xctest' started at 2023-01-12 13:38:22.394
49+
Test Suite 'MyCLITests' started at 2023-01-12 13:38:22.394
50+
Test Case '-[MyCLITests.MyCLITests testExample]' started.
51+
Test Case '-[MyCLITests.MyCLITests testExample]' passed (0.003 seconds).
52+
Test Suite 'MyCLITests' passed at 2023-01-12 13:38:22.397.
53+
Executed 1 test, with 0 failures (0 unexpected) in 0.003 (0.003) seconds
54+
Test Suite 'MyCLIPackageTests.xctest' passed at 2023-01-12 13:38:22.398.
55+
Executed 1 test, with 0 failures (0 unexpected) in 0.003 (0.004) seconds
56+
Test Suite 'All tests' passed at 2023-01-12 13:38:22.398.
57+
Executed 1 test, with 0 failures (0 unexpected) in 0.003 (0.005) seconds
58+
~~~
59+
60+
We can also run the program by running `swift run` in our terminal.
61+
62+
~~~bash
63+
❯ swift run MyCLI
64+
[3/3] Linking MyCLI
65+
Hello, World!
66+
~~~
67+
68+
## Adding dependencies
69+
70+
Swift based applications are usually composed from libraries that provide useful functionality.
71+
72+
In this project, we’ll use a package called [swift-figlet](https://github.com/tomerd/swift-figlet) which will help us make ASCII art.
73+
74+
You can find more interesting libraries on [Swift Package Index](https://swiftpackageindex.com) -- the unofficial package index for Swift.
75+
76+
To do so, we extend our `Package.swift` file with the following information:
77+
78+
~~~swift
79+
// swift-tools-version: 5.7
80+
81+
import PackageDescription
82+
83+
let package = Package(
84+
name: "MyCLI",
85+
products: [
86+
.executable(name: "MyCLI", targets: ["MyCLI"])
87+
],
88+
dependencies: [
89+
.package(url: "https://github.com/tomerd/swift-figlet", branch: "main"),
90+
],
91+
targets: [
92+
.executableTarget(
93+
name: "MyCLI",
94+
dependencies: [
95+
.product(name: "Figlet", package: "swift-figlet"),
96+
]
97+
),
98+
.testTarget(
99+
name: "MyCLITests",
100+
dependencies: ["MyCLI"]
101+
),
102+
]
103+
)
104+
~~~
105+
106+
Running `swift build` will instruct SwiftPM to install the new dependencies and then proceed to build the code.
107+
108+
Running this command also created a new file for us, `Package.resolved`.
109+
This file is a snapshot of the exact versions of the dependencies we are using locally.
110+
111+
To use this dependency, we can open `MyCLI.swift`, remove everything that’s in there (it’s just an example), and add this line to it:
112+
113+
~~~swift
114+
import Figlet
115+
~~~
116+
117+
This line means that we can now use the `Figlet` module that the `swift-figlet` package exports.
118+
119+
## A small application
120+
121+
Now let’s write a small application with our new dependency. In our `MyCLI.swift`, add the following code:
122+
123+
~~~swift
124+
import Figlet // from the previous step
125+
126+
@main
127+
struct FigletTool {
128+
static func main() {
129+
Figlet.say("Hello, Swift!")
130+
}
131+
}
132+
~~~
133+
134+
Now lets remove the default unit test since we changes the tools' code.
135+
Replace the example content of `MyCLITests.swift` with the following code:
136+
137+
~~~swift
138+
@testable import MyCLI
139+
import XCTest
140+
141+
final class MyCLITests: XCTestCase {}
142+
~~~
143+
144+
Once we save that, we can run our application with `swift run`
145+
Assuming everything went well, you should see your application print this to the screen:
146+
147+
~~~no-highlight
148+
_ _ _ _ _ __ _ _
149+
| | | | ___ | | | | ___ ___ __ __ (_) / _| | |_ | |
150+
| |_| | / _ \ | | | | / _ \ / __| \ \ /\ / / | | | |_ | __| | |
151+
| _ | | __/ | | | | | (_) | _ \__ \ \ V V / | | | _| | |_ |_|
152+
|_| |_| \___| |_| |_| \___/ ( ) |___/ \_/\_/ |_| |_| \__| (_)
153+
|/
154+
~~~
155+
156+
## Argument parsing
157+
158+
Most command line tools need to be able to parse command line arguments.
159+
160+
To add this capability to our application, we add a dependency on [swift-argument-parser](https://github.com/apple/swift-argument-parser).
161+
162+
To do so, we extend our `Package.swift` file with the following information:
163+
164+
~~~swift
165+
// swift-tools-version: 5.7
166+
167+
import PackageDescription
168+
169+
let package = Package(
170+
name: "swift-swift",
171+
dependencies: [
172+
.package(url: "https://github.com/tomerd/swift-figlet", branch: "main"),
173+
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
174+
],
175+
products: [
176+
.executable(name: "MyCLI", targets: ["MyCLI"])
177+
],
178+
targets: [
179+
.executableTarget(
180+
name: "MyCLI",
181+
dependencies: [
182+
.product(name: "Figlet", package: "swift-figlet"),
183+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
184+
]
185+
),
186+
.testTarget(
187+
name: "MyCLITests",
188+
dependencies: ["MyCLI"]
189+
),
190+
]
191+
)
192+
~~~
193+
194+
We can now import the argument parsing module provided by `swift-argument-parser` and use it in our application:
195+
196+
~~~swift
197+
import ArgumentParser
198+
import Figlet
199+
200+
@main
201+
struct FigletTool: ParsableCommand {
202+
@Option(help: "Specify the input")
203+
public var input: String
204+
205+
public func run() throws {
206+
Figlet.say(self.input)
207+
}
208+
}
209+
~~~
210+
211+
For more information about how [swift-argument-parser](https://github.com/apple/swift-argument-parser) parses command line options, see [swift-argument-parser documentation](https://github.com/apple/swift-argument-parser) documentation.
212+
213+
Once we save that, we can run our application with `swift run MyCLI --input 'Hello, world!'`
214+
215+
Note we need to specify the executable in this case, so we can pass the `input` argument to it.
216+
217+
Assuming everything went well, you should see your application print this to the screen:
218+
219+
~~~no-highlight
220+
_ _ _ _ _ _ _
221+
| | | | ___ | | | | ___ __ __ ___ _ __ | | __| | | |
222+
| |_| | / _ \ | | | | / _ \ \ \ /\ / / / _ \ | '__| | | / _` | | |
223+
| _ | | __/ | | | | | (_) | _ \ V V / | (_) | | | | | | (_| | |_|
224+
|_| |_| \___| |_| |_| \___/ ( ) \_/\_/ \___/ |_| |_| \__,_| (_)
225+
|/
226+
~~~
227+
228+
---
229+
230+
Find the source code for this guide at [https://github.com/apple/swift-getting-started-cli](https://github.com/apple/swift-getting-started-cli)

getting-started/cli-tool/index.md

Lines changed: 0 additions & 6 deletions
This file was deleted.

getting-started/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ layout: page
33
title: Getting Started
44
---
55

6-
{% include_relative _installing.md %}
6+
{% include getting-started/_installing.md %}
77
{% include_relative _use-cases.html %}
8-
{% include_relative _go-further.html %}
8+
{% include_relative _go-further.html %}

0 commit comments

Comments
 (0)