Skip to content

Commit e23a72d

Browse files
heckjbripeticcaMaxDesiatov
authored
migrated, and updated, swift package manager getting started content (#8738)
Migrate content from https://www.swift.org/documentation/package-manager/ to DocC into an article `Getting Started` ### Modifications: Added getting started article, with updated content to align to examples - two of the 3 updated to reference Swift 5.10 to show more recent dependency declarations in a `Package.swift` manifest. resolves #8702 --------- Co-authored-by: Bri Peticca <[email protected]> Co-authored-by: Max Desiatov <[email protected]>
1 parent f2cbf10 commit e23a72d

File tree

2 files changed

+187
-5
lines changed

2 files changed

+187
-5
lines changed

Sources/PackageManagerDocs/Documentation.docc/GettingStarted.md

Lines changed: 186 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,193 @@
11
# Getting Started
22

3-
Learn to create and use a Swift package.
3+
Learn to create and use Swift packages.
44

55
## Overview
66

7-
overview content here....
7+
To provide a more complete look at what the Swift Package Manager can do, the following example consists of three interdependent packages:
88

9-
### First Section
9+
- [PlayingCard](https://github.com/apple/example-package-playingcard) - Defines PlayingCard, Suit, and Rank types.
10+
- [DeckOfPlayingCards](https://github.com/apple/example-package-deckofplayingcards) - Defines a Deck type that shuffles and deals an array of PlayingCard values.
11+
- [Dealer](https://github.com/apple/example-package-dealer) - Defines an executable that creates a DeckOfPlayingCards, shuffles it, and deals the first 10 cards.
12+
13+
### Creating a Library Package
14+
15+
We'll start by creating a target representing a playing card in a standard 52-card deck.
16+
The [PlayingCard](https://github.com/apple/example-package-playingcard) target defines the PlayingCard type, which consists of a Suit enumeration value (Clubs, Diamonds, Hearts, Spades) and a Rank enumeration value (Ace, Two, Three, …, Jack, Queen, King).
17+
18+
```swift
19+
public enum Rank: Int {
20+
case two = 2
21+
case three, four, five, six, seven, eight, nine, ten
22+
case jack, queen, king, ace
23+
}
24+
25+
public enum Suit: String {
26+
case spades, hearts, diamonds, clubs
27+
}
28+
29+
public struct PlayingCard {
30+
let rank: Rank
31+
let suit: Suit
32+
}
33+
```
34+
35+
By convention, a target includes any source files located in the `Sources/<target-name>` directory.
36+
37+
```
38+
example-package-playingcard
39+
├── Sources
40+
│ └── PlayingCard
41+
│ ├── PlayingCard.swift
42+
│ ├── Rank.swift
43+
│ └── Suit.swift
44+
└── Package.swift
45+
```
46+
47+
Because the PlayingCard target does not produce an executable, it can be described as a library.
48+
A library is a target that builds a module which can be imported by other packages.
49+
By default, a library module exposes all of the public types and methods declared in source code located in the `Sources/<target-name>` directory.
50+
51+
When creating a library package intended for use as a dependency in other projects, the `Package.swift` manifest resides at the top level/root of the package directory structure.
52+
53+
Run swift build to start the Swift build process.
54+
If everything worked correctly, it compiles the Swift module for PlayingCard.
55+
56+
> The complete code for the PlayingCard package can be found at [https://github.com/apple/example-package-playingcard](https://github.com/apple/example-package-playingcard).
57+
58+
### Importing Dependencies
59+
60+
The [DeckOfPlayingCards package](https://github.com/apple/example-package-playingcard.git) depends in the previous package: It defines a Deck type.
61+
62+
To use the PlayingCards module, the DeckOfPlayingCards package declares the package as a dependency in its `Package.swift` manifest file.
63+
64+
```swift
65+
// swift-tools-version:5.10
66+
import PackageDescription
67+
68+
let package = Package(
69+
name: "DeckOfPlayingCards",
70+
products: [
71+
.library(name: "DeckOfPlayingCards",
72+
targets: ["DeckOfPlayingCards"]),
73+
],
74+
dependencies: [
75+
.package(
76+
url: "https://github.com/apple/example-package-playingcard.git",
77+
from: "3.0.0"),
78+
],
79+
targets: [
80+
.target(
81+
name: "DeckOfPlayingCards",
82+
dependencies: [
83+
.product(name: "PlayingCard",
84+
package: "example-package-playingcard")
85+
]),
86+
.testTarget(
87+
name: "DeckOfPlayingCardsTests",
88+
dependencies: [
89+
.target(name: "DeckOfPlayingCards")
90+
]),
91+
]
92+
)
93+
```
94+
95+
Each dependency specifies a source URL and version requirements.
96+
The source URL is a URL accessible to the current user that resolves to a Git repository.
97+
The package manager uses the version requirements, which follow Semantic Versioning (SemVer) conventions, to determine which Git tag to check out and use to build the dependency.
98+
The requirement for the PlayingCard dependency uses the most recent version with a major version equal to 3.
99+
100+
When you run the swift build command, the Package Manager downloads all of the dependencies, compiles them, and links them to the package module.
101+
This allows DeckOfPlayingCards to access the public members of its dependent modules with import statements.
102+
103+
You can see the downloaded sources in the `.build/checkouts` directory at the root of your project, and intermediate build products in the `.build` directory at the root of your project.
104+
105+
> The complete code for the DeckOfPlayingCards package can be found at [https://github.com/apple/example-package-deckofplayingcards](https://github.com/apple/example-package-deckofplayingcards).
106+
107+
### Resolving transitive dependencies
108+
109+
With everything else in place, now you can build the Dealer executable.
110+
The Dealer executable depends on the `DeckOfPlayingCards` package, which in turn depends on the `PlayingCard` package.
111+
However, because the package manager automatically resolves transitive dependencies, you only need to declare the `DeckOfPlayingCards` package as a dependency.
112+
113+
```swift
114+
// swift-tools-version:5.10
115+
116+
import PackageDescription
117+
118+
let package = Package(
119+
name: "dealer",
120+
platforms: [
121+
.macOS(.v11)
122+
],
123+
products: [
124+
.executable(name: "dealer",
125+
targets: ["dealer"]),
126+
],
127+
dependencies: [
128+
.package(
129+
url: "https://github.com/apple/example-package-deckofplayingcards.git",
130+
from: "3.0.0"),
131+
.package(
132+
url: "https://github.com/apple/swift-argument-parser.git",
133+
from: "0.4.4"),
134+
],
135+
targets: [
136+
.executableTarget(
137+
name: "dealer",
138+
dependencies: [
139+
.product(name: "DeckOfPlayingCards",
140+
package: "example-package-deckofplayingcards"),
141+
.product(name: "ArgumentParser",
142+
package: "swift-argument-parser")
143+
]),
144+
.testTarget(
145+
name: "DealerTests",
146+
dependencies: [
147+
.byName(name: "dealer")
148+
]),
149+
]
150+
)
151+
152+
```
153+
154+
Swift requires that a source file imports the modules for any types that are referenced in code.
155+
In the Dealer module's `Deal.swift` file, the code imports `DeckOfPlayingCards` and `PlayingCard` to use types from each.
156+
157+
```swift
158+
import DeckOfPlayingCards
159+
160+
var deck = Deck.standard52CardDeck()
161+
deck.shuffle()
162+
163+
for count in counts {
164+
var cards: [PlayingCard] = []
165+
166+
for _ in 0..<count {
167+
guard let card = deck.deal() else {
168+
Self.exit(withError: Error.notEnoughCards)
169+
}
170+
171+
cards.append(card)
172+
}
173+
174+
print(cards.map(\.description).joined(separator: "\t"))
175+
}
176+
```
177+
178+
Running the `swift build` command compiles and produces the `Dealer` executable, which you run from the `.build/debug` directory.
179+
180+
```bash
181+
$ swift build
182+
$ .build/debug/Dealer 5
183+
♠︎ 6 ♡ 4 ♣︎ 4 ♡ A ♡ K
184+
```
185+
186+
You can build and run the complete example by downloading the source code of the Dealer project from GitHub and running the following commands:
187+
188+
```bash
189+
$ git clone https://github.com/apple/example-package-dealer.git
190+
$ cd example-package-dealer
191+
$ swift run dealer <count>
192+
```
10193

11-
First section content

Sources/PackageManagerDocs/Documentation.docc/IntroducingPackages.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Learn to create and use a Swift package.
55
## Overview
66

77
A package consists of a `Package.swift` manifest file along with source files, resources, and other assets.
8-
The manifest file, or package manifest, defines the package's name and its contents using the PackageDescription module.
8+
The manifest file, or package manifest, defines the package's name and its contents using the [PackageDescription](https://developer.apple.com/documentation/packagedescription) module.
99

1010
Each package declares `Products`, a list of what the package produces.
1111
Types of products include libraries, executables, and plugins:

0 commit comments

Comments
 (0)