Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
213 changes: 213 additions & 0 deletions _data/new-data/get-started/command-line-tools/code-box-with-tabs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
pre-code-text: In addition to detailed help screens and error messages out of the box, your ArgumentParser CLI tools can provide completion scripts and man pages, as well as extensibility through a JSON rendering of the interface.
headline: ArgumentParser in use
tabs:
- label: CLI usage
code: |-
$ repeat yes --count 3
yes
yes
yes

$ repeat --count
Error: Missing value for '--count <count>'
Help: --count <count> The number of times to repeat 'phrase'.
Usage: repeat <phrase> [--count <count>]
See 'repeat --help' for more information.

$ repeat -h
USAGE: repeat <phrase> [--count <count>]

ARGUMENTS:
<phrase> The phrase to repeat.

OPTIONS:
--count <count> The number of times to repeat 'phrase'.
-h, --help Show help information.'
- label: Man page
code: |-
.\" "Generated by swift-argument-parser"
.Dd May 21, 2025
.Dt REPEAT 1
.Os
.Sh NAME
.Nm repeat
.Sh SYNOPSIS
.Nm
.Ar subcommand
.Ar phrase
.Op Fl -count Ar count
.Op Fl -help
.Sh DESCRIPTION
.Bl -tag -width 6n
.It Ar phrase
The phrase to repeat.
.It Fl -count Ar count
The number of times to repeat 'phrase'.
.It Fl h , -help
Show help information.
.It Em help
Show subcommand help information.
.Bl -tag -width 6n
.It Ar subcommands...
.El
.El
.Sh "EXIT STATUS"
.Ex -std
- label: Completion script
code: |-
#compdef repeat

__repeat_complete() {
local -ar non_empty_completions=("${@:#(|:*)}")
local -ar empty_completions=("${(M)@:#(|:*)}")
_describe -V '' non_empty_completions -- empty_completions -P $'\'\''
}

__repeat_custom_complete() {
local -a completions
completions=("${(@f)"$("${command_name}" "${@}" "${command_line[@]}")"}")
if [[ "${#completions[@]}" -gt 1 ]]; then
__repeat_complete "${completions[@]:0:-1}"
fi
}

__repeat_cursor_index_in_current_word() {
if [[ -z "${QIPREFIX}${IPREFIX}${PREFIX}" ]]; then
printf 0
else
printf %s "${#${(z)LBUFFER}[-1]}"
fi
}

_repeat() {
emulate -RL zsh -G
setopt extendedglob nullglob numericglobsort
unsetopt aliases banghist

local -xr SAP_SHELL=zsh
local -x SAP_SHELL_VERSION
SAP_SHELL_VERSION="$(builtin emulate zsh -c 'printf %s "${ZSH_VERSION}"')"
local -r SAP_SHELL_VERSION

local context state state_descr line
local -A opt_args

local -r command_name="${words[1]}"
local -ar command_line=("${words[@]}")
local -ir current_word_index="$((CURRENT - 1))"

local -i ret=1
local -ar arg_specs=(
':phrase:'
'--count[The number of times to repeat '\''phrase'\''.]:count:'
'(-h --help)'{-h,--help}'[Show help information.]'
)
_arguments -w -s -S : "${arg_specs[@]}" && ret=0

return "${ret}"
}

_repeat
- label: JSON output
code: |-
{
"command" : {
"arguments" : [
{
"abstract" : "The phrase to repeat.",
"isOptional" : false,
"isRepeating" : false,
"kind" : "positional",
"shouldDisplay" : true,
"valueName" : "phrase"
},
{
"abstract" : "The number of times to repeat 'phrase'.",
"isOptional" : true,
"isRepeating" : false,
"kind" : "option",
"names" : [
{
"kind" : "long",
"name" : "count"
}
],
"preferredName" : {
"kind" : "long",
"name" : "count"
},
"shouldDisplay" : true,
"valueName" : "count"
},
{
"abstract" : "Show help information.",
"isOptional" : true,
"isRepeating" : false,
"kind" : "flag",
"names" : [
{
"kind" : "short",
"name" : "h"
},
{
"kind" : "long",
"name" : "help"
}
],
"preferredName" : {
"kind" : "long",
"name" : "help"
},
"shouldDisplay" : true,
"valueName" : "help"
}
],
"commandName" : "repeat",
"shouldDisplay" : true,
"subcommands" : [
{
"abstract" : "Show subcommand help information.",
"arguments" : [
{
"isOptional" : true,
"isRepeating" : true,
"kind" : "positional",
"shouldDisplay" : true,
"valueName" : "subcommands"
},
{
"isOptional" : true,
"isRepeating" : false,
"kind" : "flag",
"names" : [
{
"kind" : "short",
"name" : "h"
},
{
"kind" : "long",
"name" : "help"
},
{
"kind" : "longWithSingleDash",
"name" : "help"
}
],
"preferredName" : {
"kind" : "long",
"name" : "help"
},
"shouldDisplay" : false,
"valueName" : "help"
}
],
"commandName" : "help",
"shouldDisplay" : true,
"superCommands" : [
"repeat"
]
}
]
},
"serializationVersion" : 0
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
headline: Build straightforward CLI tools with Argument Parser
paragraphs:
- 'You can quickly build full-featured command-line interfaces using the Swift Argument Parser library. Define commands by creating types with regular Swift properties. Link multiple commands to create rich command hierarchies.'
- 'ArgumentParser provides a detailed help screen, clear error messages with near-miss checking, broad customization, and more.'
link:
text: Swift Argument Parser
url: https://github.com/apple/swift-argument-parser
code: |-
import ArgumentParser
@main
struct Repeat: ParsableCommand {
@Argument(help: "The phrase to repeat.")
var phrase: String

@Option(help: "The number of times to repeat 'phrase'.")
var count: Int? = nil

mutating func run() throws {
let repeatCount = count ?? .max

for i in 1...repeatCount {
print(phrase)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
headline: Handle process execution robustly with minimal boilerplate
headline: Use Subprocess to handle process execution
paragraphs:
- 'Subprocess is a Swift library that provides precise, idiomatic control over launching and managing child processes. You can either collect the child process output asynchronously in full, or stream it in real time using AsyncSequence, making it easy to process output line-by-line as it arrives.'
- 'Subprocess gives you fine-grained control over environment variables, arguments, and many platform specific parameters, while embracing Swift’s concurrency features and type safety. Whether you’re building CLI tools or server-side Swift applications, swift-subprocess integrates cleanly.'
Expand Down
10 changes: 5 additions & 5 deletions _data/new-data/get-started/command-line-tools/hero.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ link:
url: /getting-started/cli-swiftpm/
text: Get Started
boxes:
- title: Quickly get started
text: Many common command line features are auto-generated using the Swift Argument Parser package, including help commands and completion scripts.
- title: Inherit Swift’s strengths
text: Swift's speed and safety make it a great choice for building command line tools.
- title: Simplified setup
text: Auto-generate common command line features like help commands and completion scripts using the Swift Argument Parser package.
- title: Language strengths
text: Swift is fast, memory safe, and has robust string handling, making it a great choice for building command line tools.
- title: Interoperable
text: Swift’s interoperability enables you to use or wrap existing libraries in other languages within your CLI tools.
text: Integrate and reuse existing libraries written in other languages like C and C++ by taking advantage of Swift's interoperability.
52 changes: 23 additions & 29 deletions _includes/new-includes/components/code-box.html
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
<div
class="code-box content-wrapper {% if include.with-tabs %}code-box-with-tabs{% endif %}"
>
<div class="content-body">
<h2>{{include.content.headline}}</h2>
{% if include.content.pre-code-text %}
<p class="body-copy">{{include.content.pre-code-text}}</p>
{% endif %}
{% if include.content.tabs %}
<nav>
<ul class="code-box-tabs">
{% for tab in include.content.tabs %}
<li class="body-copy{% if forloop.first %} active{% endif %}">
<button data-tab-index="{{forloop.index0}}">{{tab.label}}</button>
</li>
{% endfor %}
</ul>
</nav>
{% for tab in include.content.tabs %}
<pre
data-tab-index="{{forloop.index0}}"
class="{% if forloop.first %}active{% endif %}"
><code>{{tab.code}}</code></pre>
{% endfor %} {% else %}
{% if include.content.code %}
<pre><code>{{include.content.code}}</code></pre>
{% endif %}
{% endif %} {% if include.content.after-code-text %}
<p class="body-copy">{{include.content.after-code-text}}</p>
{% endif %}
</div>
{% if include.content.links %}
<h2>{{include.content.headline}}</h2>
{% if include.content.pre-code-text %}
<p class="body-copy">{{include.content.pre-code-text}}</p>
{% endif %} {% if include.content.tabs %}
<nav>
<ul class="code-box-tabs">
{% for tab in include.content.tabs %}
<li class="body-copy{% if forloop.first %} active{% endif %}">
<button data-tab-index="{{forloop.index0}}">{{tab.label}}</button>
</li>
{% endfor %}
</ul>
</nav>
{% for tab in include.content.tabs %}
<pre
data-tab-index="{{forloop.index0}}"
class="{% if forloop.first %}active{% endif %}"
><code>{{tab.code | escape}}</code></pre>
{% endfor %} {% else %} {% if include.content.code %}
<pre><code>{{include.content.code | escape}}</code></pre>
{% endif %} {% endif %} {% if include.content.after-code-text %}
<p class="body-copy">{{include.content.after-code-text}}</p>
{% endif %}{% if include.content.links %}
<div class="link-wrapper">
{% for link in include.content.links %}
<a class="body-copy" href="{{ link.href }}"> {{ link.copy }} <i></i> </a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
<h2>{{ include.content.headline }}</h2>
{% for paragraph in include.content.paragraphs %}
<p class="body-copy">{{paragraph}}</p>
{% endfor %}
{% endfor %} {% if include.content.link %}
<a class="body-copy" href="{{ include.content.link.url }}"
>{{ include.content.link.text }} <i></i
></a>
{% endif %}
</div>
<!-- prettier-ignore -->
<div class="code body-copy" markdown="1">
Expand Down
Binary file modified assets/images/noise.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion assets/javascripts/new-javascripts/hero.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const heroAnimation = async () => {
const DURATION = 1000

const tl = anime.createTimeline({
defaults: { duration: DURATION, ease: 'out(.8)' },
defaults: { duration: DURATION, ease: 'inOut(.8)' },
})

tl.label('start', 0)
Expand Down
18 changes: 17 additions & 1 deletion assets/stylesheets/new-stylesheets/pages/_get-started.scss
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,17 @@
flex-direction: column;
align-items: flex-start;
text-align: left;
padding: 37px 111px 41px 49px;
padding: 37px 50px 41px 50px;
margin-bottom: 70px;
box-sizing: border-box;
border-radius: 22px;

pre {
max-height: 400px;
}

&.code-box-with-tabs {
overflow: hidden;
pre {
display: none;

Expand All @@ -397,6 +402,7 @@
&-tabs {
margin-bottom: 20px;
padding-left: 0 !important;

button {
outline: none;
border: none;
Expand Down Expand Up @@ -469,6 +475,16 @@
a {
@include link-with-right-arrow;
}

@media only screen and (max-width: 768px) {
nav {
ul {
white-space: nowrap;
width: calc(100% - 59px);
overflow: scroll;
}
}
}
}

.headline-section {
Expand Down
Loading
Loading