Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
244 commits
Select commit Hold shift + click to select a range
9b1e5ab
created command for templates + added commands for local and git
May 14, 2025
b800ec6
initial push for templates in package.swift prototype
May 21, 2025
b50a4fc
fixtures + cleanup
Jun 4, 2025
90640a0
deleting unnecessary fixtures
Jun 4, 2025
d3d6591
added new dependencies to handle addDependency functionality of templ…
Jun 4, 2025
7ecbc34
build plan for building products and targets of type templates, will …
Jun 4, 2025
dd53579
fulfilling cases for addproduct, will need to revisit to make sure ad…
Jun 4, 2025
db71c64
fulfilling cases for addtarget, will need to revisit to make sure add…
Jun 4, 2025
e8aa145
show templates in a local package
Jun 4, 2025
026654b
fullfilling switch case for snippets
Jun 4, 2025
082d38a
registering the show-templates command and adding more to init
Jun 4, 2025
4d9ca97
removing testing library options, to revisit and discuss
Jun 4, 2025
374f842
pairing templates with executables for now wehen it comes to creating…
Jun 4, 2025
0326d50
added context switcher for swiftcommandstate
Jun 4, 2025
76f4e3c
make templates recognizable by package.swift
Jun 4, 2025
7d86a7b
dependency graph for swift targets and templates need to be revisited
Jun 5, 2025
aefc478
diagnostics added for template targets + products, will need to add t…
Jun 5, 2025
e93ebd5
manifest loading and json parsing
Jun 5, 2025
27b194f
templates directory check added, as template executables should not b…
Jun 5, 2025
21e0e38
added templates as a type of module, will need to revisit to edit beh…
Jun 5, 2025
5aa6b95
added templates as a type of module, will need to revisit to edit beh…
Jun 5, 2025
9a99048
changed tools version when generating a new project, will need to rev…
Jun 5, 2025
8d555f3
target and product descriptions syntax
Jun 5, 2025
1def8d8
build parameters for templates, will need to revisit
Jun 5, 2025
9d54614
plugins support for executing templates
Jun 5, 2025
c23948c
buildsupport for templates, will need to revisit
Jun 5, 2025
84e7e2a
template creation workhorse
Jun 5, 2025
eb495d7
build support for xcbuild
Jun 5, 2025
1938272
reverting plugin test to normal
Jun 5, 2025
5e7ba4a
printing out --experimental-dump-help
Jun 5, 2025
5722eb2
capturing --experimental-dump-help and parsing it
Jun 5, 2025
4bb98cc
Move new package description API to the array types and update versio…
cmcgee1024 Jun 5, 2025
ef8eab1
Merge pull request #16 from christie-mcgee/ergonomics
Jun 6, 2025
536802d
Fix show-executables subcommand so that it does not show templates
cmcgee1024 Jun 6, 2025
9079977
Use in-process API to run experimental dump help and decode JSON
cmcgee1024 Jun 6, 2025
4c1288a
Merge pull request #18 from christie-mcgee/ergonomics
Jun 7, 2025
ace4c02
Merge branch 'inbetween' into use_inprocess_api
Jun 7, 2025
c461579
Merge pull request #19 from christie-mcgee/use_inprocess_api
Jun 7, 2025
50890f8
fixtures update
Jun 7, 2025
d2cdc43
Updating package.swift to include Argumnetparser dependency for works…
Jun 7, 2025
0b6eec2
argument parsing dump-help
Jun 7, 2025
e7040c2
merging
Jun 7, 2025
e2c8172
running the executable
Jun 9, 2025
4f89b89
fixed syntax issues + added functionality for arguments with enums
Jun 9, 2025
7b79863
Remove template target and product types and use the template init op…
cmcgee1024 Jun 10, 2025
67b03d2
Match whitespace and formatting to original main branch
cmcgee1024 Jun 10, 2025
237bd95
formatting + starting to add git capabilities
Jun 10, 2025
2b15a28
Merge pull request #23 from christie-mcgee/reduce_target_product_types
Jun 11, 2025
7a42dfd
git support + dependency mapping based on type
Jun 11, 2025
8b0bd20
Merge branch 'inbetween' of github.pie.apple.com:jbute/swift-pm-templ…
Jun 11, 2025
3b2c146
added requirements + ability to checkout a branch without creating ne…
Jun 11, 2025
0c6ab10
added git functionality to show-templates
Jun 11, 2025
7698033
refactoring and organizing code
Jun 11, 2025
c9f5001
organizing code to differentiate between initializing regular package…
Jun 11, 2025
824c8c6
added documentation + reorganized show-templates code
Jun 11, 2025
c037f68
changed naming from template types (git, local, registry) to template…
Jun 11, 2025
9fcef0b
generating templates from package registry
Jun 12, 2025
954f732
added registry support for show-templates
Jun 12, 2025
c57abff
formatting + documentation + quality
Jun 12, 2025
cf21512
Add instructions to the SwiftPM readme for trying out templates
cmcgee1024 Jun 13, 2025
5049f27
Make the template option optional when initializing with a template
cmcgee1024 Jun 13, 2025
517215f
On failure due to multiple available templates provide the list as pa…
cmcgee1024 Jun 13, 2025
bc68900
Merge pull request #36 from christie-mcgee/make_template_name_optional
Jun 16, 2025
6febfe4
Merge pull request #35 from christie-mcgee/readme_instructions
Jun 16, 2025
12b3110
ergonomics, reducing repetition of template keyword
Jun 16, 2025
ca8a496
added documentation + predetermined args
Jun 17, 2025
df8286b
changed args option to instead take any arguments after as predetermi…
Jun 17, 2025
2fcb829
inferring source of template
Jun 17, 2025
bdb65e4
fixing error regarding passing args to template
Jun 18, 2025
6af858a
args checking + file existing checks if local template option picked
Jun 18, 2025
21fb739
made description, permissions, and initial type top level
Jun 20, 2025
643ac8a
made scaffolding top level command
Jun 24, 2025
afa6404
added ability to view description of templates to show-templates
Jun 24, 2025
8455874
new command swift package scaffold
Jun 24, 2025
d102b2e
added more clarity to .template parameter initialType
Jun 24, 2025
4f15959
registry stuff, might revert later, but for now we can keep
Jul 8, 2025
6355348
added back to init templates
Jul 8, 2025
240c0e2
prompting improvements
Jul 15, 2025
7b2e0e3
added validate package, first-class testing support, temporary packages
Jul 22, 2025
8750318
added testing logs + revamped testing system for templates
Jul 23, 2025
8213215
reverted package-metadata changes
Jul 23, 2025
89f4058
fixed dummyRepositorymanager to conform to protocol
Jul 23, 2025
eb511e9
possibility to edit format of test result to json too
Jul 23, 2025
407d347
bug fix where subcommand was prompted for when there was no valid sub…
Jul 23, 2025
559e1ec
run package clean after generating package
Aug 6, 2025
0f3eb21
refactoring
Aug 8, 2025
3e1d137
refactoring + error handling
Aug 13, 2025
4bb2552
refactoring templates + fixing bug where git and template id was not …
Aug 13, 2025
ff48313
refactoring test template + changed structure holding prompting answers
Aug 14, 2025
26b7027
refactored directory manager to encapsulate shared logic between init…
Aug 14, 2025
7a0b17f
refactored TemplateManager based on shared logic between init + test
Aug 15, 2025
9b51068
added end-to-end test for testing initializing a package from local t…
Aug 22, 2025
341a21f
reducing PR size
Aug 26, 2025
1141335
Merge pull request #46 from jbute/my-update
Aug 26, 2025
d84681c
added test coverage to showExecutables to make sure template does not…
Aug 26, 2025
501a138
added more tests, updated showtemplates test
Aug 26, 2025
f5e679d
added more test coverage
Aug 27, 2025
02c1035
added observability scope to templatepathresolver + ssh error message…
Aug 27, 2025
6ed7455
solved bug where test templates would not work as current directory w…
Sep 2, 2025
c9b78be
fixed bug where answers to arguments of a specific argument branch we…
Sep 2, 2025
9e93966
added predefined arguments to testing, however will need to revisit t…
Sep 2, 2025
4d23cc6
added ability to test specific branches of decision tree, need to fle…
Sep 2, 2025
09fe473
changes to usability to resolve to latest registry version
Sep 3, 2025
cbbd104
enforcing templates to have a corresponding product and plugin
Sep 3, 2025
2725a17
error handling more gracefully, with reporting from observability scope
Sep 3, 2025
ca7ca51
fixed permissions to query for them only once during process + refact…
Sep 4, 2025
092d960
Fix for .when(traits:) condition not working for multiple traits (#9015)
bripeticca Aug 26, 2025
b6d0cdd
Fix: Generate tests for executable/tool with `--enable-swift-testing`…
JeffESchmitz Aug 27, 2025
c0e0948
Emit "Found unhandled resource" to observability scope
jakepetroules Aug 21, 2025
1ccfce4
[Commands] Adopt changes to package manifest refactoring actions
xedin Aug 26, 2025
7377429
adds traits to dependency output in show-dependencies --json and --te…
heckj Aug 27, 2025
181b1d6
Tests: Migrate 2 suites to Swift Testing (#9017)
bkhouri Sep 2, 2025
86091fa
Tests: Migrate BuildSystemDelegateTests to Swift Testing and augment …
bkhouri Sep 2, 2025
477f488
Stage in fix for toolsetRunner test (#9086)
owenv Sep 3, 2025
5fb029c
initial, simple SDK documentation (#9004)
heckj Sep 3, 2025
0dcdd8b
Traits docs (#9048)
heckj Sep 3, 2025
eba40bb
Add bootstrap option to install without building.
3405691582 Aug 20, 2025
e1e4a54
Bump the Swift version to 6.3 (#9028)
shahmishal Sep 4, 2025
5bc140a
Drop unknown platforms when generating PIF (#9021)
owenv Sep 4, 2025
a5587f0
Test: Add issue to test (#9084)
bkhouri Sep 4, 2025
4815f1c
Test: Migrate CFamilyTargetTests to Swift Testing and augment (#9014)
bkhouri Sep 8, 2025
395c545
Tests: Update helpers to support both test libraries (#9082)
bkhouri Sep 8, 2025
ea095de
Merge pull request #48 from jbute/update
Sep 9, 2025
0df40c4
refactored tests + added missing ones
Sep 10, 2025
287669b
refactored + fixed small implementation details + tests for make depe…
Sep 10, 2025
aecf801
rebasing changes
Sep 16, 2025
1116d9e
changed template running system to reflect @ParentCommand changes
Sep 17, 2025
b45f302
tests + revamped prompting systems
Sep 19, 2025
de89179
formatting
Sep 22, 2025
fa25b72
changes to reflect github comments
Sep 23, 2025
6681eb1
formatting + reverting unnecessary changes
Sep 23, 2025
91b8626
documentation
Sep 23, 2025
c62dba8
documentation for authoring, initializing from, and testing templates
Sep 24, 2025
2050d3f
documentation improvements
Sep 24, 2025
33281ef
fixed optional bug when prompting + added templates examples
Sep 30, 2025
7ef7d5e
fixed printing
Oct 1, 2025
529110b
Merge remote-tracking branch 'upstream/main'
Oct 1, 2025
254ed57
Merge branch 'main' of github.pie.apple.com:jbute/swift-pm-template
Oct 1, 2025
4ce0a04
fixed merge conflicts
Oct 1, 2025
44700b5
Merge pull request #51 from jbute/update
Oct 1, 2025
5ba1bf6
Merge branch 'main' into inbetween
Oct 1, 2025
b86aa40
bumped version number
Oct 1, 2025
44e038c
created command for templates + added commands for local and git
May 14, 2025
f72d1d3
initial push for templates in package.swift prototype
May 21, 2025
cf9fb4e
fixtures + cleanup
Jun 4, 2025
fce612d
deleting unnecessary fixtures
Jun 4, 2025
499d0cf
added new dependencies to handle addDependency functionality of templ…
Jun 4, 2025
9938b4a
build plan for building products and targets of type templates, will …
Jun 4, 2025
5a815c7
fulfilling cases for addproduct, will need to revisit to make sure ad…
Jun 4, 2025
36dfdfd
fulfilling cases for addtarget, will need to revisit to make sure add…
Jun 4, 2025
ac94217
show templates in a local package
Jun 4, 2025
9e4c4c9
fullfilling switch case for snippets
Jun 4, 2025
b5b9d11
registering the show-templates command and adding more to init
Jun 4, 2025
e7467bc
removing testing library options, to revisit and discuss
Jun 4, 2025
5377383
added context switcher for swiftcommandstate
Jun 4, 2025
6fd8d61
make templates recognizable by package.swift
Jun 4, 2025
95c01d7
dependency graph for swift targets and templates need to be revisited
Jun 5, 2025
47e61cb
diagnostics added for template targets + products, will need to add t…
Jun 5, 2025
65b41d1
manifest loading and json parsing
Jun 5, 2025
f724815
templates directory check added, as template executables should not b…
Jun 5, 2025
5c04058
added templates as a type of module, will need to revisit to edit beh…
Jun 5, 2025
29d3c0f
added templates as a type of module, will need to revisit to edit beh…
Jun 5, 2025
d509aa6
changed tools version when generating a new project, will need to rev…
Jun 5, 2025
cd8b0e2
target and product descriptions syntax
Jun 5, 2025
7d4f7d3
build parameters for templates, will need to revisit
Jun 5, 2025
6051b89
plugins support for executing templates
Jun 5, 2025
ae81422
buildsupport for templates, will need to revisit
Jun 5, 2025
2afc49f
template creation workhorse
Jun 5, 2025
adea001
build support for xcbuild
Jun 5, 2025
d7b0b52
reverting plugin test to normal
Jun 5, 2025
d151584
printing out --experimental-dump-help
Jun 5, 2025
0434d0a
capturing --experimental-dump-help and parsing it
Jun 5, 2025
13b12a5
fixtures update
Jun 7, 2025
e8bdd7e
Updating package.swift to include Argumnetparser dependency for works…
Jun 7, 2025
cba59e7
argument parsing dump-help
Jun 7, 2025
0164605
Move new package description API to the array types and update versio…
cmcgee1024 Jun 5, 2025
87b5ee2
Use in-process API to run experimental dump help and decode JSON
cmcgee1024 Jun 6, 2025
9057789
Fix show-executables subcommand so that it does not show templates
cmcgee1024 Jun 6, 2025
971b8ab
running the executable
Jun 9, 2025
dac93fa
fixed syntax issues + added functionality for arguments with enums
Jun 9, 2025
e9bcb68
formatting + starting to add git capabilities
Jun 10, 2025
3ffbb68
git support + dependency mapping based on type
Jun 11, 2025
7f5822d
Remove template target and product types and use the template init op…
cmcgee1024 Jun 10, 2025
5cff0a7
Match whitespace and formatting to original main branch
cmcgee1024 Jun 10, 2025
9023ff6
added requirements + ability to checkout a branch without creating ne…
Jun 11, 2025
0d10aa9
added git functionality to show-templates
Jun 11, 2025
22b18b2
refactoring and organizing code
Jun 11, 2025
5d047f2
organizing code to differentiate between initializing regular package…
Jun 11, 2025
3d0772a
added documentation + reorganized show-templates code
Jun 11, 2025
9fd9e05
changed naming from template types (git, local, registry) to template…
Jun 11, 2025
5604cd4
generating templates from package registry
Jun 12, 2025
2ee1882
added registry support for show-templates
Jun 12, 2025
75db87f
formatting + documentation + quality
Jun 12, 2025
4410256
Make the template option optional when initializing with a template
cmcgee1024 Jun 13, 2025
56057e5
On failure due to multiple available templates provide the list as pa…
cmcgee1024 Jun 13, 2025
37c2785
Add instructions to the SwiftPM readme for trying out templates
cmcgee1024 Jun 13, 2025
5ac1b34
ergonomics, reducing repetition of template keyword
Jun 16, 2025
8e83a4a
added documentation + predetermined args
Jun 17, 2025
5f0a02b
changed args option to instead take any arguments after as predetermi…
Jun 17, 2025
4e818cf
inferring source of template
Jun 17, 2025
78c25c4
fixing error regarding passing args to template
Jun 18, 2025
9f00ac5
args checking + file existing checks if local template option picked
Jun 18, 2025
b7ce8a3
made description, permissions, and initial type top level
Jun 20, 2025
443ccb3
made scaffolding top level command
Jun 24, 2025
d298d1b
added ability to view description of templates to show-templates
Jun 24, 2025
c35b5c1
new command swift package scaffold
Jun 24, 2025
cf65c84
added more clarity to .template parameter initialType
Jun 24, 2025
2d1d4be
registry stuff, might revert later, but for now we can keep
Jul 8, 2025
367c708
added back to init templates
Jul 8, 2025
017423b
prompting improvements
Jul 15, 2025
b083948
added validate package, first-class testing support, temporary packages
Jul 22, 2025
2e66044
added testing logs + revamped testing system for templates
Jul 23, 2025
175e335
reverted package-metadata changes
Jul 23, 2025
63cb48c
fixed dummyRepositorymanager to conform to protocol
Jul 23, 2025
93a19b2
possibility to edit format of test result to json too
Jul 23, 2025
a7176f5
bug fix where subcommand was prompted for when there was no valid sub…
Jul 23, 2025
8f7b535
run package clean after generating package
Aug 6, 2025
2ffd1ce
refactoring
Aug 8, 2025
a29d930
refactoring + error handling
Aug 13, 2025
25d2510
refactoring templates + fixing bug where git and template id was not …
Aug 13, 2025
3019c8a
refactoring test template + changed structure holding prompting answers
Aug 14, 2025
5b71568
refactored directory manager to encapsulate shared logic between init…
Aug 14, 2025
4423fd7
refactored TemplateManager based on shared logic between init + test
Aug 15, 2025
9ffc964
added end-to-end test for testing initializing a package from local t…
Aug 22, 2025
a4bdf01
reducing PR size
Aug 26, 2025
c332a31
added test coverage to showExecutables to make sure template does not…
Aug 26, 2025
9df9938
added more tests, updated showtemplates test
Aug 26, 2025
910a29f
added more test coverage
Aug 27, 2025
fce6acf
added observability scope to templatepathresolver + ssh error message…
Aug 27, 2025
63ee710
solved bug where test templates would not work as current directory w…
Sep 2, 2025
ffbf2a7
fixed bug where answers to arguments of a specific argument branch we…
Sep 2, 2025
961494f
added predefined arguments to testing, however will need to revisit t…
Sep 2, 2025
33d3aa6
added ability to test specific branches of decision tree, need to fle…
Sep 2, 2025
9b8535c
changes to usability to resolve to latest registry version
Sep 3, 2025
ef80b31
enforcing templates to have a corresponding product and plugin
Sep 3, 2025
5439544
error handling more gracefully, with reporting from observability scope
Sep 3, 2025
b59119a
fixed permissions to query for them only once during process + refact…
Sep 4, 2025
1d3be45
merged with internal repo due to missing commits
Oct 2, 2025
8ca8d8f
reverted swift-version
Oct 2, 2025
c807367
reducing PR size by getting rid of unwanted changes
Oct 2, 2025
9b37c4e
reducing PR
Oct 2, 2025
c3003f5
removed source conflicts in fixtures
Oct 2, 2025
94dc8d0
formatting
Oct 2, 2025
3d5ebdb
removed redeclarations mistake during merge
Oct 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
496 changes: 496 additions & 0 deletions Documentation/Templates.md

Large diffs are not rendered by default.

74 changes: 74 additions & 0 deletions Documentation/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* [Creating a Library Package](#creating-a-library-package)
* [Creating an Executable Package](#creating-an-executable-package)
* [Creating a Macro Package](#creating-a-macro-package)
* [Creating a Package based on a custom user-defined template](#creating-a-package-based-on-a-custom-user-defined-template)
* [Defining Dependencies](#defining-dependencies)
* [Publishing a Package](#publishing-a-package)
* [Requiring System Libraries](#requiring-system-libraries)
Expand Down Expand Up @@ -88,6 +89,79 @@ Evolution proposal for [Expression Macros](https://github.com/swiftlang/swift-ev
and the WWDC [Write Swift macros](https://developer.apple.com/videos/play/wwdc2023/10166)
video. See further documentation on macros in [The Swift Programming Language](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/) book.


### Creating a Package based on a custom user-defined template

SwiftPM can create packages based on custom user-defined templates distributed as Swift packages. These templates can be obtained from local directories, Git repositories, or package registries, and provide interactive configuration through command-line arguments.
To create a package from a custom template, use the `swift package init` command with the `--type` option along with a template source:

```bash
# From a package registry
$ swift package init --type MyTemplate --package-id author.template-example

# From a Git repository
$ swift package init --type MyTemplate --url https://github.com/author/template-example

# From a local directory
$ swift package init --type MyTemplate --path /path/to/template
```

The template will prompt you for configuration options during initialization:

```bash
$ swift package init --type ServerTemplate --package-id example.server-templates
Building template package...
Build of product 'ServerTemplate' complete! (3.2s)

Add a README.md file with an introduction and tour of the code: [y/N] y

Choose from the following:

• Name: crud
About: Generate CRUD server with database support
• Name: bare
About: Generate a minimal server

Type the name of the option:
crud

Pick a database system for data storage. [sqlite3, postgresql] (default: sqlite3):
postgresql

Building for debugging...
Build of product 'ServerTemplate' complete! (1.1s)
```

Templates support the same versioning options as regular Swift package dependencies:

```bash
# Specific version
$ swift package init --type MyTemplate --package-id author.template --exact 1.2.0

# Version range
$ swift package init --type MyTemplate --package-id author.template --from 1.0.0

# Specific branch
$ swift package init --type MyTemplate --url https://github.com/author/template --branch main

# Specific revision
$ swift package init --type MyTemplate --url https://github.com/author/template --revision abc123
```

You can provide template arguments directly to skip interactive prompts:

```bash
$ swift package init --type ServerTemplate --package-id example.server-templates crud --database postgresql --readme true
```

Use the `--build-package` flag to automatically build and validate the generated package:

```bash
$ swift package init --type MyTemplate --package-id author.template --build-package
```

This ensures your template generates valid, buildable Swift packages.

## Defining Dependencies

To depend on a package, define the dependency and the version in the manifest of
Expand Down
69 changes: 69 additions & 0 deletions Examples/init-templates/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// swift-tools-version:6.3.0
import PackageDescription

let testTargets: [Target] = [.testTarget(
name: "ServerTemplateTests",
dependencies: [
"ServerTemplate",
]
)]

let package = Package(
name: "SimpleTemplateExample",
products:
.template(name: "PartsService") +
.template(name: "Template1") +
.template(name: "Template2") +
.template(name: "ServerTemplate"),
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", branch: "main"),
.package(url: "https://github.com/apple/swift-system.git", from: "1.4.2"),
.package(url: "https://github.com/stencilproject/Stencil.git", from: "0.15.1"),
],
targets: testTargets + .template(
name: "PartsService",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SystemPackage", package: "swift-system"),
],

initialPackageType: .executable,
description: "This template generates a simple parts management service using Hummingbird, and Fluent!"

) + .template(
name: "Template1",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SystemPackage", package: "swift-system"),
],

initialPackageType: .executable,
templatePermissions: [
.allowNetworkConnections(scope: .none, reason: "Need network access to help generate a template"),
],
description: "This is a simple template that uses Swift string interpolation."

) + .template(
name: "Template2",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SystemPackage", package: "swift-system"),
.product(name: "Stencil", package: "Stencil"),

],
resources: [
.process("StencilTemplates"),
],
initialPackageType: .executable,
description: "This is a template that uses Stencil templating."

) + .template(
name: "ServerTemplate",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SystemPackage", package: "swift-system"),
],
initialPackageType: .executable,
description: "A set of starter Swift Server projects."
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation

import PackagePlugin

/// plugin that will kickstart the template executable
@main
struct PartsServiceTemplatePlugin: CommandPlugin {
func performCommand(
context: PluginContext,
arguments: [String]
) async throws {
let tool = try context.tool(named: "PartsService")
let packageDirectory = context.package.directoryURL.path
let packageName = context.package.displayName

let process = Process()

process.executableURL = URL(filePath: tool.url.path())
process.arguments = ["--pkg-dir", packageDirectory, "--name", packageName] + arguments.filter { $0 != "--" }

try process.run()
process.waitUntilExit()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Foundation

import PackagePlugin

/// plugin that will kickstart the template executable
@main
struct ServerTemplatePlugin: CommandPlugin {
func performCommand(
context: PluginContext,
arguments: [String]
) async throws {
let tool = try context.tool(named: "ServerTemplate")
let packageDirectory = context.package.directoryURL.path

let process = Process()

let stderrPipe = Pipe()

process.executableURL = URL(filePath: tool.url.path())
process.arguments = ["--pkg-dir", packageDirectory] + arguments.filter { $0 != "--" }
process.standardError = stderrPipe

try process.run()
process.waitUntilExit()

let stderrData = stderrPipe.fileHandleForReading.readDataToEndOfFile()
let stderrOutput = String(data: stderrData, encoding: .utf8) ?? ""

if process.terminationStatus != 0 {
throw PluginError.executionFailed(code: process.terminationStatus, stderrOutput: stderrOutput)
}
}

enum PluginError: Error, CustomStringConvertible {
case executionFailed(code: Int32, stderrOutput: String)

var description: String {
switch self {
case .executionFailed(let code, let stderrOutput):
"""

Plugin subprocess failed with exit code \(code).

Output:
\(stderrOutput)

"""
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// plugin.swift
// TemplateWorkflow
//
// Created by John Bute on 2025-04-14.
//
import Foundation

import PackagePlugin

/// plugin that will kickstart the template executable
@main
struct TemplatePlugin: CommandPlugin {
func performCommand(
context: PluginContext,
arguments: [String]
) async throws {
let tool = try context.tool(named: "Template1")
let packageDirectory = context.package.directoryURL.path
let process = Process()
let stderrPipe = Pipe()

process.executableURL = URL(filePath: tool.url.path())
process.arguments = ["--pkg-dir", packageDirectory] + arguments.filter { $0 != "--" }
process.standardError = stderrPipe

try process.run()
process.waitUntilExit()
let stderrData = stderrPipe.fileHandleForReading.readDataToEndOfFile()
let stderrOutput = String(data: stderrData, encoding: .utf8) ?? ""

if process.terminationStatus != 0 {
throw PluginError.executionFailed(code: process.terminationStatus, stderrOutput: stderrOutput)
}
}

enum PluginError: Error, CustomStringConvertible {
case executionFailed(code: Int32, stderrOutput: String)

var description: String {
switch self {
case .executionFailed(let code, let stderrOutput):
"""

Plugin subprocess failed with exit code \(code).

Output:
\(stderrOutput)

"""
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// Template2Plugin.swift
// TemplateWorkflow
//
// Created by John Bute on 2025-04-23.
//

//
// plugin.swift
// TemplateWorkflow
//
// Created by John Bute on 2025-04-14.
//
import Foundation

import PackagePlugin

/// plugin that will kickstart the template executable
@main
struct DeclarativeTemplatePlugin: CommandPlugin {
func performCommand(
context: PluginContext,
arguments: [String]
) async throws {
let tool = try context.tool(named: "Template2")
let process = Process()

process.executableURL = URL(filePath: tool.url.path())
process.arguments = arguments.filter { $0 != "--" }

try process.run()
process.waitUntilExit()
}
}
21 changes: 21 additions & 0 deletions Examples/init-templates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Swift package templating example

---

This template project is a simple example of how a template author can create a template and generate a swift projects, utilizing the `swift package init` capability in swift package manager (to come).

## Parts Service

The parts service template can generate a REST service using Hummingbird (app server), and Fluent (ORM) with configurable database management system (SQLite3, and PostgreSQL). There are various switches to customize your project.

Invoke the parts service generator like this:

```
swift run parts-service --pkg-dir <new_package_dir>
```

You can find the additional information and parameters by invoking the help:

```
swift run parts-service --help
```
Loading