mirror of
https://github.com/spectreconsole/spectre.console.git
synced 2025-10-25 15:19:23 +00:00
Compare commits
207 Commits
0.48.0
...
9f622f3123
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f622f3123 | ||
|
|
e51812237e | ||
|
|
749f0fded8 | ||
|
|
f5f61ca610 | ||
|
|
d90e94dbb3 | ||
|
|
169abca986 | ||
|
|
3c2156268c | ||
|
|
6fb81103f0 | ||
|
|
880e83b27c | ||
|
|
0b270e1ccd | ||
|
|
2d9e8069fd | ||
|
|
b551bbd244 | ||
|
|
3a70fbec75 | ||
|
|
c67b3df3ba | ||
|
|
8e474f514c | ||
|
|
097f740bbd | ||
|
|
ba7299adcf | ||
|
|
d84f9ae713 | ||
|
|
3a6d3e4520 | ||
|
|
a8b2f1f1e0 | ||
|
|
0889c2f97c | ||
|
|
f4782d9916 | ||
|
|
8b59ddfd41 | ||
|
|
6ad814cab0 | ||
|
|
f32f80dc57 | ||
|
|
7f3ebe02c4 | ||
|
|
d77bfb6391 | ||
|
|
7819f0693d | ||
|
|
465be9391b | ||
|
|
7e5ddb1efe | ||
|
|
aabe8eeaf8 | ||
|
|
108b23fca8 | ||
|
|
7051bc9e2d | ||
|
|
65bab890f2 | ||
|
|
bd0e2d3e22 | ||
|
|
9efc426eb9 | ||
|
|
2570202990 | ||
|
|
e4b5b56d93 | ||
|
|
67c3909bbb | ||
|
|
d836ad1805 | ||
|
|
57dd8ee410 | ||
|
|
6105ee2a86 | ||
|
|
b5c839030c | ||
|
|
b08ca1c4d7 | ||
|
|
68fcfe0de4 | ||
|
|
b0f82d787d | ||
|
|
1dabf25e1c | ||
|
|
958820dd66 | ||
|
|
c4a97f3c89 | ||
|
|
4ac88b5d3f | ||
|
|
c937c8800a | ||
|
|
349eac1e22 | ||
|
|
2f8a38f169 | ||
|
|
e9f9f56189 | ||
|
|
cefb51df7b | ||
|
|
75b3b83210 | ||
|
|
dfdd129dd0 | ||
|
|
17c7a4f7d6 | ||
|
|
520efe07e2 | ||
|
|
c81bc5fe1d | ||
|
|
edf7f23957 | ||
|
|
80a8b0e406 | ||
|
|
dca67da8cd | ||
|
|
78272e62e6 | ||
|
|
540fb0195f | ||
|
|
93668e92b6 | ||
|
|
11a320c7c9 | ||
|
|
c1eb94c1db | ||
|
|
9d8d3c1d6d | ||
|
|
7e1142df58 | ||
|
|
a6b96e9297 | ||
|
|
f1f633cc72 | ||
|
|
05ce33615e | ||
|
|
97715f2553 | ||
|
|
039553efbb | ||
|
|
f704f2a0e8 | ||
|
|
8c5264d117 | ||
|
|
58bf89a56a | ||
|
|
29ab313bb9 | ||
|
|
92daeb739d | ||
|
|
43e9669395 | ||
|
|
ab8384acf6 | ||
|
|
b2689be3ed | ||
|
|
835143d95f | ||
|
|
8f2a859087 | ||
|
|
2be8e8da4e | ||
|
|
2a8810affd | ||
|
|
e1d21e7e61 | ||
|
|
c7c3ebdf57 | ||
|
|
b67af32423 | ||
|
|
10773a5625 | ||
|
|
4802751357 | ||
|
|
4515d89705 | ||
|
|
be45494d6e | ||
|
|
69689d2ba1 | ||
|
|
aa9e5c48c6 | ||
|
|
8d06daf355 | ||
|
|
cecfdc386c | ||
|
|
375a708c43 | ||
|
|
574ead6d46 | ||
|
|
a87277e859 | ||
|
|
fdc03f2081 | ||
|
|
3eb620a44e | ||
|
|
bc88da8056 | ||
|
|
00b9aecb4f | ||
|
|
444dbed259 | ||
|
|
a32dc8030b | ||
|
|
75547b2436 | ||
|
|
22d1cbe01f | ||
|
|
7f8ed509bb | ||
|
|
c70a8b8fc5 | ||
|
|
b470af11f7 | ||
|
|
23b160a3f5 | ||
|
|
1345a6347a | ||
|
|
78f3f80b17 | ||
|
|
a55b80220d | ||
|
|
f8a4b2271d | ||
|
|
dba7ad0875 | ||
|
|
322ed2efbb | ||
|
|
156d254208 | ||
|
|
3437130bf0 | ||
|
|
32384f7b8d | ||
|
|
32361d3f15 | ||
|
|
b9d2d2df6d | ||
|
|
8e44a83737 | ||
|
|
fd69ad0b01 | ||
|
|
753894de94 | ||
|
|
dc2cb40b79 | ||
|
|
511f798f0f | ||
|
|
2081c0fd9a | ||
|
|
96512f353f | ||
|
|
56feea11a1 | ||
|
|
45c24055fa | ||
|
|
d56139756c | ||
|
|
7af1eedca7 | ||
|
|
6116af3844 | ||
|
|
2cc6c457ad | ||
|
|
f02b46107e | ||
|
|
42fd801876 | ||
|
|
bb72b44d60 | ||
|
|
d79e6adc5f | ||
|
|
64b9ef582d | ||
|
|
a19c84e25a | ||
|
|
b61fff042b | ||
|
|
ca441dbe7a | ||
|
|
f6bcf67cbe | ||
|
|
5c87d7fa04 | ||
|
|
0e2ed511a5 | ||
|
|
7b13148773 | ||
|
|
e5a6459c52 | ||
|
|
68b28b57f2 | ||
|
|
43b5ac99f9 | ||
|
|
b1b50a21f7 | ||
|
|
5d4b2c88e5 | ||
|
|
3acc90e47c | ||
|
|
88515b7d7f | ||
|
|
c5e11626b5 | ||
|
|
2ead177404 | ||
|
|
71f762f646 | ||
|
|
95bff47b85 | ||
|
|
de04619f88 | ||
|
|
ecdfdd4b85 | ||
|
|
a893a9601e | ||
|
|
d52d14e848 | ||
|
|
a62e79992b | ||
|
|
4f22f5b7c3 | ||
|
|
ff7282ecb8 | ||
|
|
eb38f76a6a | ||
|
|
20a2f727f7 | ||
|
|
fc0b553a4a | ||
|
|
1a3249cdae | ||
|
|
43f9ae92ad | ||
|
|
e66d3aab2e | ||
|
|
d921ac6f02 | ||
|
|
5acd83a3ef | ||
|
|
397b742bec | ||
|
|
d30b08201d | ||
|
|
8da05bcc17 | ||
|
|
badcd642ec | ||
|
|
fde9ee04cf | ||
|
|
b6e0b2389a | ||
|
|
3f5e8aabf5 | ||
|
|
ead874e6b2 | ||
|
|
e13410861d | ||
|
|
bf3b91a535 | ||
|
|
72704529c5 | ||
|
|
b21e07ea94 | ||
|
|
703d653ec5 | ||
|
|
71631b248a | ||
|
|
63c22575ea | ||
|
|
9cc888e5ad | ||
|
|
d5b4621233 | ||
|
|
cee97821d6 | ||
|
|
55c763a5c2 | ||
|
|
d03c10623c | ||
|
|
5a52c1f277 | ||
|
|
544e6a92df | ||
|
|
a94bc15746 | ||
|
|
e7ce6a69b7 | ||
|
|
7cf7e84dd8 | ||
|
|
6f1f29967d | ||
|
|
006da0f9ea | ||
|
|
c62f79eded | ||
|
|
1d19079913 | ||
|
|
44300c871f | ||
|
|
989c0b9904 | ||
|
|
cb52eb63ce |
@@ -8,7 +8,7 @@ indent_size = 4
|
|||||||
insert_final_newline = false
|
insert_final_newline = false
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[*.sln]
|
[*.{sln,slnx}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
[*.{csproj,vbproj,vcxproj,vcxproj.filters}]
|
[*.{csproj,vbproj,vcxproj,vcxproj.filters}]
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
# Use file scoped namespace declarations
|
# Use file scoped namespace declarations
|
||||||
7b2da0a4f63bf3ceab99d2c88535e74155f2b99c
|
7b2da0a4f63bf3ceab99d2c88535e74155f2b99c
|
||||||
|
|
||||||
|
# fix line-endings
|
||||||
|
e2ad4b1ea5555e701cda4fd400bb6592e318e1ff
|
||||||
|
|||||||
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
* text=auto
|
||||||
|
|
||||||
|
*.cs text eol=lf
|
||||||
|
*.md text eol=lf
|
||||||
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -26,3 +26,6 @@ If applicable, add screenshots to help explain your problem.
|
|||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
Add any other context about the problem here.
|
Add any other context about the problem here.
|
||||||
|
|
||||||
|
---
|
||||||
|
Please upvote :+1: this issue if you are interested in it.
|
||||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
3
.github/ISSUE_TEMPLATE/feature_request.md
vendored
3
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -18,3 +18,6 @@ A clear and concise description of any alternative solutions or features you've
|
|||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
Add any other context or screenshots about the feature request here.
|
Add any other context or screenshots about the feature request here.
|
||||||
|
|
||||||
|
---
|
||||||
|
Please upvote :+1: this issue if you are interested in it.
|
||||||
5
.github/pull_request_template.md
vendored
5
.github/pull_request_template.md
vendored
@@ -7,7 +7,7 @@ fixes #
|
|||||||
|
|
||||||
<!-- formalities. These are not optional. -->
|
<!-- formalities. These are not optional. -->
|
||||||
|
|
||||||
- [ ] I have read the [Contribution Guidelines](../CONTRIBUTING.md)
|
- [ ] I have read the [Contribution Guidelines](https://github.com/spectreconsole/spectre.console/blob/main/CONTRIBUTING.md)
|
||||||
- [ ] I have commented on the issue above and discussed the intended changes
|
- [ ] I have commented on the issue above and discussed the intended changes
|
||||||
- [ ] A maintainer has signed off on the changes and the issue was assigned to me
|
- [ ] A maintainer has signed off on the changes and the issue was assigned to me
|
||||||
- [ ] All newly added code is adequately covered by tests
|
- [ ] All newly added code is adequately covered by tests
|
||||||
@@ -17,3 +17,6 @@ fixes #
|
|||||||
## Changes
|
## Changes
|
||||||
|
|
||||||
<!-- describe the changes you made. -->
|
<!-- describe the changes you made. -->
|
||||||
|
|
||||||
|
---
|
||||||
|
Please upvote :+1: this pull request if you are interested in it.
|
||||||
63
.github/workflows/ci.yaml
vendored
63
.github/workflows/ci.yaml
vendored
@@ -8,48 +8,6 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
###################################################
|
|
||||||
# DOCS
|
|
||||||
###################################################
|
|
||||||
|
|
||||||
docs:
|
|
||||||
name: Documentation
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@master
|
|
||||||
|
|
||||||
- name: Setup .NET SDK
|
|
||||||
uses: actions/setup-dotnet@v3
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: '16'
|
|
||||||
|
|
||||||
- name: Cache dependencies
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: npm-${{ hashFiles('package-lock.json') }}
|
|
||||||
restore-keys: npm-
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
cd docs
|
|
||||||
dotnet tool restore
|
|
||||||
dotnet run --configuration Release
|
|
||||||
|
|
||||||
- name: Archive doc generation
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: documentation-output
|
|
||||||
path: docs/output/
|
|
||||||
retention-days: 5
|
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# BUILD
|
# BUILD
|
||||||
###################################################
|
###################################################
|
||||||
@@ -57,30 +15,19 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
name: Build
|
name: Build
|
||||||
if: "!contains(github.event.head_commit.message, 'skip-ci')"
|
if: "!contains(github.event.head_commit.message, 'skip-ci')"
|
||||||
strategy:
|
runs-on: ubuntu-latest
|
||||||
matrix:
|
|
||||||
kind: ['linux', 'windows', 'macOS']
|
|
||||||
include:
|
|
||||||
- kind: linux
|
|
||||||
os: ubuntu-latest
|
|
||||||
- kind: windows
|
|
||||||
os: windows-latest
|
|
||||||
- kind: macOS
|
|
||||||
os: macos-latest
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup .NET SDK
|
- name: Setup .NET SDK
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v5
|
||||||
with:
|
with:
|
||||||
dotnet-version: |
|
dotnet-version: |
|
||||||
6.0.x
|
|
||||||
7.0.x
|
|
||||||
8.0.x
|
8.0.x
|
||||||
|
9.0.x
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -90,7 +37,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Verify Test Results
|
- name: Upload Verify Test Results
|
||||||
if: failure()
|
if: failure()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: verify-test-results
|
name: verify-test-results
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
78
.github/workflows/publish.yaml
vendored
78
.github/workflows/publish.yaml
vendored
@@ -15,40 +15,33 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# BUILD
|
# PUBLISH
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build
|
name: Publish NuGet Packages
|
||||||
if: |
|
if: "!contains(github.event.head_commit.message, 'skip-ci') || startsWith(github.ref, 'refs/tags/')"
|
||||||
(!startsWith(github.event.head_commit.message, 'skip-ci')
|
runs-on: ubuntu-latest
|
||||||
&& !startsWith(github.event.head_commit.message, 'chore:'))
|
|
||||||
|| startsWith(github.ref, 'refs/tags/')
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
kind: ['linux', 'windows', 'macOS']
|
|
||||||
include:
|
|
||||||
- kind: linux
|
|
||||||
os: ubuntu-latest
|
|
||||||
- kind: windows
|
|
||||||
os: windows-latest
|
|
||||||
- kind: macOS
|
|
||||||
os: macos-latest
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup .NET SDK
|
- name: Setup .NET SDK
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v5
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
8.0.x
|
||||||
|
9.0.x
|
||||||
|
|
||||||
- name: Build
|
- name: Publish
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
dotnet tool restore
|
dotnet tool restore
|
||||||
dotnet cake
|
dotnet cake --target="publish" \
|
||||||
|
--nuget-key="${{secrets.NUGET_API_KEY}}" \
|
||||||
|
--github-key="${{secrets.GITHUB_TOKEN}}"
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# DOCS
|
# DOCS
|
||||||
@@ -60,20 +53,20 @@ jobs:
|
|||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup .NET SDK
|
- name: Setup .NET SDK
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v5
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v5
|
||||||
with:
|
with:
|
||||||
node-version: '16'
|
node-version: '22'
|
||||||
|
|
||||||
- name: Cache dependencies
|
- name: Cache dependencies
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.npm
|
path: ~/.npm
|
||||||
key: npm-${{ hashFiles('package-lock.json') }}
|
key: npm-${{ hashFiles('package-lock.json') }}
|
||||||
@@ -88,35 +81,4 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd docs
|
cd docs
|
||||||
dotnet tool restore
|
dotnet tool restore
|
||||||
dotnet run --configuration Release -- deploy
|
dotnet run --configuration Release -- deploy
|
||||||
|
|
||||||
###################################################
|
|
||||||
# PUBLISH
|
|
||||||
###################################################
|
|
||||||
|
|
||||||
publish:
|
|
||||||
name: Publish NuGet Packages
|
|
||||||
needs: [build]
|
|
||||||
if: "!contains(github.event.head_commit.message, 'skip-ci') || startsWith(github.ref, 'refs/tags/')"
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup .NET SDK
|
|
||||||
uses: actions/setup-dotnet@v3
|
|
||||||
with:
|
|
||||||
dotnet-version: |
|
|
||||||
6.0.x
|
|
||||||
7.0.x
|
|
||||||
8.0.x
|
|
||||||
|
|
||||||
- name: Publish
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
dotnet tool restore
|
|
||||||
dotnet cake --target="publish" \
|
|
||||||
--nuget-key="${{secrets.NUGET_API_KEY}}" \
|
|
||||||
--github-key="${{secrets.GITHUB_TOKEN}}"
|
|
||||||
24
.github/workflows/top-issues-dashboard.yml
vendored
Normal file
24
.github/workflows/top-issues-dashboard.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: Top issues action.
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 */1 * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ShowAndLabelTopIssues:
|
||||||
|
name: Display and label top issues.
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Top Issues action
|
||||||
|
uses: rickstaa/top-issues-action@v1.3.101
|
||||||
|
env:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
top_list_size: 10
|
||||||
|
label: true
|
||||||
|
dashboard: true
|
||||||
|
dashboard_show_total_reactions: true
|
||||||
|
top_issues: true
|
||||||
|
top_bugs: true
|
||||||
|
top_features: true
|
||||||
|
feature_label: feature
|
||||||
|
top_pull_requests: true
|
||||||
@@ -39,7 +39,7 @@ What is generally considered trivial:
|
|||||||
### Code style
|
### Code style
|
||||||
|
|
||||||
Normal .NET coding guidelines apply.
|
Normal .NET coding guidelines apply.
|
||||||
See the [Framework Design Guidelines](https://msdn.microsoft.com/en-us/library/ms229042%28v=vs.110%29.aspx) for more information.
|
See the [Framework Design Guidelines](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/) for more information.
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ Any new code should also have reasonable unit test coverage.
|
|||||||
information and a link back to the discussion.
|
information and a link back to the discussion.
|
||||||
* Once you get a nod from someone in the Spectre.Console Team, you can start on the feature.
|
* Once you get a nod from someone in the Spectre.Console Team, you can start on the feature.
|
||||||
* Alternatively, if a feature is on the issues list with the
|
* Alternatively, if a feature is on the issues list with the
|
||||||
[Up For Grabs](https://github.com/spectreconsole/spectre.console/labels/up-for-grabs) label,
|
[good first issue](https://github.com/spectreconsole/spectre.console/labels/good%20first%20issue) label,
|
||||||
it is open for a community member (contributor) to patch. You should comment that you are signing up for it on
|
it is open for a community member (contributor) to patch. You should comment that you are signing up for it on
|
||||||
the issue so someone else doesn't also sign up for the work.
|
the issue so someone else doesn't also sign up for the work.
|
||||||
|
|
||||||
@@ -158,4 +158,4 @@ Harder for us roughly translates to a longer SLA for your pull request.
|
|||||||
## Acknowledgement
|
## Acknowledgement
|
||||||
|
|
||||||
This contribution guide was taken from the [Chocolatey project](https://chocolatey.org/)
|
This contribution guide was taken from the [Chocolatey project](https://chocolatey.org/)
|
||||||
with permission and was edited to follow Spectre.Console's conventions and processes.
|
with permission and was edited to follow Spectre.Console's conventions and processes.
|
||||||
|
|||||||
23
README.fa.md
23
README.fa.md
@@ -44,30 +44,13 @@ https://spectreconsole.net/
|
|||||||
|
|
||||||
<h2 id="examples">مثالها</h2>
|
<h2 id="examples">مثالها</h2>
|
||||||
|
|
||||||
برای بررسی `Spectre.Console` در عمل، ابزار سراسری
|
To see `Spectre.Console` in action, please see the
|
||||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
|
[examples repository](https://github.com/spectreconsole/examples).
|
||||||
را نصب کنید.
|
|
||||||
|
|
||||||
<pre dir="ltr">
|
|
||||||
> dotnet tool restore
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
حالا شما میتوانید مثالهای موجود در این مخزن را لیست کنید:
|
|
||||||
|
|
||||||
<pre dir="ltr">
|
|
||||||
> dotnet example
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
و برای اجرای مثال:
|
|
||||||
|
|
||||||
<pre dir="ltr">
|
|
||||||
> dotnet example tables
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h2 id="license">مجوز</h2>
|
<h2 id="license">مجوز</h2>
|
||||||
|
|
||||||
<div dir="ltr">
|
<div dir="ltr">
|
||||||
Copyright © Patrik Svensson, Phil Scott
|
Copyright © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
همانطور که Spectre.Console تحت مجوز MIT ارائه شده است؛ برای کسب اطلاعات بیشتر به مجوز مراجعه کنید.
|
همانطور که Spectre.Console تحت مجوز MIT ارائه شده است؛ برای کسب اطلاعات بیشتر به مجوز مراجعه کنید.
|
||||||
|
|||||||
46
README.md
46
README.md
@@ -3,8 +3,7 @@
|
|||||||
_[](https://www.nuget.org/packages/spectre.console)_ _[](https://www.nuget.org/packages/spectre.console.cli)_ [](https://app.netlify.com/sites/spectreconsole/deploys)
|
_[](https://www.nuget.org/packages/spectre.console)_ _[](https://www.nuget.org/packages/spectre.console.cli)_ [](https://app.netlify.com/sites/spectreconsole/deploys)
|
||||||
|
|
||||||
A .NET library that makes it easier to create beautiful, cross platform, console applications.
|
A .NET library that makes it easier to create beautiful, cross platform, console applications.
|
||||||
It is heavily inspired by the excellent [Rich library](https://github.com/willmcgugan/rich)
|
It is heavily inspired by the excellent Python library, [Rich](https://github.com/willmcgugan/rich). Detailed instructions for using `Spectre.Console` are located on the project website, https://spectreconsole.net
|
||||||
for Python. For detailed usage instructions, [please refer to the documentation at https://spectreconsole.net/.](https://spectreconsole.net/)
|
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
@@ -19,18 +18,22 @@ for Python. For detailed usage instructions, [please refer to the documentation
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Written with unit testing in mind.
|
* Supports tables, grids, panels, and a [Rich](https://github.com/willmcgugan/rich) inspired markup language.
|
||||||
* Supports tables, grids, panels, and a [rich](https://github.com/willmcgugan/rich) inspired markup language.
|
|
||||||
* Supports the most common SRG parameters when it comes to text
|
* Supports the most common SRG parameters when it comes to text
|
||||||
styling such as bold, dim, italic, underline, strikethrough,
|
styling such as bold, dim, italic, underline, strikethrough,
|
||||||
and blinking text.
|
and blinking text.
|
||||||
* Supports 3/4/8/24-bit colors in the terminal.
|
* Supports 3/4/8/24-bit colors in the terminal.
|
||||||
The library will detect the capabilities of the current terminal
|
The library will detect the capabilities of the current terminal
|
||||||
and downgrade colors as needed.
|
and downgrade colors as needed.
|
||||||
|
* Written with unit testing in mind.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## Important Notices
|
||||||
|
|
||||||
|
> [!IMPORTANT]\
|
||||||
|
> We use the [Top Issues Dashboard](https://github.com/spectreconsole/spectre.console/issues/1517) for tracking community demand. Please upvote :+1: the issues and pull requests you are interested in.
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
The fastest way of getting started using `Spectre.Console` is to install the NuGet package.
|
The fastest way of getting started using `Spectre.Console` is to install the NuGet package.
|
||||||
@@ -42,34 +45,17 @@ dotnet add package Spectre.Console
|
|||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
The documentation for `Spectre.Console` can be found at
|
The documentation for `Spectre.Console` can be found at
|
||||||
https://spectreconsole.net/
|
https://spectreconsole.net
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
To see `Spectre.Console` in action, install the
|
To see `Spectre.Console` in action, please see the
|
||||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
|
[examples repository](https://github.com/spectreconsole/examples).
|
||||||
global tool.
|
|
||||||
|
|
||||||
```
|
|
||||||
> dotnet tool restore
|
|
||||||
```
|
|
||||||
|
|
||||||
Now you can list available examples in this repository:
|
|
||||||
|
|
||||||
```
|
|
||||||
> dotnet example
|
|
||||||
```
|
|
||||||
|
|
||||||
And to run an example:
|
|
||||||
|
|
||||||
```
|
|
||||||
> dotnet example tables
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sponsors
|
## Sponsors
|
||||||
|
|
||||||
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)
|
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)
|
||||||
Spectre.Console to show their support and to ensure the longevity of the project.
|
`Spectre.Console` to show their support and to ensure the longevity of the project.
|
||||||
|
|
||||||
* [Rodney Littles II](https://github.com/RLittlesII)
|
* [Rodney Littles II](https://github.com/RLittlesII)
|
||||||
* [Martin Björkström](https://github.com/bjorkstromm)
|
* [Martin Björkström](https://github.com/bjorkstromm)
|
||||||
@@ -97,8 +83,8 @@ This project is supported by the [.NET Foundation](https://dotnetfoundation.org)
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen
|
Copyright © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||||
|
|
||||||
Spectre.Console is provided as-is under the MIT license. For more information see LICENSE.
|
`Spectre.Console` is provided as-is under the MIT license. For more information see LICENSE.
|
||||||
|
|
||||||
* SixLabors.ImageSharp, a library which Spectre.Console relies upon, is licensed under Apache 2.0 when distributed as part of Spectre.Console. The Six Labors Split License covers all other usage, see: https://github.com/SixLabors/ImageSharp/blob/master/LICENSE
|
* SixLabors.ImageSharp, a library which `Spectre.Console` relies upon, is licensed under Apache 2.0 when distributed as part of `Spectre.Console`. The Six Labors Split License covers all other usage, see: https://github.com/SixLabors/ImageSharp/blob/master/LICENSE
|
||||||
|
|||||||
@@ -43,24 +43,8 @@ https://spectreconsole.net/
|
|||||||
|
|
||||||
## Exemplos
|
## Exemplos
|
||||||
|
|
||||||
Para ver o `Spectre.Console` em ação, instale a ferramenta global
|
To see `Spectre.Console` in action, please see the
|
||||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example).
|
[examples repository](https://github.com/spectreconsole/examples).
|
||||||
|
|
||||||
```
|
|
||||||
> dotnet tool restore
|
|
||||||
```
|
|
||||||
|
|
||||||
Agora você pode listar os exemplos disponíveis neste repositório:
|
|
||||||
|
|
||||||
```
|
|
||||||
> dotnet example
|
|
||||||
```
|
|
||||||
|
|
||||||
E para executar um exemplo:
|
|
||||||
|
|
||||||
```
|
|
||||||
> dotnet example tables
|
|
||||||
```
|
|
||||||
|
|
||||||
## Patrocinadores
|
## Patrocinadores
|
||||||
|
|
||||||
@@ -83,7 +67,7 @@ Eu estou muito agradecido.
|
|||||||
|
|
||||||
## Licença
|
## Licença
|
||||||
|
|
||||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen
|
Copyright © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||||
|
|
||||||
Spectre.Console é fornecido no estado em que se encontra sob a licença do MIT. Para obter mais informações, consulte o arquivo [LICENSE](LICENSE.md).
|
Spectre.Console é fornecido no estado em que se encontra sob a licença do MIT. Para obter mais informações, consulte o arquivo [LICENSE](LICENSE.md).
|
||||||
|
|
||||||
|
|||||||
21
README.zh.md
21
README.zh.md
@@ -39,23 +39,8 @@ https://spectreconsole.net/
|
|||||||
|
|
||||||
## 例子
|
## 例子
|
||||||
|
|
||||||
如果想直接运行`Spectre.Console`的例子,则需要安装[dotnet-example](https://github.com/patriksvensson/dotnet-example)工具。
|
To see `Spectre.Console` in action, please see the
|
||||||
|
[examples repository](https://github.com/spectreconsole/examples).
|
||||||
```
|
|
||||||
> dotnet tool restore
|
|
||||||
```
|
|
||||||
|
|
||||||
然后你可以列出仓库里的所有例子:
|
|
||||||
|
|
||||||
```
|
|
||||||
> dotnet example
|
|
||||||
```
|
|
||||||
|
|
||||||
跑一个看看效果:
|
|
||||||
|
|
||||||
```
|
|
||||||
> dotnet example tables
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sponsors
|
## Sponsors
|
||||||
|
|
||||||
@@ -77,7 +62,7 @@ https://spectreconsole.net/
|
|||||||
|
|
||||||
## 开源许可
|
## 开源许可
|
||||||
|
|
||||||
版权所有 © Patrik Svensson, Phil Scott, Nils Andresen
|
版权所有 © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||||
|
|
||||||
Spectre.Console 基于 MIT 协议提供。查看 LICENSE 文件了解更多信息。
|
Spectre.Console 基于 MIT 协议提供。查看 LICENSE 文件了解更多信息。
|
||||||
|
|
||||||
|
|||||||
68
build.cake
68
build.cake
@@ -12,10 +12,11 @@ Task("Clean")
|
|||||||
|
|
||||||
Task("Build")
|
Task("Build")
|
||||||
.IsDependentOn("Clean")
|
.IsDependentOn("Clean")
|
||||||
.Does(context =>
|
.Does(context =>
|
||||||
{
|
{
|
||||||
Information("Compiling generator...");
|
Information("Compiling generator...");
|
||||||
DotNetBuild("./resources/scripts/Generator/Generator.sln", new DotNetBuildSettings {
|
DotNetBuild("./resources/scripts/Generator/Generator.slnx", new DotNetBuildSettings
|
||||||
|
{
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
Verbosity = DotNetVerbosity.Minimal,
|
Verbosity = DotNetVerbosity.Minimal,
|
||||||
NoLogo = true,
|
NoLogo = true,
|
||||||
@@ -25,35 +26,8 @@ Task("Build")
|
|||||||
});
|
});
|
||||||
|
|
||||||
Information("\nCompiling Spectre.Console...");
|
Information("\nCompiling Spectre.Console...");
|
||||||
DotNetBuild("./src/Spectre.Console.sln", new DotNetBuildSettings {
|
DotNetBuild("./src/Spectre.Console.slnx", new DotNetBuildSettings
|
||||||
Configuration = configuration,
|
{
|
||||||
Verbosity = DotNetVerbosity.Minimal,
|
|
||||||
NoLogo = true,
|
|
||||||
NoIncremental = context.HasArgument("rebuild"),
|
|
||||||
MSBuildSettings = new DotNetMSBuildSettings()
|
|
||||||
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Task("Build-Analyzer")
|
|
||||||
.IsDependentOn("Build")
|
|
||||||
.Does(context =>
|
|
||||||
{
|
|
||||||
DotNetBuild("./src/Spectre.Console.Analyzer.sln", new DotNetBuildSettings {
|
|
||||||
Configuration = configuration,
|
|
||||||
Verbosity = DotNetVerbosity.Minimal,
|
|
||||||
NoLogo = true,
|
|
||||||
NoIncremental = context.HasArgument("rebuild"),
|
|
||||||
MSBuildSettings = new DotNetMSBuildSettings()
|
|
||||||
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Task("Build-Examples")
|
|
||||||
.IsDependentOn("Build")
|
|
||||||
.Does(context =>
|
|
||||||
{
|
|
||||||
DotNetBuild("./examples/Examples.sln", new DotNetBuildSettings {
|
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
Verbosity = DotNetVerbosity.Minimal,
|
Verbosity = DotNetVerbosity.Minimal,
|
||||||
NoLogo = true,
|
NoLogo = true,
|
||||||
@@ -65,11 +39,9 @@ Task("Build-Examples")
|
|||||||
|
|
||||||
Task("Test")
|
Task("Test")
|
||||||
.IsDependentOn("Build")
|
.IsDependentOn("Build")
|
||||||
.IsDependentOn("Build-Analyzer")
|
|
||||||
.IsDependentOn("Build-Examples")
|
|
||||||
.Does(context =>
|
.Does(context =>
|
||||||
{
|
{
|
||||||
DotNetTest("./test/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetTestSettings {
|
DotNetTest("./src/Tests/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetTestSettings {
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
Verbosity = DotNetVerbosity.Minimal,
|
Verbosity = DotNetVerbosity.Minimal,
|
||||||
NoLogo = true,
|
NoLogo = true,
|
||||||
@@ -77,15 +49,7 @@ Task("Test")
|
|||||||
NoBuild = true,
|
NoBuild = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
DotNetTest("./test/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj", new DotNetTestSettings {
|
DotNetTest("./src/Tests/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj", new DotNetTestSettings {
|
||||||
Configuration = configuration,
|
|
||||||
Verbosity = DotNetVerbosity.Minimal,
|
|
||||||
NoLogo = true,
|
|
||||||
NoRestore = true,
|
|
||||||
NoBuild = true,
|
|
||||||
});
|
|
||||||
|
|
||||||
DotNetTest("./test/Spectre.Console.Analyzer.Tests/Spectre.Console.Analyzer.Tests.csproj", new DotNetTestSettings {
|
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
Verbosity = DotNetVerbosity.Minimal,
|
Verbosity = DotNetVerbosity.Minimal,
|
||||||
NoLogo = true,
|
NoLogo = true,
|
||||||
@@ -96,20 +60,10 @@ Task("Test")
|
|||||||
|
|
||||||
Task("Package")
|
Task("Package")
|
||||||
.IsDependentOn("Test")
|
.IsDependentOn("Test")
|
||||||
.Does(context =>
|
.Does(context =>
|
||||||
{
|
{
|
||||||
context.DotNetPack($"./src/Spectre.Console.sln", new DotNetPackSettings {
|
context.DotNetPack($"./src/Spectre.Console.slnx", new DotNetPackSettings
|
||||||
Configuration = configuration,
|
{
|
||||||
Verbosity = DotNetVerbosity.Minimal,
|
|
||||||
NoLogo = true,
|
|
||||||
NoRestore = true,
|
|
||||||
NoBuild = true,
|
|
||||||
OutputDirectory = "./.artifacts",
|
|
||||||
MSBuildSettings = new DotNetMSBuildSettings()
|
|
||||||
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
|
||||||
});
|
|
||||||
|
|
||||||
context.DotNetPack($"./src/Spectre.Console.Analyzer.sln", new DotNetPackSettings {
|
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
Verbosity = DotNetVerbosity.Minimal,
|
Verbosity = DotNetVerbosity.Minimal,
|
||||||
NoLogo = true,
|
NoLogo = true,
|
||||||
@@ -155,4 +109,4 @@ Task("Default")
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Execution
|
// Execution
|
||||||
|
|
||||||
RunTarget(target)
|
RunTarget(target);
|
||||||
@@ -7,6 +7,11 @@
|
|||||||
<DefaultItemExcludes>$(DefaultItemExcludes);output\**;.gitignore</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);output\**;.gitignore</DefaultItemExcludes>
|
||||||
<NoWarn>MVC1000</NoWarn>
|
<NoWarn>MVC1000</NoWarn>
|
||||||
<MinVerSkip>true</MinVerSkip>
|
<MinVerSkip>true</MinVerSkip>
|
||||||
|
<!--
|
||||||
|
Disable NuGetAudit for now, there is an in progress PR with Statiq regarding these packages,
|
||||||
|
but since since this is just a generator we are safe to ignore this for now.
|
||||||
|
-->
|
||||||
|
<NuGetAudit>false</NuGetAudit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -33,13 +38,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Playwright" Version="1.19.0" />
|
<PackageReference Include="Microsoft.Playwright" Version="1.55.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
<PackageReference Include="Statiq.CodeAnalysis" Version="1.0.0-beta.58" />
|
<PackageReference Include="Statiq.CodeAnalysis" Version="1.0.0-beta.72" />
|
||||||
<PackageReference Include="Statiq.Common" Version="1.0.0-beta.58" />
|
<PackageReference Include="Statiq.Common" Version="1.0.0-beta.72" />
|
||||||
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.44" />
|
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.60" />
|
||||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.5.0" />
|
<PackageReference Include="MinVer" PrivateAssets="All" Version="6.0.0" />
|
||||||
<PackageReference Include="Statiq.Web.Netlify" Version="1.0.0-beta.44" />
|
<PackageReference Include="Statiq.Web.Netlify" Version="1.0.0-beta.60" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 16
|
|
||||||
VisualStudioVersion = 16.0.30011.22
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Docs", "Docs.csproj", "{C337F609-A890-4E52-BDA3-91658039B0E3}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{C337F609-A890-4E52-BDA3-91658039B0E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{C337F609-A890-4E52-BDA3-91658039B0E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{C337F609-A890-4E52-BDA3-91658039B0E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C337F609-A890-4E52-BDA3-91658039B0E3}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {2FB3922B-494A-45EB-A479-FC507B8E107C}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
3
docs/Docs.slnx
Normal file
3
docs/Docs.slnx
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<Solution>
|
||||||
|
<Project Path="Docs.csproj" />
|
||||||
|
</Solution>
|
||||||
155
docs/Program.cs
155
docs/Program.cs
@@ -1,77 +1,78 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Docs.Extensions;
|
using Docs.Extensions;
|
||||||
using Docs.Shortcodes;
|
using Docs.Shortcodes;
|
||||||
using Docs.Utilities;
|
using Docs.Utilities;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Statiq.App;
|
using Statiq.App;
|
||||||
using Statiq.Common;
|
using Statiq.Common;
|
||||||
using Statiq.Core;
|
using Statiq.Core;
|
||||||
using Statiq.Web;
|
using Statiq.Web;
|
||||||
|
|
||||||
namespace Docs
|
namespace Docs
|
||||||
{
|
{
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
public static async Task<int> Main(string[] args) =>
|
public static async Task<int> Main(string[] args) =>
|
||||||
await Bootstrapper.Factory
|
await Bootstrapper.Factory
|
||||||
.CreateWeb(args)
|
.CreateWeb(args)
|
||||||
.AddSetting(Keys.Host, "spectreconsole.net")
|
.AddSetting(Keys.Host, "spectreconsole.net")
|
||||||
.AddSetting(Keys.LinksUseHttps, true)
|
.AddSetting(Keys.LinksUseHttps, true)
|
||||||
.AddSetting(Constants.EditLink, ConfigureEditLink())
|
.AddSetting(Constants.EditLink, ConfigureEditLink())
|
||||||
.AddSetting(Constants.SourceFiles, new List<string>
|
.AddSetting(Constants.SourceFiles, new List<string>
|
||||||
{
|
{
|
||||||
"../../src/Spectre.Console/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
"../../src/Spectre.Console/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||||
"../../src/Spectre.Console.Cli/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
"../../src/Spectre.Console.Cli/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||||
"../../src/Spectre.Console.ImageSharp/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
"../../src/Spectre.Console.Testing/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||||
"../../src/Spectre.Console.Json/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs"
|
"../../src/Extensions/Spectre.Console.ImageSharp/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||||
})
|
"../../src/Extensions/Spectre.Console.Json/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs"
|
||||||
.AddSetting(Constants.ExampleSourceFiles, new List<string>
|
})
|
||||||
{
|
.AddSetting(Constants.ExampleSourceFiles, new List<string>
|
||||||
"../../examples/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
{
|
||||||
}
|
"../../examples/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||||
)
|
}
|
||||||
.ConfigureServices(i =>
|
)
|
||||||
{
|
.ConfigureServices(i =>
|
||||||
i.AddSingleton(new TypeNameLinks());
|
{
|
||||||
})
|
i.AddSingleton(new TypeNameLinks());
|
||||||
.ConfigureSite("spectreconsole", "spectre.console", "main")
|
})
|
||||||
.AddShortcode("Children", typeof(ChildrenShortcode))
|
.ConfigureSite("spectreconsole", "spectre.console", "main")
|
||||||
.AddShortcode("ColorTable", typeof(ColorTableShortcode))
|
.AddShortcode("Children", typeof(ChildrenShortcode))
|
||||||
.AddShortcode("EmojiTable", typeof(EmojiTableShortcode))
|
.AddShortcode("ColorTable", typeof(ColorTableShortcode))
|
||||||
.AddShortcode("Alert", typeof(AlertShortcode))
|
.AddShortcode("EmojiTable", typeof(EmojiTableShortcode))
|
||||||
.AddShortcode("Info", typeof(InfoShortcode))
|
.AddShortcode("Alert", typeof(AlertShortcode))
|
||||||
.AddShortcode("AsciiCast", typeof(AsciiCastShortcode))
|
.AddShortcode("Info", typeof(InfoShortcode))
|
||||||
.AddShortcode("Example", typeof(ExampleSnippet))
|
.AddShortcode("AsciiCast", typeof(AsciiCastShortcode))
|
||||||
.AddPipelines()
|
.AddShortcode("Example", typeof(ExampleSnippet))
|
||||||
.BuildPipeline(
|
.AddPipelines()
|
||||||
"Bootstrap",
|
.BuildPipeline(
|
||||||
builder => builder
|
"Bootstrap",
|
||||||
.WithInputReadFiles("../node_modules/asciinema-player/dist/bundle/asciinema-player.js")
|
builder => builder
|
||||||
.WithProcessModules(new SetDestination(Config.FromDocument(doc => new NormalizedPath($"./assets/{doc.Source.FileName}")), true))
|
.WithInputReadFiles("../node_modules/asciinema-player/dist/bundle/asciinema-player.js")
|
||||||
.WithOutputWriteFiles()
|
.WithProcessModules(new SetDestination(Config.FromDocument(doc => new NormalizedPath($"./assets/{doc.Source.FileName}")), true))
|
||||||
)
|
.WithOutputWriteFiles()
|
||||||
.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("npm", "install --audit false --fund false --progress false")
|
)
|
||||||
{
|
.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("npm", "install --audit false --fund false --progress false")
|
||||||
LogErrors = false
|
{
|
||||||
})
|
LogErrors = false
|
||||||
.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("dotnet", "playwright install chromium"))
|
})
|
||||||
.AddProcess(ProcessTiming.BeforeDeployment, _ => new ProcessLauncher("npm", "run build:tailwind")
|
.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("dotnet", "playwright install chromium"))
|
||||||
{
|
.AddProcess(ProcessTiming.BeforeDeployment, _ => new ProcessLauncher("npm", "run build:tailwind")
|
||||||
LogErrors = false
|
{
|
||||||
})
|
LogErrors = false
|
||||||
.RunAsync();
|
})
|
||||||
|
.RunAsync();
|
||||||
private static Config<string> ConfigureEditLink()
|
|
||||||
{
|
private static Config<string> ConfigureEditLink()
|
||||||
return Config.FromDocument((doc, ctx) =>
|
{
|
||||||
{
|
return Config.FromDocument((doc, ctx) =>
|
||||||
return string.Format("https://github.com/{0}/{1}/edit/{2}/docs/input/{3}",
|
{
|
||||||
ctx.GetString(Constants.Site.Owner),
|
return string.Format("https://github.com/{0}/{1}/edit/{2}/docs/input/{3}",
|
||||||
ctx.GetString(Constants.Site.Repository),
|
ctx.GetString(Constants.Site.Owner),
|
||||||
ctx.GetString(Constants.Site.Branch),
|
ctx.GetString(Constants.Site.Repository),
|
||||||
doc.Source.GetRelativeInputPath());
|
ctx.GetString(Constants.Site.Branch),
|
||||||
});
|
doc.Source.GetRelativeInputPath());
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"microsoft.playwright.cli": {
|
"microsoft.playwright.cli": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"commands": [
|
"commands": [
|
||||||
"playwright"
|
"playwright"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"sdk": {
|
|
||||||
"version": "8.0.100",
|
|
||||||
"rollForward": "latestFeature"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,7 +29,7 @@ Optional: Embed an asciicast. The cast parameter should be the base name of the
|
|||||||
one suffixed with -rich.cast and a second named -plain.cast. The cast attribute should be the name without
|
one suffixed with -rich.cast and a second named -plain.cast. The cast attribute should be the name without
|
||||||
the suffix.
|
the suffix.
|
||||||
|
|
||||||
To generate a new cast file, open the \resources\scripts\Generator\Generator.sln project and add a new sample in the
|
To generate a new cast file, open the \resources\scripts\Generator\Generator.slnx project and add a new sample in the
|
||||||
Commands/AsciiCast/Samples/ folder. If the widget is static such as a tree or a table, try and animate the widget
|
Commands/AsciiCast/Samples/ folder. If the widget is static such as a tree or a table, try and animate the widget
|
||||||
using the Live widget to change the content or styling.
|
using the Live widget to change the content or styling.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ For all available spinners, see https://jsfiddle.net/sindresorhus/2eLtsbey/embed
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Spinners can be used with [Progress](xref:progress) and [Status](xref:status).
|
Spinners can be used with [Progress](xref:live-progress) and [Status](xref:live-status).
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Status()
|
AnsiConsole.Status()
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ Description: "*Spectre.Console* makes it easy to write text with different style
|
|||||||
Highlights:
|
Highlights:
|
||||||
- Bold, Italic, Underline, strikethrough
|
- Bold, Italic, Underline, strikethrough
|
||||||
- Dim, Invert
|
- Dim, Invert
|
||||||
- Conceal, slowblink, rapidblink
|
- Conceal, slowblink, rapidblink
|
||||||
- Links
|
- Links
|
||||||
|
Xref: appendix-styles
|
||||||
---
|
---
|
||||||
|
|
||||||
Note that what styles that can be used is defined by the system or your terminal software, and may not appear as they should.
|
Note that what styles that can be used is defined by the system or your terminal software, and may not appear as they should.
|
||||||
@@ -46,9 +47,9 @@ Note that what styles that can be used is defined by the system or your terminal
|
|||||||
<tr>
|
<tr>
|
||||||
<td><code>strikethrough</code></td>
|
<td><code>strikethrough</code></td>
|
||||||
<td>Shows text with a horizontal line through the center</td>
|
<td>Shows text with a horizontal line through the center</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>link</link></td>
|
<td><code>link</code></td>
|
||||||
<td>Creates a clickable link within text</td>
|
<td>Creates a clickable link within text</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
2
docs/input/assets/casts/align-rich.cast
Normal file
2
docs/input/assets/casts/align-rich.cast
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
{"version": 2, "width": 40, "height": 3, "timestamp": 1667342769, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
|
||||||
|
[0.0, "o", "\u001b[H\u001b[2B\u001b[38;5;9;48;5;0mSpectre!\u001b[0m"]
|
||||||
332
docs/input/assets/casts/await-spinner-plain.cast
Normal file
332
docs/input/assets/casts/await-spinner-plain.cast
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
{"version": 2, "width": 42, "height": 4, "title": "await-spinner (plain)", "env": {"TERM": "Spectre.Console"}}
|
||||||
|
[0, "o", "Loading the rocket ship "]
|
||||||
|
[0, "o", "\u001B[?25l"]
|
||||||
|
[0, "o", "\u280B"]
|
||||||
|
[0, "o", "\u001B[1D"]
|
||||||
|
[0.094, "o", "\u001B[?25l"]
|
||||||
|
[0.094, "o", "\u2819"]
|
||||||
|
[0.094, "o", "\u001B[1D"]
|
||||||
|
[0.188, "o", "\u001B[?25l"]
|
||||||
|
[0.188, "o", "\u2839"]
|
||||||
|
[0.188, "o", "\u001B[1D"]
|
||||||
|
[0.266, "o", "\u001B[?25l"]
|
||||||
|
[0.266, "o", "\u2838"]
|
||||||
|
[0.266, "o", "\u001B[1D"]
|
||||||
|
[0.36, "o", "\u001B[?25l"]
|
||||||
|
[0.36, "o", "\u283C"]
|
||||||
|
[0.36, "o", "\u001B[1D"]
|
||||||
|
[0.453, "o", "\u001B[?25l"]
|
||||||
|
[0.453, "o", "\u2834"]
|
||||||
|
[0.453, "o", "\u001B[1D"]
|
||||||
|
[0.563, "o", "\u001B[?25l"]
|
||||||
|
[0.563, "o", "\u2826"]
|
||||||
|
[0.563, "o", "\u001B[1D"]
|
||||||
|
[0.656, "o", "\u001B[?25l"]
|
||||||
|
[0.656, "o", "\u2827"]
|
||||||
|
[0.656, "o", "\u001B[1D"]
|
||||||
|
[0.75, "o", "\u001B[?25l"]
|
||||||
|
[0.75, "o", "\u2807"]
|
||||||
|
[0.75, "o", "\u001B[1D"]
|
||||||
|
[0.844, "o", "\u001B[?25l"]
|
||||||
|
[0.844, "o", "\u280F"]
|
||||||
|
[0.844, "o", "\u001B[1D"]
|
||||||
|
[0.922, "o", "\u001B[?25l"]
|
||||||
|
[0.922, "o", "\u280B"]
|
||||||
|
[0.922, "o", "\u001B[1D"]
|
||||||
|
[1.016, "o", "\u001B[?25l"]
|
||||||
|
[1.016, "o", "\u2819"]
|
||||||
|
[1.016, "o", "\u001B[1D"]
|
||||||
|
[1.11, "o", "\u001B[?25l"]
|
||||||
|
[1.11, "o", "\u2839"]
|
||||||
|
[1.11, "o", "\u001B[1D"]
|
||||||
|
[1.203, "o", "\u001B[?25l"]
|
||||||
|
[1.203, "o", "\u2838"]
|
||||||
|
[1.203, "o", "\u001B[1D"]
|
||||||
|
[1.297, "o", "\u001B[?25l"]
|
||||||
|
[1.297, "o", "\u283C"]
|
||||||
|
[1.297, "o", "\u001B[1D"]
|
||||||
|
[1.391, "o", "\u001B[?25l"]
|
||||||
|
[1.391, "o", "\u2834"]
|
||||||
|
[1.391, "o", "\u001B[1D"]
|
||||||
|
[1.485, "o", "\u001B[?25l"]
|
||||||
|
[1.485, "o", "\u2826"]
|
||||||
|
[1.485, "o", "\u001B[1D"]
|
||||||
|
[1.578, "o", "\u001B[?25l"]
|
||||||
|
[1.578, "o", "\u2827"]
|
||||||
|
[1.578, "o", "\u001B[1D"]
|
||||||
|
[1.672, "o", "\u001B[?25l"]
|
||||||
|
[1.672, "o", "\u2807"]
|
||||||
|
[1.672, "o", "\u001B[1D"]
|
||||||
|
[1.75, "o", "\u001B[?25l"]
|
||||||
|
[1.75, "o", "\u280F"]
|
||||||
|
[1.75, "o", "\u001B[1D"]
|
||||||
|
[1.828, "o", "\u001B[?25l"]
|
||||||
|
[1.828, "o", "\u280B"]
|
||||||
|
[1.828, "o", "\u001B[1D"]
|
||||||
|
[1.906, "o", "\u001B[?25l"]
|
||||||
|
[1.906, "o", "\u2819"]
|
||||||
|
[1.906, "o", "\u001B[1D"]
|
||||||
|
[2, "o", "\u001B[?25l"]
|
||||||
|
[2, "o", "\u2839"]
|
||||||
|
[2, "o", "\u001B[1D"]
|
||||||
|
[2.11, "o", "\u001B[?25l"]
|
||||||
|
[2.11, "o", "\u2838"]
|
||||||
|
[2.11, "o", "\u001B[1D"]
|
||||||
|
[2.203, "o", "\u001B[?25l"]
|
||||||
|
[2.203, "o", "\u283C"]
|
||||||
|
[2.203, "o", "\u001B[1D"]
|
||||||
|
[2.297, "o", "\u001B[?25l"]
|
||||||
|
[2.297, "o", "\u2834"]
|
||||||
|
[2.297, "o", "\u001B[1D"]
|
||||||
|
[2.391, "o", "\u001B[?25l"]
|
||||||
|
[2.391, "o", "\u2826"]
|
||||||
|
[2.391, "o", "\u001B[1D"]
|
||||||
|
[2.485, "o", "\u001B[?25l"]
|
||||||
|
[2.485, "o", "\u2827"]
|
||||||
|
[2.485, "o", "\u001B[1D"]
|
||||||
|
[2.578, "o", "\u001B[?25l"]
|
||||||
|
[2.578, "o", "\u2807"]
|
||||||
|
[2.578, "o", "\u001B[1D"]
|
||||||
|
[2.656, "o", "\u001B[?25l"]
|
||||||
|
[2.656, "o", "\u280F"]
|
||||||
|
[2.656, "o", "\u001B[1D"]
|
||||||
|
[2.735, "o", "\u001B[?25l"]
|
||||||
|
[2.735, "o", "\u280B"]
|
||||||
|
[2.735, "o", "\u001B[1D"]
|
||||||
|
[2.828, "o", "\u001B[?25l"]
|
||||||
|
[2.828, "o", "\u2819"]
|
||||||
|
[2.828, "o", "\u001B[1D"]
|
||||||
|
[2.922, "o", "\u001B[?25l"]
|
||||||
|
[2.922, "o", "\u2839"]
|
||||||
|
[2.922, "o", "\u001B[1D"]
|
||||||
|
[3.016, "o", "\u001B[?25l"]
|
||||||
|
[3.016, "o", "\u2838"]
|
||||||
|
[3.016, "o", "\u001B[1D"]
|
||||||
|
[3.094, "o", "\u001B[?25l"]
|
||||||
|
[3.094, "o", "\u283C"]
|
||||||
|
[3.094, "o", "\u001B[1D"]
|
||||||
|
[3.188, "o", "\u001B[?25l"]
|
||||||
|
[3.188, "o", "\u2834"]
|
||||||
|
[3.188, "o", "\u001B[1D"]
|
||||||
|
[3.281, "o", "\u001B[?25l"]
|
||||||
|
[3.281, "o", "\u2826"]
|
||||||
|
[3.281, "o", "\u001B[1D"]
|
||||||
|
[3.375, "o", "\u001B[?25l"]
|
||||||
|
[3.375, "o", "\u2827"]
|
||||||
|
[3.375, "o", "\u001B[1D"]
|
||||||
|
[3.453, "o", "\u001B[?25l"]
|
||||||
|
[3.453, "o", "\u2807"]
|
||||||
|
[3.453, "o", "\u001B[1D"]
|
||||||
|
[3.516, "o", " "]
|
||||||
|
[3.516, "o", "\u001B[1D"]
|
||||||
|
[3.516, "o", "\u001B[?25h"]
|
||||||
|
[3.516, "o", "\u001B[32mDone\u001B[0m\r\n"]
|
||||||
|
[3.516, "o", "Firing up the engines "]
|
||||||
|
[3.516, "o", "\u001B[?25l"]
|
||||||
|
[3.516, "o", "[ ]"]
|
||||||
|
[3.516, "o", "\u001B[6D"]
|
||||||
|
[3.61, "o", "\u001B[?25l"]
|
||||||
|
[3.61, "o", "[= ]"]
|
||||||
|
[3.61, "o", "\u001B[6D"]
|
||||||
|
[3.703, "o", "\u001B[?25l"]
|
||||||
|
[3.703, "o", "[== ]"]
|
||||||
|
[3.703, "o", "\u001B[6D"]
|
||||||
|
[3.797, "o", "\u001B[?25l"]
|
||||||
|
[3.797, "o", "[=== ]"]
|
||||||
|
[3.797, "o", "\u001B[6D"]
|
||||||
|
[3.875, "o", "\u001B[?25l"]
|
||||||
|
[3.875, "o", "[ ===]"]
|
||||||
|
[3.875, "o", "\u001B[6D"]
|
||||||
|
[3.953, "o", "\u001B[?25l"]
|
||||||
|
[3.953, "o", "[ ==]"]
|
||||||
|
[3.953, "o", "\u001B[6D"]
|
||||||
|
[4.063, "o", "\u001B[?25l"]
|
||||||
|
[4.063, "o", "[ =]"]
|
||||||
|
[4.063, "o", "\u001B[6D"]
|
||||||
|
[4.156, "o", "\u001B[?25l"]
|
||||||
|
[4.156, "o", "[ ]"]
|
||||||
|
[4.156, "o", "\u001B[6D"]
|
||||||
|
[4.25, "o", "\u001B[?25l"]
|
||||||
|
[4.25, "o", "[ =]"]
|
||||||
|
[4.25, "o", "\u001B[6D"]
|
||||||
|
[4.328, "o", "\u001B[?25l"]
|
||||||
|
[4.328, "o", "[ ==]"]
|
||||||
|
[4.328, "o", "\u001B[6D"]
|
||||||
|
[4.406, "o", "\u001B[?25l"]
|
||||||
|
[4.406, "o", "[ ===]"]
|
||||||
|
[4.406, "o", "\u001B[6D"]
|
||||||
|
[4.5, "o", "\u001B[?25l"]
|
||||||
|
[4.5, "o", "[====]"]
|
||||||
|
[4.5, "o", "\u001B[6D"]
|
||||||
|
[4.594, "o", "\u001B[?25l"]
|
||||||
|
[4.594, "o", "[=== ]"]
|
||||||
|
[4.594, "o", "\u001B[6D"]
|
||||||
|
[4.688, "o", "\u001B[?25l"]
|
||||||
|
[4.688, "o", "[== ]"]
|
||||||
|
[4.688, "o", "\u001B[6D"]
|
||||||
|
[4.781, "o", "\u001B[?25l"]
|
||||||
|
[4.781, "o", "[= ]"]
|
||||||
|
[4.781, "o", "\u001B[6D"]
|
||||||
|
[4.86, "o", "\u001B[?25l"]
|
||||||
|
[4.86, "o", "[ ]"]
|
||||||
|
[4.86, "o", "\u001B[6D"]
|
||||||
|
[4.953, "o", "\u001B[?25l"]
|
||||||
|
[4.953, "o", "[= ]"]
|
||||||
|
[4.953, "o", "\u001B[6D"]
|
||||||
|
[5.031, "o", "\u001B[?25l"]
|
||||||
|
[5.031, "o", "[== ]"]
|
||||||
|
[5.031, "o", "\u001B[6D"]
|
||||||
|
[5.125, "o", "\u001B[?25l"]
|
||||||
|
[5.125, "o", "[=== ]"]
|
||||||
|
[5.125, "o", "\u001B[6D"]
|
||||||
|
[5.219, "o", "\u001B[?25l"]
|
||||||
|
[5.219, "o", "[ ===]"]
|
||||||
|
[5.219, "o", "\u001B[6D"]
|
||||||
|
[5.313, "o", "\u001B[?25l"]
|
||||||
|
[5.313, "o", "[ ==]"]
|
||||||
|
[5.313, "o", "\u001B[6D"]
|
||||||
|
[5.422, "o", "\u001B[?25l"]
|
||||||
|
[5.422, "o", "[ =]"]
|
||||||
|
[5.422, "o", "\u001B[6D"]
|
||||||
|
[5.5, "o", "\u001B[?25l"]
|
||||||
|
[5.5, "o", "[ ]"]
|
||||||
|
[5.5, "o", "\u001B[6D"]
|
||||||
|
[5.594, "o", "\u001B[?25l"]
|
||||||
|
[5.594, "o", "[ =]"]
|
||||||
|
[5.594, "o", "\u001B[6D"]
|
||||||
|
[5.672, "o", "\u001B[?25l"]
|
||||||
|
[5.672, "o", "[ ==]"]
|
||||||
|
[5.672, "o", "\u001B[6D"]
|
||||||
|
[5.766, "o", "\u001B[?25l"]
|
||||||
|
[5.766, "o", "[ ===]"]
|
||||||
|
[5.766, "o", "\u001B[6D"]
|
||||||
|
[5.86, "o", "\u001B[?25l"]
|
||||||
|
[5.86, "o", "[====]"]
|
||||||
|
[5.86, "o", "\u001B[6D"]
|
||||||
|
[5.953, "o", "\u001B[?25l"]
|
||||||
|
[5.969, "o", "[=== ]"]
|
||||||
|
[5.969, "o", "\u001B[6D"]
|
||||||
|
[6.063, "o", "\u001B[?25l"]
|
||||||
|
[6.063, "o", "[== ]"]
|
||||||
|
[6.063, "o", "\u001B[6D"]
|
||||||
|
[6.156, "o", "\u001B[?25l"]
|
||||||
|
[6.156, "o", "[= ]"]
|
||||||
|
[6.156, "o", "\u001B[6D"]
|
||||||
|
[6.25, "o", "\u001B[?25l"]
|
||||||
|
[6.25, "o", "[ ]"]
|
||||||
|
[6.25, "o", "\u001B[6D"]
|
||||||
|
[6.328, "o", "\u001B[?25l"]
|
||||||
|
[6.328, "o", "[= ]"]
|
||||||
|
[6.328, "o", "\u001B[6D"]
|
||||||
|
[6.422, "o", "\u001B[?25l"]
|
||||||
|
[6.422, "o", "[== ]"]
|
||||||
|
[6.422, "o", "\u001B[6D"]
|
||||||
|
[6.516, "o", "\u001B[?25l"]
|
||||||
|
[6.516, "o", "[=== ]"]
|
||||||
|
[6.516, "o", "\u001B[6D"]
|
||||||
|
[6.61, "o", "\u001B[?25l"]
|
||||||
|
[6.61, "o", "[ ===]"]
|
||||||
|
[6.61, "o", "\u001B[6D"]
|
||||||
|
[6.703, "o", "\u001B[?25l"]
|
||||||
|
[6.703, "o", "[ ==]"]
|
||||||
|
[6.703, "o", "\u001B[6D"]
|
||||||
|
[6.797, "o", "\u001B[?25l"]
|
||||||
|
[6.797, "o", "[ =]"]
|
||||||
|
[6.797, "o", "\u001B[6D"]
|
||||||
|
[6.891, "o", "\u001B[?25l"]
|
||||||
|
[6.891, "o", "[ ]"]
|
||||||
|
[6.891, "o", "\u001B[6D"]
|
||||||
|
[6.922, "o", " "]
|
||||||
|
[6.922, "o", "\u001B[6D"]
|
||||||
|
[6.922, "o", "\u001B[?25h"]
|
||||||
|
[6.922, "o", "\u001B[32mDone\u001B[0m\r\n"]
|
||||||
|
[6.922, "o", "Blasting into orbit "]
|
||||||
|
[6.922, "o", "\u001B[?25l"]
|
||||||
|
[6.922, "o", "\u2631"]
|
||||||
|
[6.922, "o", "\u001B[1D"]
|
||||||
|
[7.031, "o", "\u001B[?25l"]
|
||||||
|
[7.031, "o", "\u2632"]
|
||||||
|
[7.031, "o", "\u001B[1D"]
|
||||||
|
[7.141, "o", "\u001B[?25l"]
|
||||||
|
[7.141, "o", "\u2634"]
|
||||||
|
[7.141, "o", "\u001B[1D"]
|
||||||
|
[7.25, "o", "\u001B[?25l"]
|
||||||
|
[7.25, "o", "\u2631"]
|
||||||
|
[7.25, "o", "\u001B[1D"]
|
||||||
|
[7.36, "o", "\u001B[?25l"]
|
||||||
|
[7.36, "o", "\u2632"]
|
||||||
|
[7.36, "o", "\u001B[1D"]
|
||||||
|
[7.485, "o", "\u001B[?25l"]
|
||||||
|
[7.485, "o", "\u2634"]
|
||||||
|
[7.485, "o", "\u001B[1D"]
|
||||||
|
[7.594, "o", "\u001B[?25l"]
|
||||||
|
[7.594, "o", "\u2631"]
|
||||||
|
[7.594, "o", "\u001B[1D"]
|
||||||
|
[7.703, "o", "\u001B[?25l"]
|
||||||
|
[7.703, "o", "\u2632"]
|
||||||
|
[7.703, "o", "\u001B[1D"]
|
||||||
|
[7.813, "o", "\u001B[?25l"]
|
||||||
|
[7.813, "o", "\u2634"]
|
||||||
|
[7.813, "o", "\u001B[1D"]
|
||||||
|
[7.922, "o", "\u001B[?25l"]
|
||||||
|
[7.922, "o", "\u2631"]
|
||||||
|
[7.922, "o", "\u001B[1D"]
|
||||||
|
[8.031, "o", "\u001B[?25l"]
|
||||||
|
[8.031, "o", "\u2632"]
|
||||||
|
[8.031, "o", "\u001B[1D"]
|
||||||
|
[8.141, "o", "\u001B[?25l"]
|
||||||
|
[8.141, "o", "\u2634"]
|
||||||
|
[8.141, "o", "\u001B[1D"]
|
||||||
|
[8.25, "o", "\u001B[?25l"]
|
||||||
|
[8.25, "o", "\u2631"]
|
||||||
|
[8.25, "o", "\u001B[1D"]
|
||||||
|
[8.375, "o", "\u001B[?25l"]
|
||||||
|
[8.375, "o", "\u2632"]
|
||||||
|
[8.375, "o", "\u001B[1D"]
|
||||||
|
[8.485, "o", "\u001B[?25l"]
|
||||||
|
[8.485, "o", "\u2634"]
|
||||||
|
[8.485, "o", "\u001B[1D"]
|
||||||
|
[8.594, "o", "\u001B[?25l"]
|
||||||
|
[8.594, "o", "\u2631"]
|
||||||
|
[8.594, "o", "\u001B[1D"]
|
||||||
|
[8.703, "o", "\u001B[?25l"]
|
||||||
|
[8.703, "o", "\u2632"]
|
||||||
|
[8.703, "o", "\u001B[1D"]
|
||||||
|
[8.813, "o", "\u001B[?25l"]
|
||||||
|
[8.813, "o", "\u2634"]
|
||||||
|
[8.813, "o", "\u001B[1D"]
|
||||||
|
[8.938, "o", "\u001B[?25l"]
|
||||||
|
[8.938, "o", "\u2631"]
|
||||||
|
[8.938, "o", "\u001B[1D"]
|
||||||
|
[9.047, "o", "\u001B[?25l"]
|
||||||
|
[9.047, "o", "\u2632"]
|
||||||
|
[9.047, "o", "\u001B[1D"]
|
||||||
|
[9.156, "o", "\u001B[?25l"]
|
||||||
|
[9.156, "o", "\u2634"]
|
||||||
|
[9.156, "o", "\u001B[1D"]
|
||||||
|
[9.266, "o", "\u001B[?25l"]
|
||||||
|
[9.266, "o", "\u2631"]
|
||||||
|
[9.266, "o", "\u001B[1D"]
|
||||||
|
[9.375, "o", "\u001B[?25l"]
|
||||||
|
[9.375, "o", "\u2632"]
|
||||||
|
[9.375, "o", "\u001B[1D"]
|
||||||
|
[9.485, "o", "\u001B[?25l"]
|
||||||
|
[9.485, "o", "\u2634"]
|
||||||
|
[9.485, "o", "\u001B[1D"]
|
||||||
|
[9.594, "o", "\u001B[?25l"]
|
||||||
|
[9.594, "o", "\u2631"]
|
||||||
|
[9.594, "o", "\u001B[1D"]
|
||||||
|
[9.719, "o", "\u001B[?25l"]
|
||||||
|
[9.719, "o", "\u2632"]
|
||||||
|
[9.719, "o", "\u001B[1D"]
|
||||||
|
[9.828, "o", "\u001B[?25l"]
|
||||||
|
[9.828, "o", "\u2634"]
|
||||||
|
[9.828, "o", "\u001B[1D"]
|
||||||
|
[9.938, "o", "\u001B[?25l"]
|
||||||
|
[9.938, "o", "\u2631"]
|
||||||
|
[9.938, "o", "\u001B[1D"]
|
||||||
|
[9.953, "o", " "]
|
||||||
|
[9.953, "o", "\u001B[1D"]
|
||||||
|
[9.953, "o", "\u001B[?25h"]
|
||||||
|
[9.953, "o", "\u001B[31mOh no\u001B[0m\r\n"]
|
||||||
|
|
||||||
326
docs/input/assets/casts/await-spinner-rich.cast
Normal file
326
docs/input/assets/casts/await-spinner-rich.cast
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
{"version": 2, "width": 42, "height": 4, "title": "await-spinner (rich)", "env": {"TERM": "Spectre.Console"}}
|
||||||
|
[0, "o", "Loading the rocket ship "]
|
||||||
|
[0, "o", "\u001B[?25l"]
|
||||||
|
[0, "o", "\u280B"]
|
||||||
|
[0, "o", "\u001B[1D"]
|
||||||
|
[0.094, "o", "\u001B[?25l"]
|
||||||
|
[0.094, "o", "\u2819"]
|
||||||
|
[0.094, "o", "\u001B[1D"]
|
||||||
|
[0.172, "o", "\u001B[?25l"]
|
||||||
|
[0.172, "o", "\u2839"]
|
||||||
|
[0.172, "o", "\u001B[1D"]
|
||||||
|
[0.266, "o", "\u001B[?25l"]
|
||||||
|
[0.266, "o", "\u2838"]
|
||||||
|
[0.266, "o", "\u001B[1D"]
|
||||||
|
[0.36, "o", "\u001B[?25l"]
|
||||||
|
[0.36, "o", "\u283C"]
|
||||||
|
[0.36, "o", "\u001B[1D"]
|
||||||
|
[0.453, "o", "\u001B[?25l"]
|
||||||
|
[0.453, "o", "\u2834"]
|
||||||
|
[0.453, "o", "\u001B[1D"]
|
||||||
|
[0.547, "o", "\u001B[?25l"]
|
||||||
|
[0.547, "o", "\u2826"]
|
||||||
|
[0.547, "o", "\u001B[1D"]
|
||||||
|
[0.641, "o", "\u001B[?25l"]
|
||||||
|
[0.641, "o", "\u2827"]
|
||||||
|
[0.641, "o", "\u001B[1D"]
|
||||||
|
[0.719, "o", "\u001B[?25l"]
|
||||||
|
[0.719, "o", "\u2807"]
|
||||||
|
[0.719, "o", "\u001B[1D"]
|
||||||
|
[0.797, "o", "\u001B[?25l"]
|
||||||
|
[0.797, "o", "\u280F"]
|
||||||
|
[0.797, "o", "\u001B[1D"]
|
||||||
|
[0.891, "o", "\u001B[?25l"]
|
||||||
|
[0.891, "o", "\u280B"]
|
||||||
|
[0.891, "o", "\u001B[1D"]
|
||||||
|
[0.969, "o", "\u001B[?25l"]
|
||||||
|
[0.969, "o", "\u2819"]
|
||||||
|
[0.969, "o", "\u001B[1D"]
|
||||||
|
[1.078, "o", "\u001B[?25l"]
|
||||||
|
[1.078, "o", "\u2839"]
|
||||||
|
[1.094, "o", "\u001B[1D"]
|
||||||
|
[1.25, "o", "\u001B[?25l"]
|
||||||
|
[1.25, "o", "\u2838"]
|
||||||
|
[1.266, "o", "\u001B[1D"]
|
||||||
|
[1.407, "o", "\u001B[?25l"]
|
||||||
|
[1.407, "o", "\u283C"]
|
||||||
|
[1.422, "o", "\u001B[1D"]
|
||||||
|
[1.532, "o", "\u001B[?25l"]
|
||||||
|
[1.532, "o", "\u2834"]
|
||||||
|
[1.532, "o", "\u001B[1D"]
|
||||||
|
[1.61, "o", "\u001B[?25l"]
|
||||||
|
[1.61, "o", "\u2826"]
|
||||||
|
[1.61, "o", "\u001B[1D"]
|
||||||
|
[1.703, "o", "\u001B[?25l"]
|
||||||
|
[1.703, "o", "\u2827"]
|
||||||
|
[1.703, "o", "\u001B[1D"]
|
||||||
|
[1.782, "o", "\u001B[?25l"]
|
||||||
|
[1.782, "o", "\u2807"]
|
||||||
|
[1.782, "o", "\u001B[1D"]
|
||||||
|
[1.86, "o", "\u001B[?25l"]
|
||||||
|
[1.86, "o", "\u280F"]
|
||||||
|
[1.86, "o", "\u001B[1D"]
|
||||||
|
[1.953, "o", "\u001B[?25l"]
|
||||||
|
[1.953, "o", "\u280B"]
|
||||||
|
[1.953, "o", "\u001B[1D"]
|
||||||
|
[2.047, "o", "\u001B[?25l"]
|
||||||
|
[2.047, "o", "\u2819"]
|
||||||
|
[2.047, "o", "\u001B[1D"]
|
||||||
|
[2.125, "o", "\u001B[?25l"]
|
||||||
|
[2.125, "o", "\u2839"]
|
||||||
|
[2.125, "o", "\u001B[1D"]
|
||||||
|
[2.219, "o", "\u001B[?25l"]
|
||||||
|
[2.219, "o", "\u2838"]
|
||||||
|
[2.219, "o", "\u001B[1D"]
|
||||||
|
[2.313, "o", "\u001B[?25l"]
|
||||||
|
[2.313, "o", "\u283C"]
|
||||||
|
[2.313, "o", "\u001B[1D"]
|
||||||
|
[2.407, "o", "\u001B[?25l"]
|
||||||
|
[2.407, "o", "\u2834"]
|
||||||
|
[2.407, "o", "\u001B[1D"]
|
||||||
|
[2.5, "o", "\u001B[?25l"]
|
||||||
|
[2.5, "o", "\u2826"]
|
||||||
|
[2.5, "o", "\u001B[1D"]
|
||||||
|
[2.594, "o", "\u001B[?25l"]
|
||||||
|
[2.594, "o", "\u2827"]
|
||||||
|
[2.594, "o", "\u001B[1D"]
|
||||||
|
[2.688, "o", "\u001B[?25l"]
|
||||||
|
[2.688, "o", "\u2807"]
|
||||||
|
[2.688, "o", "\u001B[1D"]
|
||||||
|
[2.782, "o", "\u001B[?25l"]
|
||||||
|
[2.782, "o", "\u280F"]
|
||||||
|
[2.782, "o", "\u001B[1D"]
|
||||||
|
[2.875, "o", "\u001B[?25l"]
|
||||||
|
[2.875, "o", "\u280B"]
|
||||||
|
[2.875, "o", "\u001B[1D"]
|
||||||
|
[2.969, "o", "\u001B[?25l"]
|
||||||
|
[2.969, "o", "\u2819"]
|
||||||
|
[2.969, "o", "\u001B[1D"]
|
||||||
|
[3.063, "o", "\u001B[?25l"]
|
||||||
|
[3.063, "o", "\u2839"]
|
||||||
|
[3.063, "o", "\u001B[1D"]
|
||||||
|
[3.157, "o", "\u001B[?25l"]
|
||||||
|
[3.157, "o", "\u2838"]
|
||||||
|
[3.157, "o", "\u001B[1D"]
|
||||||
|
[3.25, "o", "\u001B[?25l"]
|
||||||
|
[3.25, "o", "\u283C"]
|
||||||
|
[3.25, "o", "\u001B[1D"]
|
||||||
|
[3.344, "o", "\u001B[?25l"]
|
||||||
|
[3.344, "o", "\u2834"]
|
||||||
|
[3.344, "o", "\u001B[1D"]
|
||||||
|
[3.469, "o", "\u001B[?25l"]
|
||||||
|
[3.469, "o", "\u2826"]
|
||||||
|
[3.469, "o", "\u001B[1D"]
|
||||||
|
[3.563, "o", "\u001B[?25l"]
|
||||||
|
[3.563, "o", "\u2827"]
|
||||||
|
[3.563, "o", "\u001B[1D"]
|
||||||
|
[3.563, "o", " "]
|
||||||
|
[3.563, "o", "\u001B[1D"]
|
||||||
|
[3.563, "o", "\u001B[?25h"]
|
||||||
|
[3.563, "o", "\u001B[38;5;2mDone\u001B[0m\r\n"]
|
||||||
|
[3.563, "o", "Firing up the engines "]
|
||||||
|
[3.563, "o", "\u001B[?25l"]
|
||||||
|
[3.563, "o", "[ ]"]
|
||||||
|
[3.563, "o", "\u001B[6D"]
|
||||||
|
[3.672, "o", "\u001B[?25l"]
|
||||||
|
[3.672, "o", "[= ]"]
|
||||||
|
[3.672, "o", "\u001B[6D"]
|
||||||
|
[3.75, "o", "\u001B[?25l"]
|
||||||
|
[3.75, "o", "[== ]"]
|
||||||
|
[3.75, "o", "\u001B[6D"]
|
||||||
|
[3.844, "o", "\u001B[?25l"]
|
||||||
|
[3.844, "o", "[=== ]"]
|
||||||
|
[3.844, "o", "\u001B[6D"]
|
||||||
|
[3.953, "o", "\u001B[?25l"]
|
||||||
|
[3.953, "o", "[ ===]"]
|
||||||
|
[3.953, "o", "\u001B[6D"]
|
||||||
|
[4.047, "o", "\u001B[?25l"]
|
||||||
|
[4.047, "o", "[ ==]"]
|
||||||
|
[4.047, "o", "\u001B[6D"]
|
||||||
|
[4.157, "o", "\u001B[?25l"]
|
||||||
|
[4.157, "o", "[ =]"]
|
||||||
|
[4.157, "o", "\u001B[6D"]
|
||||||
|
[4.25, "o", "\u001B[?25l"]
|
||||||
|
[4.25, "o", "[ ]"]
|
||||||
|
[4.25, "o", "\u001B[6D"]
|
||||||
|
[4.344, "o", "\u001B[?25l"]
|
||||||
|
[4.344, "o", "[ =]"]
|
||||||
|
[4.344, "o", "\u001B[6D"]
|
||||||
|
[4.438, "o", "\u001B[?25l"]
|
||||||
|
[4.438, "o", "[ ==]"]
|
||||||
|
[4.438, "o", "\u001B[6D"]
|
||||||
|
[4.532, "o", "\u001B[?25l"]
|
||||||
|
[4.532, "o", "[ ===]"]
|
||||||
|
[4.532, "o", "\u001B[6D"]
|
||||||
|
[4.625, "o", "\u001B[?25l"]
|
||||||
|
[4.625, "o", "[====]"]
|
||||||
|
[4.625, "o", "\u001B[6D"]
|
||||||
|
[4.719, "o", "\u001B[?25l"]
|
||||||
|
[4.719, "o", "[=== ]"]
|
||||||
|
[4.719, "o", "\u001B[6D"]
|
||||||
|
[4.828, "o", "\u001B[?25l"]
|
||||||
|
[4.844, "o", "[== ]"]
|
||||||
|
[4.86, "o", "\u001B[6D"]
|
||||||
|
[4.953, "o", "\u001B[?25l"]
|
||||||
|
[4.953, "o", "[= ]"]
|
||||||
|
[4.953, "o", "\u001B[6D"]
|
||||||
|
[5.047, "o", "\u001B[?25l"]
|
||||||
|
[5.047, "o", "[ ]"]
|
||||||
|
[5.047, "o", "\u001B[6D"]
|
||||||
|
[5.141, "o", "\u001B[?25l"]
|
||||||
|
[5.141, "o", "[= ]"]
|
||||||
|
[5.141, "o", "\u001B[6D"]
|
||||||
|
[5.235, "o", "\u001B[?25l"]
|
||||||
|
[5.235, "o", "[== ]"]
|
||||||
|
[5.235, "o", "\u001B[6D"]
|
||||||
|
[5.328, "o", "\u001B[?25l"]
|
||||||
|
[5.328, "o", "[=== ]"]
|
||||||
|
[5.328, "o", "\u001B[6D"]
|
||||||
|
[5.422, "o", "\u001B[?25l"]
|
||||||
|
[5.422, "o", "[ ===]"]
|
||||||
|
[5.422, "o", "\u001B[6D"]
|
||||||
|
[5.532, "o", "\u001B[?25l"]
|
||||||
|
[5.532, "o", "[ ==]"]
|
||||||
|
[5.532, "o", "\u001B[6D"]
|
||||||
|
[5.625, "o", "\u001B[?25l"]
|
||||||
|
[5.625, "o", "[ =]"]
|
||||||
|
[5.625, "o", "\u001B[6D"]
|
||||||
|
[5.719, "o", "\u001B[?25l"]
|
||||||
|
[5.719, "o", "[ ]"]
|
||||||
|
[5.719, "o", "\u001B[6D"]
|
||||||
|
[5.813, "o", "\u001B[?25l"]
|
||||||
|
[5.813, "o", "[ =]"]
|
||||||
|
[5.813, "o", "\u001B[6D"]
|
||||||
|
[5.907, "o", "\u001B[?25l"]
|
||||||
|
[5.907, "o", "[ ==]"]
|
||||||
|
[5.907, "o", "\u001B[6D"]
|
||||||
|
[6, "o", "\u001B[?25l"]
|
||||||
|
[6, "o", "[ ===]"]
|
||||||
|
[6, "o", "\u001B[6D"]
|
||||||
|
[6.094, "o", "\u001B[?25l"]
|
||||||
|
[6.094, "o", "[====]"]
|
||||||
|
[6.094, "o", "\u001B[6D"]
|
||||||
|
[6.188, "o", "\u001B[?25l"]
|
||||||
|
[6.188, "o", "[=== ]"]
|
||||||
|
[6.188, "o", "\u001B[6D"]
|
||||||
|
[6.282, "o", "\u001B[?25l"]
|
||||||
|
[6.282, "o", "[== ]"]
|
||||||
|
[6.282, "o", "\u001B[6D"]
|
||||||
|
[6.375, "o", "\u001B[?25l"]
|
||||||
|
[6.375, "o", "[= ]"]
|
||||||
|
[6.375, "o", "\u001B[6D"]
|
||||||
|
[6.453, "o", "\u001B[?25l"]
|
||||||
|
[6.453, "o", "[ ]"]
|
||||||
|
[6.453, "o", "\u001B[6D"]
|
||||||
|
[6.547, "o", "\u001B[?25l"]
|
||||||
|
[6.547, "o", "[= ]"]
|
||||||
|
[6.547, "o", "\u001B[6D"]
|
||||||
|
[6.625, "o", "\u001B[?25l"]
|
||||||
|
[6.625, "o", "[== ]"]
|
||||||
|
[6.625, "o", "\u001B[6D"]
|
||||||
|
[6.703, "o", "\u001B[?25l"]
|
||||||
|
[6.703, "o", "[=== ]"]
|
||||||
|
[6.703, "o", "\u001B[6D"]
|
||||||
|
[6.797, "o", "\u001B[?25l"]
|
||||||
|
[6.797, "o", "[ ===]"]
|
||||||
|
[6.797, "o", "\u001B[6D"]
|
||||||
|
[6.891, "o", "\u001B[?25l"]
|
||||||
|
[6.891, "o", "[ ==]"]
|
||||||
|
[6.891, "o", "\u001B[6D"]
|
||||||
|
[6.969, "o", " "]
|
||||||
|
[6.969, "o", "\u001B[6D"]
|
||||||
|
[6.969, "o", "\u001B[?25h"]
|
||||||
|
[6.969, "o", "\u001B[38;5;2mDone\u001B[0m\r\n"]
|
||||||
|
[6.969, "o", "Blasting into orbit "]
|
||||||
|
[6.969, "o", "\u001B[?25l"]
|
||||||
|
[6.969, "o", "\u2631"]
|
||||||
|
[6.969, "o", "\u001B[1D"]
|
||||||
|
[7.078, "o", "\u001B[?25l"]
|
||||||
|
[7.078, "o", "\u2632"]
|
||||||
|
[7.078, "o", "\u001B[1D"]
|
||||||
|
[7.172, "o", "\u001B[?25l"]
|
||||||
|
[7.172, "o", "\u2634"]
|
||||||
|
[7.172, "o", "\u001B[1D"]
|
||||||
|
[7.282, "o", "\u001B[?25l"]
|
||||||
|
[7.282, "o", "\u2631"]
|
||||||
|
[7.282, "o", "\u001B[1D"]
|
||||||
|
[7.375, "o", "\u001B[?25l"]
|
||||||
|
[7.375, "o", "\u2632"]
|
||||||
|
[7.375, "o", "\u001B[1D"]
|
||||||
|
[7.485, "o", "\u001B[?25l"]
|
||||||
|
[7.485, "o", "\u2634"]
|
||||||
|
[7.485, "o", "\u001B[1D"]
|
||||||
|
[7.594, "o", "\u001B[?25l"]
|
||||||
|
[7.594, "o", "\u2631"]
|
||||||
|
[7.594, "o", "\u001B[1D"]
|
||||||
|
[7.703, "o", "\u001B[?25l"]
|
||||||
|
[7.703, "o", "\u2632"]
|
||||||
|
[7.703, "o", "\u001B[1D"]
|
||||||
|
[7.813, "o", "\u001B[?25l"]
|
||||||
|
[7.813, "o", "\u2634"]
|
||||||
|
[7.813, "o", "\u001B[1D"]
|
||||||
|
[7.922, "o", "\u001B[?25l"]
|
||||||
|
[7.922, "o", "\u2631"]
|
||||||
|
[7.922, "o", "\u001B[1D"]
|
||||||
|
[8.032, "o", "\u001B[?25l"]
|
||||||
|
[8.032, "o", "\u2632"]
|
||||||
|
[8.032, "o", "\u001B[1D"]
|
||||||
|
[8.125, "o", "\u001B[?25l"]
|
||||||
|
[8.125, "o", "\u2634"]
|
||||||
|
[8.125, "o", "\u001B[1D"]
|
||||||
|
[8.235, "o", "\u001B[?25l"]
|
||||||
|
[8.235, "o", "\u2631"]
|
||||||
|
[8.235, "o", "\u001B[1D"]
|
||||||
|
[8.344, "o", "\u001B[?25l"]
|
||||||
|
[8.344, "o", "\u2632"]
|
||||||
|
[8.344, "o", "\u001B[1D"]
|
||||||
|
[8.453, "o", "\u001B[?25l"]
|
||||||
|
[8.453, "o", "\u2634"]
|
||||||
|
[8.453, "o", "\u001B[1D"]
|
||||||
|
[8.563, "o", "\u001B[?25l"]
|
||||||
|
[8.563, "o", "\u2631"]
|
||||||
|
[8.563, "o", "\u001B[1D"]
|
||||||
|
[8.657, "o", "\u001B[?25l"]
|
||||||
|
[8.657, "o", "\u2632"]
|
||||||
|
[8.657, "o", "\u001B[1D"]
|
||||||
|
[8.766, "o", "\u001B[?25l"]
|
||||||
|
[8.766, "o", "\u2634"]
|
||||||
|
[8.766, "o", "\u001B[1D"]
|
||||||
|
[8.86, "o", "\u001B[?25l"]
|
||||||
|
[8.86, "o", "\u2631"]
|
||||||
|
[8.86, "o", "\u001B[1D"]
|
||||||
|
[8.969, "o", "\u001B[?25l"]
|
||||||
|
[8.969, "o", "\u2632"]
|
||||||
|
[8.969, "o", "\u001B[1D"]
|
||||||
|
[9.078, "o", "\u001B[?25l"]
|
||||||
|
[9.078, "o", "\u2634"]
|
||||||
|
[9.078, "o", "\u001B[1D"]
|
||||||
|
[9.203, "o", "\u001B[?25l"]
|
||||||
|
[9.203, "o", "\u2631"]
|
||||||
|
[9.203, "o", "\u001B[1D"]
|
||||||
|
[9.313, "o", "\u001B[?25l"]
|
||||||
|
[9.313, "o", "\u2632"]
|
||||||
|
[9.313, "o", "\u001B[1D"]
|
||||||
|
[9.407, "o", "\u001B[?25l"]
|
||||||
|
[9.407, "o", "\u2634"]
|
||||||
|
[9.407, "o", "\u001B[1D"]
|
||||||
|
[9.516, "o", "\u001B[?25l"]
|
||||||
|
[9.516, "o", "\u2631"]
|
||||||
|
[9.516, "o", "\u001B[1D"]
|
||||||
|
[9.625, "o", "\u001B[?25l"]
|
||||||
|
[9.625, "o", "\u2632"]
|
||||||
|
[9.625, "o", "\u001B[1D"]
|
||||||
|
[9.719, "o", "\u001B[?25l"]
|
||||||
|
[9.719, "o", "\u2634"]
|
||||||
|
[9.735, "o", "\u001B[1D"]
|
||||||
|
[9.828, "o", "\u001B[?25l"]
|
||||||
|
[9.828, "o", "\u2631"]
|
||||||
|
[9.828, "o", "\u001B[1D"]
|
||||||
|
[9.938, "o", "\u001B[?25l"]
|
||||||
|
[9.938, "o", "\u2632"]
|
||||||
|
[9.938, "o", "\u001B[1D"]
|
||||||
|
[10, "o", " "]
|
||||||
|
[10, "o", "\u001B[1D"]
|
||||||
|
[10, "o", "\u001B[?25h"]
|
||||||
|
[10, "o", "\u001B[38;5;9mOh no\u001B[0m\r\n"]
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ Spectre.Console will tell your terminal to use the color that is configured in t
|
|||||||
If you are using an 8 or 24-bit color for the foreground text, it is recommended that you also set an appropriate
|
If you are using an 8 or 24-bit color for the foreground text, it is recommended that you also set an appropriate
|
||||||
background color to match.
|
background color to match.
|
||||||
|
|
||||||
**Do** escape data when outputting any user input or any external data via Markup using the [`EscapeMarkup`](xref:M:Spectre.Console.Markup.Escape(System.String)) method on the data. Any user input containing `[` or `]` will likely cause a runtime error while rendering otherwise.
|
**Do** escape data when outputting any user input or any external data via Markup using the [`Markup.Escape`](xref:M:Spectre.Console.Markup.Escape(System.String)) method on the data. Any user input containing `[` or `]` will likely cause a runtime error while rendering otherwise.
|
||||||
|
|
||||||
**Consider** replacing `Markup` and `MarkupLine` with [`MarkupInterpolated`](xref:M:Spectre.Console.AnsiConsole.MarkupInterpolated(System.FormattableString)) and [`MarkupLineInterpolated`](xref:M:Spectre.Console.AnsiConsole.MarkupLineInterpolated(System.FormattableString)). Both these methods will automatically escape all data in the interpolated string holes. When working with widgets such as the Table and Tree, consider using [`Markup.FromInterpolated`](xref:M:Spectre.Console.Markup.FromInterpolated(System.FormattableString,Spectre.Console.Style)) to generate an `IRenderable` from an interpolated string.
|
**Consider** replacing `Markup` and `MarkupLine` with [`MarkupInterpolated`](xref:M:Spectre.Console.AnsiConsole.MarkupInterpolated(System.FormattableString)) and [`MarkupLineInterpolated`](xref:M:Spectre.Console.AnsiConsole.MarkupLineInterpolated(System.FormattableString)). Both these methods will automatically escape all data in the interpolated string holes. When working with widgets such as the Table and Tree, consider using [`Markup.FromInterpolated`](xref:M:Spectre.Console.Markup.FromInterpolated(System.FormattableString,Spectre.Console.Style)) to generate an `IRenderable` from an interpolated string.
|
||||||
|
|
||||||
@@ -85,10 +85,8 @@ on the main thread.
|
|||||||
### Unit Testing Best Practices
|
### Unit Testing Best Practices
|
||||||
|
|
||||||
For testing of console output, Spectre.Console has [`IAnsiConsole`](xref:T:Spectre.Console.IAnsiConsole) that can be
|
For testing of console output, Spectre.Console has [`IAnsiConsole`](xref:T:Spectre.Console.IAnsiConsole) that can be
|
||||||
injected into your application.
|
injected into your application. The [Spectre.Console.Test](https://www.nuget.org/packages/Spectre.Console.Testing/)
|
||||||
The [Spectre.Console.Test](https://www.nuget.org/packages/Spectre.Console.Testing/) contains a set of utilities for
|
NuGet package contains utilities for capturing the console output for verification. See the [Unit Testing](cli/unit-testing) page for further guidance.
|
||||||
capturing the output for verification, either manually or via a tool such
|
|
||||||
as [Verify](https://github.com/VerifyTests/Verify).
|
|
||||||
|
|
||||||
### Analyzer for Best Practices
|
### Analyzer for Best Practices
|
||||||
|
|
||||||
@@ -96,6 +94,31 @@ Spectre.Console has an [analyzer](https://www.nuget.org/packages/Spectre.Console
|
|||||||
common errors in writing console output from above such as using multiple live rendering widgets simultaneously,
|
common errors in writing console output from above such as using multiple live rendering widgets simultaneously,
|
||||||
or using the static `AnsiConsole` class when `IAnsiConsole` is available.
|
or using the static `AnsiConsole` class when `IAnsiConsole` is available.
|
||||||
|
|
||||||
|
### Native AOT Support
|
||||||
|
|
||||||
|
Publishing your app as Native AOT with Spectre.Console produces an app that's self-contained and has been ahead-of-time (AOT) compiled to native code. Native AOT apps have faster startup time and smaller memory footprints. These apps can run on machines that don't have the .NET runtime installed.
|
||||||
|
|
||||||
|
To enable AOT support on your application, Add `<PublishAot>true</PublishAot>` to your project file.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<PropertyGroup>
|
||||||
|
<PublishAot>true</PublishAot>
|
||||||
|
</PropertyGroup>
|
||||||
|
```
|
||||||
|
|
||||||
|
Current Spectre.Console support for AOT:
|
||||||
|
|
||||||
|
* ☑️ Spectre.Console
|
||||||
|
* ❌ Spectre.Console.Cli
|
||||||
|
* ☑️ Spectre.Console.Json
|
||||||
|
* ☑️ Spectre.Console.ImageSharp
|
||||||
|
|
||||||
|
Spectre.Console.Cli relies on reflection and discovering types at runtime, preventing it from currently supporting AOT.
|
||||||
|
|
||||||
|
Spectre.Console supports AOT, but with the following limitations
|
||||||
|
|
||||||
|
* `WriteException` will output a simple stacktrace and ignore any `ExceptionFormats` set.
|
||||||
|
|
||||||
### Configuring the Windows Terminal For Unicode and Emoji Support
|
### Configuring the Windows Terminal For Unicode and Emoji Support
|
||||||
|
|
||||||
Windows Terminal supports Unicode and Emoji. However, the shells such as Powershell and cmd.exe do not.
|
Windows Terminal supports Unicode and Emoji. However, the shells such as Powershell and cmd.exe do not.
|
||||||
@@ -119,4 +142,4 @@ For cmd.exe, the following steps are required to enable Unicode and Emoji suppor
|
|||||||
5. Reboot.
|
5. Reboot.
|
||||||
|
|
||||||
You will also need to ensure that your Console application is configured to use a font that supports Unicode and Emoji,
|
You will also need to ensure that your Console application is configured to use a font that supports Unicode and Emoji,
|
||||||
such as Cascadia Code.
|
such as Cascadia Code.
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
Title: Spectre.Console 0.48 released!
|
||||||
|
Description: .NET 8, custom help providers, and more!
|
||||||
|
Published: 2023-11-22
|
||||||
|
Category: Release Notes
|
||||||
|
Excluded: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Version 0.48 of Spectre.Console has been released!
|
||||||
|
|
||||||
|
Several rendering issues have been addressed, such as fixing problems related to rendering inside status causing corrupt output, avoiding exceptions on Rows with no children, as well as addressing rendering bugs in TextPath.
|
||||||
|
|
||||||
|
New features have been added, such as the ability to show separators between table rows. Other notable additions include progress bar header and footer support, customizable (and localizable) help providers, and the option to style text and confirmation prompts.
|
||||||
|
|
||||||
|
# New Contributors
|
||||||
|
|
||||||
|
* [@icalvo](https://github.com/icalvo) made their first contribution in [#1215](https://github.com/spectreconsole/spectre.console/pull/1215)
|
||||||
|
* [@fredrikbentzen](https://github.com/fredrikbentzen) made their first contribution in [#1132](https://github.com/spectreconsole/spectre.console/pull/1132)
|
||||||
|
* [@jeppevammenkristensen](https://github.com/jeppevammenkristensen) made their first contribution in [#1241](https://github.com/spectreconsole/spectre.console/pull/1241)
|
||||||
|
* [@tomaszprasolek](https://github.com/tomaszprasolek) made their first contribution in [#1257](https://github.com/spectreconsole/spectre.console/pull/1257)
|
||||||
|
* [@olabacker](https://github.com/olabacker) made their first contribution in [#1302](https://github.com/spectreconsole/spectre.console/pull/1302)
|
||||||
|
* [@AndrewRathbun](https://github.com/AndrewRathbun) made their first contribution in [#1315](https://github.com/spectreconsole/spectre.console/pull/1315)
|
||||||
|
|
||||||
|
|
||||||
|
# What's Changed
|
||||||
|
|
||||||
|
## Rendering
|
||||||
|
|
||||||
|
* Add .NET 8 support by [@patriksvensson](https://github.com/patriksvensson) in [#1367](https://github.com/spectreconsole/spectre.console/pull/1367)
|
||||||
|
* Fixed render issue where writeline inside status caused corrupt output #415 #694 by [@fredrikbentzen](https://github.com/fredrikbentzen) in [#1132](https://github.com/spectreconsole/spectre.console/pull/1132)
|
||||||
|
* Relax the SDK requirements by rolling forward to the latest feature by [@0xced](https://github.com/0xced) in [#1237](https://github.com/spectreconsole/spectre.console/pull/1237)
|
||||||
|
* Add fix to avoid exception on rows with no children by [@jeppevammenkristensen](https://github.com/jeppevammenkristensen) in [#1241](https://github.com/spectreconsole/spectre.console/pull/1241)
|
||||||
|
* Set `end_of_line` to `LF` instead of `CRLF` by [@0xced](https://github.com/0xced) in [#1256](https://github.com/spectreconsole/spectre.console/pull/1256)
|
||||||
|
* Fix `Rule` widget docs by [@tomaszprasolek](https://github.com/tomaszprasolek) in [#1257](https://github.com/spectreconsole/spectre.console/pull/1257)
|
||||||
|
* Added the missing columns-cast by [@nils](https://github.com/nils)-a in [#1294](https://github.com/spectreconsole/spectre.console/pull/1294)
|
||||||
|
* Render tables with zero-width columns by [@Frassle](https://github.com/Frassle) in [#1197](https://github.com/spectreconsole/spectre.console/pull/1197)
|
||||||
|
* Fix figlet centering possibly throwing due to negative size by [@olabacker](https://github.com/olabacker) in [#1302](https://github.com/spectreconsole/spectre.console/pull/1302)
|
||||||
|
* Add option to show separator between table rows by [@patriksvensson](https://github.com/patriksvensson) in [#1304](https://github.com/spectreconsole/spectre.console/pull/1304)
|
||||||
|
* Enable setting the color of the values in a `BreakdownChart` by [@nils](https://github.com/nils)-a in [#1303](https://github.com/spectreconsole/spectre.console/pull/1303)
|
||||||
|
* Progress bar header and footer by [@phil](https://github.com/phil)-scott-78 in [#1262](https://github.com/spectreconsole/spectre.console/pull/1262)
|
||||||
|
* Add an example showing the decorations off by [@Frassle](https://github.com/Frassle) in [#1191](https://github.com/spectreconsole/spectre.console/pull/1191)
|
||||||
|
* Fixes `TextPath` rendering bugs by [@patriksvensson](https://github.com/patriksvensson) in [#1308](https://github.com/spectreconsole/spectre.console/pull/1308)
|
||||||
|
* Fix greedy row measure by [@nils](https://github.com/nils)-a in [#1338](https://github.com/spectreconsole/spectre.console/pull/1338)
|
||||||
|
* Fix `AnsiConsoleOutput` safe height by [@0xced](https://github.com/0xced) in [#1358](https://github.com/spectreconsole/spectre.console/pull/1358)
|
||||||
|
* Allow passing a nullable style in `DefaultValueStyle()` and `ChoicesStyle()` by [@0xced](https://github.com/0xced) in [#1359](https://github.com/spectreconsole/spectre.console/pull/1359)
|
||||||
|
* Allow `ConfirmationPrompt` Styling by [@wbaldoumas](https://github.com/wbaldoumas) in [#1210](https://github.com/spectreconsole/spectre.console/pull/1210)
|
||||||
|
|
||||||
|
## CLI
|
||||||
|
* Add async command unit tests by [@FrankRay78](https://github.com/FrankRay78) in [#1228](https://github.com/spectreconsole/spectre.console/pull/1228)
|
||||||
|
* Add support for async delegate by [@icalvo](https://github.com/icalvo) in [#1215](https://github.com/spectreconsole/spectre.console/pull/1215)
|
||||||
|
* Remove unnecessary `[NotNull]` attributes by [@0xced](https://github.com/0xced) in [#1255](https://github.com/spectreconsole/spectre.console/pull/1255)
|
||||||
|
* Allow custom help providers by [@FrankRay78](https://github.com/FrankRay78) in [#1259](https://github.com/spectreconsole/spectre.console/pull/1259)
|
||||||
|
* Specified details for settings for the argument vector by [@nils](https://github.com/nils)-a in [#1301](https://github.com/spectreconsole/spectre.console/pull/1301)
|
||||||
|
* Add support for localisation in help provider by [@FrankRay78](https://github.com/FrankRay78) in [#1349](https://github.com/spectreconsole/spectre.console/pull/1349)
|
||||||
|
* Fix DefaultValue for `FileInfo` and `DirectoryInfo` by [@0xced](https://github.com/0xced) in [#1238](https://github.com/spectreconsole/spectre.console/pull/1238)
|
||||||
|
|
||||||
|
## Documentation & Samples
|
||||||
|
* Added a minimal PR template by [@nils](https://github.com/nils)-a in [#1318](https://github.com/spectreconsole/spectre.console/pull/1318)
|
||||||
|
* Fix typo in `showcase` sample by [@AndrewRathbun](https://github.com/AndrewRathbun) in [#1315](https://github.com/spectreconsole/spectre.console/pull/1315)
|
||||||
|
* Update `columns` sample to showcase nicer data by [@nils](https://github.com/nils)-a in [#1295](https://github.com/spectreconsole/spectre.console/pull/1295)
|
||||||
|
* Change all `SetErrorHandler` to `SetExceptionHandler` by [@nils](https://github.com/nils)-a in [#1298](https://github.com/spectreconsole/spectre.console/pull/1298)
|
||||||
|
|
||||||
|
## Other stuff
|
||||||
|
* Ensure the `Generator` project compiles by [@patriksvensson](https://github.com/patriksvensson) in [#1371](https://github.com/spectreconsole/spectre.console/pull/1371)
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
Title: Spectre.Console 0.49 released!
|
||||||
|
Description: Bug fixes, bug fixes, bug fixes
|
||||||
|
Published: 2024-04-23
|
||||||
|
Category: Release Notes
|
||||||
|
Excluded: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Version 0.49 of Spectre.Console has been released!
|
||||||
|
|
||||||
|
## New Contributors
|
||||||
|
* @baronfel made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1425
|
||||||
|
* @DarqueWarrior made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1431
|
||||||
|
* @tonycknight made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1435
|
||||||
|
* @caesay made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1439
|
||||||
|
* @jsheely made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1414
|
||||||
|
* @danielcweber made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1456
|
||||||
|
* @martincostello made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1477
|
||||||
|
* @slang25 made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1289
|
||||||
|
* @thomhurst made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1250
|
||||||
|
* @gerardog made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1489
|
||||||
|
* @yenneferofvengerberg made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1503
|
||||||
|
* @BlazeFace made their first contribution in https://github.com/spectreconsole/spectre.console/pull/1509
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
* Cleanup line endings by @nils-a in https://github.com/spectreconsole/spectre.console/pull/1381
|
||||||
|
* Added Spectre.Console.Cli to quick-start. by @nils-a in https://github.com/spectreconsole/spectre.console/pull/1413
|
||||||
|
* Fix rendering of ListPrompt for odd pageSizes by @nils-a in https://github.com/spectreconsole/spectre.console/pull/1365
|
||||||
|
* Remove mandelbrot example due to conflicting license by @patriksvensson in https://github.com/spectreconsole/spectre.console/pull/1426
|
||||||
|
* Allow specifying a property to ignore the use of build-time packages for versioning and analysis by @baronfel in https://github.com/spectreconsole/spectre.console/pull/1425
|
||||||
|
* Add the possibility to register multiple interceptors by @nils-a in https://github.com/spectreconsole/spectre.console/pull/1412
|
||||||
|
* Added the ITypeResolver to the ExceptionHandler by @nils-a in https://github.com/spectreconsole/spectre.console/pull/1411
|
||||||
|
* Updated typo in commandApp.md by @DarqueWarrior in https://github.com/spectreconsole/spectre.console/pull/1431
|
||||||
|
* Command with -v displays app version instead of executing the command by @FrankRay78 in https://github.com/spectreconsole/spectre.console/pull/1427
|
||||||
|
* HelpProvider colors should be configurable by @FrankRay78 in https://github.com/spectreconsole/spectre.console/pull/1408
|
||||||
|
* Direct contributors to the current CONTRIBUTING.md by @tonycknight in https://github.com/spectreconsole/spectre.console/pull/1435
|
||||||
|
* Fix deadlock when cancelling prompts by @caesay in https://github.com/spectreconsole/spectre.console/pull/1439
|
||||||
|
* Add progress bar value formatter by @jsheely in https://github.com/spectreconsole/spectre.console/pull/1414
|
||||||
|
* Update dependencies and do some clean-up by @patriksvensson in https://github.com/spectreconsole/spectre.console/pull/1440
|
||||||
|
* Delete [UsesVerify], which has become obsolete through the latest update. by @danielcweber in https://github.com/spectreconsole/spectre.console/pull/1456
|
||||||
|
* Don't erase secret prompt text upon backspace when mask is null by @danielcweber in https://github.com/spectreconsole/spectre.console/pull/1458
|
||||||
|
* Update dependencies to the latest version by @patriksvensson in https://github.com/spectreconsole/spectre.console/pull/1459
|
||||||
|
* Automatically register command settings by @patriksvensson in https://github.com/spectreconsole/spectre.console/pull/1463
|
||||||
|
* Remove [DebuggerDisplay] from Paragraph by @martincostello in https://github.com/spectreconsole/spectre.console/pull/1477
|
||||||
|
* Selection Prompt Search by @slang25 in https://github.com/spectreconsole/spectre.console/pull/1289
|
||||||
|
* Update dependency SixLabors.ImageSharp to v3.1.3 by @renovate in https://github.com/spectreconsole/spectre.console/pull/1486
|
||||||
|
* Positioned Progress Tasks - Before or After Other Tasks by @thomhurst in https://github.com/spectreconsole/spectre.console/pull/1250
|
||||||
|
* Added NoStackTrace to ExceptionFormats by @gerardog in https://github.com/spectreconsole/spectre.console/pull/1489
|
||||||
|
* Pipe character for listing options (issue 1434) by @FrankRay78 in https://github.com/spectreconsole/spectre.console/pull/1498
|
||||||
|
* Improve XmlDoc output by @yenneferofvengerberg in https://github.com/spectreconsole/spectre.console/pull/1503
|
||||||
|
* Revert 71a5d830 to undo flickering regression by @phil-scott-78 in https://github.com/spectreconsole/spectre.console/pull/1504
|
||||||
|
* AddDelegate uses an abstract type when used in a branch by @BlazeFace in https://github.com/spectreconsole/spectre.console/pull/1509
|
||||||
|
* Missing Separator When Headers are Hidden by @BlazeFace in https://github.com/spectreconsole/spectre.console/pull/1513
|
||||||
|
* Expose raw arguments on the command context by @patriksvensson in https://github.com/spectreconsole/spectre.console/pull/1523
|
||||||
|
* Add token representation to remaining arguments by @patriksvensson in https://github.com/spectreconsole/spectre.console/pull/1525
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
Title: Spectre.Console 0.50 released!
|
||||||
|
Description: Now with 25% less lead!
|
||||||
|
Published: 2025-04-08
|
||||||
|
Category: Release Notes
|
||||||
|
Excluded: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Version 0.50 of Spectre.Console has been released!
|
||||||
|
|
||||||
|
## New Contributors
|
||||||
|
|
||||||
|
* [@Kissaki](https://github.com/Kissaki) made their first contribution in [#1575](https://github.com/spectreconsole/spectre.console/pull/1575)
|
||||||
|
* [@z4ryy](https://github.com/z4ryy) made their first contribution in [#1590](https://github.com/spectreconsole/spectre.console/pull/1590)
|
||||||
|
* [@TonWin618](https://github.com/TonWin618) made their first contribution in [#1595](https://github.com/spectreconsole/spectre.console/pull/1595)
|
||||||
|
* [@KirillOsenkov](https://github.com/KirillOsenkov) made their first contribution in [#1623](https://github.com/spectreconsole/spectre.console/pull/1623)
|
||||||
|
* [@davide-pi](https://github.com/davide-pi) made their first contribution in [#1246](https://github.com/spectreconsole/spectre.console/pull/1246)
|
||||||
|
* [@armanossiloko](https://github.com/armanossiloko) made their first contribution in [#1668](https://github.com/spectreconsole/spectre.console/pull/1668)
|
||||||
|
* [@PascalSenn](https://github.com/PascalSenn) made their first contribution in [#1687](https://github.com/spectreconsole/spectre.console/pull/1687)
|
||||||
|
* [@tpill90](https://github.com/tpill90) made their first contribution in [#904](https://github.com/spectreconsole/spectre.console/pull/904)
|
||||||
|
* [@tmds](https://github.com/tmds) made their first contribution in [#1194](https://github.com/spectreconsole/spectre.console/pull/1194)
|
||||||
|
* [@TheMarteh](https://github.com/TheMarteh) made their first contribution in [#1708](https://github.com/spectreconsole/spectre.console/pull/1708)
|
||||||
|
* [@Tolitech](https://github.com/Tolitech) made their first contribution in [#1717](https://github.com/spectreconsole/spectre.console/pull/1717)
|
||||||
|
* [@TheTonttu](https://github.com/TheTonttu) made their first contribution in [#1740](https://github.com/spectreconsole/spectre.console/pull/1740)
|
||||||
|
* [@byte2pixel](https://github.com/byte2pixel) made their first contribution in [#1762](https://github.com/spectreconsole/spectre.console/pull/1762)
|
||||||
|
* [@Moustafaa91](https://github.com/Moustafaa91) made their first contribution in [#1779](https://github.com/spectreconsole/spectre.console/pull/1779)
|
||||||
|
|
||||||
|
### General
|
||||||
|
|
||||||
|
* Strong name the assemblies by [@KirillOsenkov](https://github.com/KirillOsenkov) in [#1623](https://github.com/spectreconsole/spectre.console/pull/1623)
|
||||||
|
* Update MSDN link to learn.microsoft.com by [@Kissaki](https://github.com/Kissaki) in [#1575](https://github.com/spectreconsole/spectre.console/pull/1575)
|
||||||
|
* Add spanish translation for help strings by [@kzu](https://github.com/kzu) in [#1597](https://github.com/spectreconsole/spectre.console/pull/1597)
|
||||||
|
* Update documentation: add example for the Text Prompt usage by [@davide-pi](https://github.com/davide-pi) in [#1636](https://github.com/spectreconsole/spectre.console/pull/1636)
|
||||||
|
* Fix typos xml docs by [@devlead](https://github.com/devlead) in [#1684](https://github.com/spectreconsole/spectre.console/pull/1684)
|
||||||
|
* Upgrade SixLabors.ImageSharp to 3.1.7 by [@Moustafaa91](https://github.com/Moustafaa91) in [#1779](https://github.com/spectreconsole/spectre.console/pull/1779)
|
||||||
|
|
||||||
|
### Console
|
||||||
|
|
||||||
|
* AOT Support for Spectre.Console by [@phil-scott-78](https://github.com/phil-scott-78) in [#1690](https://github.com/spectreconsole/spectre.console/pull/1690)
|
||||||
|
* Make method reference to Markup.Escape more obvious by [@Kissaki](https://github.com/Kissaki) in [#1574](https://github.com/spectreconsole/spectre.console/pull/1574)
|
||||||
|
* Fix `HtmlEncoder` Incorrectly Applying Italics to Bold Text by [@z4ryy](https://github.com/z4ryy) in [#1590](https://github.com/spectreconsole/spectre.console/pull/1590)
|
||||||
|
* Fix Console Display Issue with Deleting Wide Characters by [@TonWin618](https://github.com/TonWin618) in [#1595](https://github.com/spectreconsole/spectre.console/pull/1595)
|
||||||
|
* Fix search bug in prompt related to custom item types by [@patriksvensson](https://github.com/patriksvensson) in [#1627](https://github.com/spectreconsole/spectre.console/pull/1627)
|
||||||
|
* Cleanup the prompt tests by [@0xced](https://github.com/0xced) in [#1635](https://github.com/spectreconsole/spectre.console/pull/1635)
|
||||||
|
* Add custom style for each calendar event by [@davide-pi](https://github.com/davide-pi) in [#1246](https://github.com/spectreconsole/spectre.console/pull/1246)
|
||||||
|
* Fix tree expansion bug by [@davide-pi](https://github.com/davide-pi) in [#1245](https://github.com/spectreconsole/spectre.console/pull/1245)
|
||||||
|
* Enhance the style of the checkboxes for multi-selection by [@davide-pi](https://github.com/davide-pi) in [#1244](https://github.com/spectreconsole/spectre.console/pull/1244)
|
||||||
|
* Improve exception if a (multi)selection prompt is used incorrectly by [@0xced](https://github.com/0xced) in [#1637](https://github.com/spectreconsole/spectre.console/pull/1637)
|
||||||
|
* Fix incorrect panel height calculation in complex layout by [@BlazeFace](https://github.com/BlazeFace) in [#1514](https://github.com/spectreconsole/spectre.console/pull/1514)
|
||||||
|
* Adding Enricher for Azure Pipelines by [@BlazeFace](https://github.com/BlazeFace) in [#1675](https://github.com/spectreconsole/spectre.console/pull/1675)
|
||||||
|
* Added hex color conversion by [@jsheely](https://github.com/jsheely) in [#1432](https://github.com/spectreconsole/spectre.console/pull/1432)
|
||||||
|
* Fixed type in Segment description by [@PascalSenn](https://github.com/PascalSenn) in [#1687](https://github.com/spectreconsole/spectre.console/pull/1687)
|
||||||
|
* Adding TransferSpeedColumn configuration to display bits/bytes + binary/decimal prefixes by [@tpill90](https://github.com/tpill90) in [#904](https://github.com/spectreconsole/spectre.console/pull/904)
|
||||||
|
* Changes Emoji dictionary to OrdinalIgnoreCase for performance by [@phil-scott-78](https://github.com/phil-scott-78) in [#1691](https://github.com/spectreconsole/spectre.console/pull/1691)
|
||||||
|
* ProgressTask.GetPercentage() returns 100 when max value is 0 by [@FrankRay78](https://github.com/FrankRay78) in [#1694](https://github.com/spectreconsole/spectre.console/pull/1694)
|
||||||
|
* Async overloads for AnsiConsole Prompt/Ask/Confirm. by [@tmds](https://github.com/tmds) in [#1194](https://github.com/spectreconsole/spectre.console/pull/1194)
|
||||||
|
* Support 3-digit hex codes in markup by [@TheMarteh](https://github.com/TheMarteh) in [#1708](https://github.com/spectreconsole/spectre.console/pull/1708)
|
||||||
|
* Add async spinner extension methods and related documentation by [@phil-scott-78](https://github.com/phil-scott-78) in [#1747](https://github.com/spectreconsole/spectre.console/pull/1747)
|
||||||
|
* Fix generic exception formatting by [@0xced](https://github.com/0xced) in [#1755](https://github.com/spectreconsole/spectre.console/pull/1755)
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
* Remove redundant explain settings ctor by [@gitfool](https://github.com/gitfool) in [#1534](https://github.com/spectreconsole/spectre.console/pull/1534)
|
||||||
|
* Trim trailing comma in settings by [@devlead](https://github.com/devlead) in [#1550](https://github.com/spectreconsole/spectre.console/pull/1550)
|
||||||
|
* Consider -? as an alias to -h by [@kzu](https://github.com/kzu) in [#1552](https://github.com/spectreconsole/spectre.console/pull/1552)
|
||||||
|
* Trimming of TestConsole output by CommandAppTester is user configurable. by [@FrankRay78](https://github.com/FrankRay78) in [#1739](https://github.com/spectreconsole/spectre.console/pull/1739)
|
||||||
|
* Include resource files for additional cultures in HelpProvider. by [@Tolitech](https://github.com/Tolitech) in [#1717](https://github.com/spectreconsole/spectre.console/pull/1717)
|
||||||
|
* Conditionally trim trailing periods of argument and option descriptions by [@TheTonttu](https://github.com/TheTonttu) in [#1740](https://github.com/spectreconsole/spectre.console/pull/1740)
|
||||||
|
* Changed IConfigurator to return IConfigurator instead of void by [@byte2pixel](https://github.com/byte2pixel) in [#1762](https://github.com/spectreconsole/spectre.console/pull/1762)
|
||||||
|
* Add parsed unknown flag to remaining arguments for a branch with a default command by [@FrankRay78](https://github.com/FrankRay78) in [#1660](https://github.com/spectreconsole/spectre.console/pull/1660)
|
||||||
|
* Correctly show application version; execution of command with version option by [@FrankRay78](https://github.com/FrankRay78) in [#1663](https://github.com/spectreconsole/spectre.console/pull/1663)
|
||||||
|
* Help output correctly decides when to show the version option by [@FrankRay78](https://github.com/FrankRay78) in [#1664](https://github.com/spectreconsole/spectre.console/pull/1664)
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
Title: Spectre.Console 0.51.1 released!
|
||||||
|
Description: Not a substitute for human interaction.
|
||||||
|
Published: 2025-09-07
|
||||||
|
Category: Release Notes
|
||||||
|
Excluded: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Version `0.51.1` of Spectre.Console has been released!
|
||||||
|
|
||||||
|
_Note: Due to an issue discovered after the release of version 0.51.0, that version has now been unlisted. Let’s all pretend it never existed 😅_
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
|
||||||
|
* Fix IndexOutOfRangeException in ExceptionFormatter by [@martincostello](https://github.com/martincostello) in [#1800](https://github.com/spectreconsole/spectre.console/pull/1800)
|
||||||
|
* TestConsole can now be configured and accessed in CommandAppTester by [@magiino](https://github.com/magiino) in [#1803](https://github.com/spectreconsole/spectre.console/pull/1803)
|
||||||
|
* Add ShowRowSeparators in Table Widget docs by [@bartoginski](https://github.com/bartoginski) in [#1807](https://github.com/spectreconsole/spectre.console/pull/1807)
|
||||||
|
* Add support for required options by [@patriksvensson](https://github.com/patriksvensson) in [#1825](https://github.com/spectreconsole/spectre.console/pull/1825)
|
||||||
|
* Added documentation for align widget by [@Elementttto](https://github.com/Elementttto) in [#1746](https://github.com/spectreconsole/spectre.console/pull/1746)
|
||||||
|
* Fixed link not displayed in markup in Style.cs and added unit test cases by [@Elementttto](https://github.com/Elementttto) in [#1750](https://github.com/spectreconsole/spectre.console/pull/1750)
|
||||||
|
* Update System.Memory dependency by [@WeihanLi](https://github.com/WeihanLi) in [#1832](https://github.com/spectreconsole/spectre.console/pull/1832)
|
||||||
|
* Reduce memory usage for rune width cache. by [@Pannoniae](https://github.com/Pannoniae) in [#1756](https://github.com/spectreconsole/spectre.console/pull/1756)
|
||||||
|
* Fix resizing of Live views with reduced size. by [@belucha](https://github.com/belucha) in [#1840](https://github.com/spectreconsole/spectre.console/pull/1840)
|
||||||
|
* Corrects comment for optional text prompt by [@aljanabim](https://github.com/aljanabim) in [#1857](https://github.com/spectreconsole/spectre.console/pull/1857)
|
||||||
|
* Update spinners by [@FroggieFrog](https://github.com/FroggieFrog) in [#1873](https://github.com/spectreconsole/spectre.console/pull/1873)
|
||||||
|
* Support J and K for navigating list prompts by [@tobias-tengler](https://github.com/tobias-tengler) in [#1877](https://github.com/spectreconsole/spectre.console/pull/1877)
|
||||||
|
* Fix space triggering selection when items in the selection list have a space. by [@mitchdenny](https://github.com/mitchdenny) in [#1881](https://github.com/spectreconsole/spectre.console/pull/1881)
|
||||||
|
* Fix bug setting Header by [@mattfennerom](https://github.com/mattfennerom) in [#1890](https://github.com/spectreconsole/spectre.console/pull/1890)
|
||||||
|
|
||||||
|
## New Contributors
|
||||||
|
|
||||||
|
* [@magiino](https://github.com/magiino) made their first contribution in [#1803](https://github.com/spectreconsole/spectre.console/pull/1803)
|
||||||
|
* [@bartoginski](https://github.com/bartoginski) made their first contribution in [#1807](https://github.com/spectreconsole/spectre.console/pull/1807)
|
||||||
|
* [@Elementttto](https://github.com/Elementttto) made their first contribution in [#1746](https://github.com/spectreconsole/spectre.console/pull/1746)
|
||||||
|
* [@WeihanLi](https://github.com/WeihanLi) made their first contribution in [#1832](https://github.com/spectreconsole/spectre.console/pull/1832)
|
||||||
|
* [@Pannoniae](https://github.com/Pannoniae) made their first contribution in [#1756](https://github.com/spectreconsole/spectre.console/pull/1756)
|
||||||
|
* [@belucha](https://github.com/belucha) made their first contribution in [#1840](https://github.com/spectreconsole/spectre.console/pull/1840)
|
||||||
|
* [@aljanabim](https://github.com/aljanabim) made their first contribution in [#1857](https://github.com/spectreconsole/spectre.console/pull/1857)
|
||||||
|
* [@FroggieFrog](https://github.com/FroggieFrog) made their first contribution in [#1873](https://github.com/spectreconsole/spectre.console/pull/1873)
|
||||||
|
* [@tobias-tengler](https://github.com/tobias-tengler) made their first contribution in [#1877](https://github.com/spectreconsole/spectre.console/pull/1877)
|
||||||
|
* [@mitchdenny](https://github.com/mitchdenny) made their first contribution in [#1881](https://github.com/spectreconsole/spectre.console/pull/1881)
|
||||||
|
* [@mattfennerom](https://github.com/mattfennerom) made their first contribution in [#1890](https://github.com/spectreconsole/spectre.console/pull/1890)
|
||||||
|
|
||||||
|
**Full Changelog**: [0.50.0...0.51.0](https://github.com/spectreconsole/spectre.console/compare/0.50.0...0.51.1)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
Title: Spectre.Console 0.52.0 released!
|
||||||
|
Description: Don't eat (too much) glue.
|
||||||
|
Published: 2025-10-10
|
||||||
|
Category: Release Notes
|
||||||
|
Excluded: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Version `0.52.0` of Spectre.Console has been released!
|
||||||
|
|
||||||
|
Exciting things are happening. We’ve merged support for my love child, OpenCli, in this release. That means you can now pass the parameter `--help-dump-opencli` to your application to get an [OpenCli](https://opencli.org) description dumped to stdout.
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
|
||||||
|
* Add OpenCLI integration to Spectre.Console.Cli by [@patriksvensson](https://github.com/patriksvensson) in [#1909](https://github.com/spectreconsole/spectre.console/pull/1909)
|
||||||
|
* Fix OPENCLI_VISIBILITY_INTERNAL to DefineConstants concat by [@devlead](https://github.com/devlead) in [#1912](https://github.com/spectreconsole/spectre.console/pull/1912)
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/spectreconsole/spectre.console/compare/0.51.1...0.52.0
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
@{
|
@{
|
||||||
Layout = @$"_layout.cshtml";
|
Layout = "_layout.cshtml";
|
||||||
}
|
}
|
||||||
@@ -1,47 +1,75 @@
|
|||||||
Title: Command Help
|
Title: Command Help
|
||||||
Order: 13
|
Order: 13
|
||||||
Description: "Console applications built with *Spectre.Console.Cli* include automatically generated help command line help."
|
Description: "Console applications built with *Spectre.Console.Cli* include automatically generated help command line help."
|
||||||
---
|
---
|
||||||
|
|
||||||
Console applications built with `Spectre.Console.Cli` include automatically generated help which is displayed when `-h` or `--help` has been specified on the command line.
|
Console applications built with `Spectre.Console.Cli` include automatically generated help which is displayed when `-h` or `--help` has been specified on the command line.
|
||||||
|
|
||||||
The automatically generated help is derived from the configured commands and their command settings.
|
The automatically generated help is derived from the configured commands and their command settings.
|
||||||
|
|
||||||
The help is also context aware and tailored depending on what has been specified on the command line before it. For example,
|
The help is also context aware and tailored depending on what has been specified on the command line before it. For example,
|
||||||
|
|
||||||
1. When `-h` or `--help` appears immediately after the application name (eg. `application.exe --help`), then the help displayed is a high-level summary of the application, including any command line examples and a listing of all possible commands the user can execute.
|
1. When `-h` or `--help` appears immediately after the application name (eg. `application.exe --help`), then the help displayed is a high-level summary of the application, including any command line examples and a listing of all possible commands the user can execute.
|
||||||
|
|
||||||
2. When `-h` or `--help` appears immediately after a command has been specified (eg. `application.exe command --help`), then the help displayed is specific to the command and includes information about command specific switches and any default values.
|
2. When `-h` or `--help` appears immediately after a command has been specified (eg. `application.exe command --help`), then the help displayed is specific to the command and includes information about command specific switches and any default values.
|
||||||
|
|
||||||
`HelpProvider` is the `Spectre.Console` class responsible for determining context and preparing the help text to write to the console. It is an implementation of the public interface `IHelpProvider`.
|
`HelpProvider` is the `Spectre.Console` class responsible for determining context and preparing the help text to write to the console. It is an implementation of the public interface `IHelpProvider`.
|
||||||
|
|
||||||
## Custom help providers
|
## Styling the help text
|
||||||
|
|
||||||
Whilst it shouldn't be common place to implement your own help provider, it is however possible.
|
Basic styling is applied to the generated help text by default, however this is configurable.
|
||||||
|
|
||||||
You are able to implement your own `IHelpProvider` and configure a `CommandApp` to use that instead of the Spectre.Console help provider.
|
`HelpProviderStyle` is the `Spectre.Console` class that holds the style information for the help text.
|
||||||
|
|
||||||
```csharp
|
The default theme shipped with Spectre.Console is provided by a factory method, `HelpProviderStyle.Default`.
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
However, you can explicitly set a custom theme when configuring a CommandApp, for example:
|
||||||
namespace Help;
|
|
||||||
|
```csharp
|
||||||
public static class Program
|
config.Settings.HelpProviderStyles = new HelpProviderStyle()
|
||||||
{
|
{
|
||||||
public static int Main(string[] args)
|
Description = new DescriptionStyle()
|
||||||
{
|
{
|
||||||
var app = new CommandApp<DefaultCommand>();
|
Header = "bold",
|
||||||
|
},
|
||||||
app.Configure(config =>
|
};
|
||||||
{
|
```
|
||||||
// Register the custom help provider
|
|
||||||
config.SetHelpProvider(new CustomHelpProvider(config.Settings));
|
Removing all styling from help text is also possible, a good choice for ensuring maximum accessibility. This is configured by clearing the style provider entirely:
|
||||||
});
|
|
||||||
|
```csharp
|
||||||
return app.Run(args);
|
config.Settings.HelpProviderStyles = null;
|
||||||
}
|
```
|
||||||
}
|
|
||||||
```
|
See [Markup](../markup) for information about the use of markup in Spectre.Console, and [Styles](xref:appendix-styles) for a listing of supported styles.
|
||||||
|
|
||||||
There is a working [example of a custom help provider](https://github.com/spectreconsole/spectre.console/tree/main/examples/Cli/Help) demonstrating this.
|
## Custom help providers
|
||||||
|
|
||||||
|
Whilst it shouldn't be common place to implement your own help provider, it is however possible.
|
||||||
|
|
||||||
|
You are able to implement your own `IHelpProvider` and configure a `CommandApp` to use that instead of the Spectre.Console help provider.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Help;
|
||||||
|
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandApp<DefaultCommand>();
|
||||||
|
|
||||||
|
app.Configure(config =>
|
||||||
|
{
|
||||||
|
// Register the custom help provider
|
||||||
|
config.SetHelpProvider(new CustomHelpProvider(config.Settings));
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.Run(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
There is a working [example of a custom help provider](https://github.com/spectreconsole/examples/tree/main/examples/Cli/Help) demonstrating this.
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ app.Configure(config =>
|
|||||||
|
|
||||||
## Multiple Commands
|
## Multiple Commands
|
||||||
|
|
||||||
In the previous example we have a single command that is configured. For complex command line applications, it is common for them to have multiple commands (or verbs) defined. Examples of applications like this are `git`, `dotnet` and `gh`. For example, git would have a `commit` command and along with other commits like `add` or `rebase`. Each with their own settings and validation. With `Spectre.Console.Cli` we use the `Configure` method to add these commands.
|
In the previous example we have a single command that is configured. For complex command line applications, it is common for them to have multiple commands (or verbs) defined. Examples of applications like this are `git`, `dotnet` and `gh`. For example, git would have a `commit` command and along with other commands like `add` or `rebase`. Each with their own settings and validation. With `Spectre.Console.Cli` we use the `Configure` method to add these commands.
|
||||||
|
|
||||||
For example, to add three different commands to the application:
|
For example, to add three different commands to the application:
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ registrations.AddSingleton<IGreeter, HelloWorldGreeter>();
|
|||||||
|
|
||||||
// Create a type registrar and register any dependencies.
|
// Create a type registrar and register any dependencies.
|
||||||
// A type registrar is an adapter for a DI framework.
|
// A type registrar is an adapter for a DI framework.
|
||||||
var registrar = new TypeRegistrar(registrations);
|
var registrar = new MyTypeRegistrar(registrations);
|
||||||
|
|
||||||
// Create a new command app with the registrar
|
// Create a new command app with the registrar
|
||||||
// and run it with the provided arguments.
|
// and run it with the provided arguments.
|
||||||
@@ -75,15 +75,21 @@ var app = new CommandApp<DefaultCommand>(registrar);
|
|||||||
return app.Run(args);
|
return app.Run(args);
|
||||||
```
|
```
|
||||||
|
|
||||||
`TypeRegistrar` is a custom class that must be created by the user. This [example using `Microsoft.Extensions.DependencyInjection` as the container](https://github.com/spectreconsole/spectre.console/tree/main/examples/Cli/Injection) provides an example `TypeRegistrar` and `TypeResolver` that can be added to your application with small adjustments for your DI container.
|
<?# Alert ?>
|
||||||
|
`MyTypeRegistrar` is a custom class that implements [ITypeRegistrar](xref:T:Spectre.Console.Cli.ITypeRegistrar) and must be provided by the user.
|
||||||
|
<?#/ Alert ?>
|
||||||
|
|
||||||
Hint: If you do write your own implementation of `TypeRegistrar` and `TypeResolver` and you have some form of unit tests in place for your project,
|
There is a working [example of dependency injection](https://github.com/spectreconsole/examples/tree/main/examples/Cli/Injection) that uses `Microsoft.Extensions.DependencyInjection` as the container. Example implementations of `ITypeRegistrar` and `ITypeResolver` are provided, which you can copy and paste to your application for dependency injection.
|
||||||
there is a utility `TypeRegistrarBaseTests` available that can be used to ensure your implementations adhere to the required implementation. Simply call `TypeRegistrarBaseTests.RunAllTests()` and expect no `TypeRegistrarBaseTests.TestFailedException` to be thrown.
|
|
||||||
|
Unit testing your `ITypeRegistrar` and `ITypeResolver` implementations is done using the utility `TypeRegistrarBaseTests` included in `Spectre.Console.Testing`. Simply call `TypeRegistrarBaseTests.RunAllTests()` and expect no `TypeRegistrarBaseTests.TestFailedException` to be thrown.
|
||||||
|
|
||||||
## Interception
|
## Interception
|
||||||
|
Interceptors can be registered with the `TypeRegistrar` (or with a custom DI-Container). Alternatively, `CommandApp` also provides a `SetInterceptor` configuration.
|
||||||
|
|
||||||
`CommandApp` also provides a `SetInterceptor` configuration. An interceptor is run before all commands are executed. This is typically used for configuring logging or other infrastructure concerns.
|
All interceptors must implement `ICommandInterceptor`. Upon execution of a command, The `Intercept`-Method of an instance of your interceptor will be called with the parsed settings. This provides an opportunity for configuring any infrastructure or modifying the settings.
|
||||||
|
When the command has been run, the `InterceptResult`-Method of the same instance is called with the result of the command.
|
||||||
|
This provides an opportunity to modify the result and also to tear down any infrastructure in use.
|
||||||
|
|
||||||
All interceptors must implement `ICommandInterceptor`. Upon execution of a command, an instance of your interceptor will be called with the parsed settings. This provides an opportunity for configuring any infrastructure or modifying the settings.
|
The `Intercept`-Method of each interceptor is run before the command is executed and the `InterceptResult`-Method is run after it. These are typically used for configuring logging or other infrastructure concerns.
|
||||||
|
|
||||||
For an example of using the interceptor to configure logging, see the [Serilog demo](https://github.com/spectreconsole/spectre.console/tree/main/examples/Cli/Logging).
|
For an example of using the interceptor to configure logging, see the [Serilog demo](https://github.com/spectreconsole/examples/tree/main/examples/Cli/Logging)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class HelloCommand : Command<HelloCommand.Settings>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override int Execute(CommandContext context, Settings settings)
|
public override int Execute(CommandContext context, Settings settings, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
AnsiConsole.MarkupLine($"Hello, [blue]{settings.Name}[/]");
|
AnsiConsole.MarkupLine($"Hello, [blue]{settings.Name}[/]");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
Title: Composing Commands
|
Title: Composing Commands
|
||||||
RedirectFrom: introduction
|
RedirectFrom: introduction
|
||||||
Order: 8
|
Order: 8
|
||||||
Description: "The underlying philosophy behind *Spectre.Console.Cli* is to rely on the .NET type system to
|
Description: The underlying philosophy behind *Spectre.Console.Cli* is
|
||||||
declare the commands, but tie everything together via composition."
|
to rely on the .NET type system to declare the commands, but tie everything together via composition.
|
||||||
---
|
---
|
||||||
|
|
||||||
The underlying philosophy behind `Spectre.Console.Cli` is to rely on the .NET type system to
|
The underlying philosophy behind `Spectre.Console.Cli` is to rely on the .NET type system to
|
||||||
@@ -55,7 +55,7 @@ in the previous step.
|
|||||||
```csharp
|
```csharp
|
||||||
public class AddPackageCommand : Command<AddPackageSettings>
|
public class AddPackageCommand : Command<AddPackageSettings>
|
||||||
{
|
{
|
||||||
public override int Execute(CommandContext context, AddPackageSettings settings)
|
public override int Execute(CommandContext context, AddPackageSettings settings, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Omitted
|
// Omitted
|
||||||
return 0;
|
return 0;
|
||||||
@@ -64,7 +64,7 @@ public class AddPackageCommand : Command<AddPackageSettings>
|
|||||||
|
|
||||||
public class AddReferenceCommand : Command<AddReferenceSettings>
|
public class AddReferenceCommand : Command<AddReferenceSettings>
|
||||||
{
|
{
|
||||||
public override int Execute(CommandContext context, AddReferenceSettings settings)
|
public override int Execute(CommandContext context, AddReferenceSettings settings, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Omitted
|
// Omitted
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -53,7 +53,11 @@ Using the `SetExceptionHandler()` during configuration it is possible to handle
|
|||||||
This method comes in two flavours: One that uses the default exitCode (or `return` value) of `-1` and one
|
This method comes in two flavours: One that uses the default exitCode (or `return` value) of `-1` and one
|
||||||
where the exitCode needs to be supplied.
|
where the exitCode needs to be supplied.
|
||||||
|
|
||||||
### Using `SetExceptionHandler(Func<Exception, int> handler)`
|
The `ITypeResolver?` parameter will be null, when the exception occurs while no `ITypeResolver` is available.
|
||||||
|
(Basically the `ITypeResolver` will be set, when the exception occurs during a command execution, but not
|
||||||
|
during the parsing phase and construction of the command.)
|
||||||
|
|
||||||
|
### Using `SetExceptionHandler(Func<Exception, ITypeResolver?, int> handler)`
|
||||||
|
|
||||||
Using this method exceptions can be handled in a custom way. The return value of the handler is used as
|
Using this method exceptions can be handled in a custom way. The return value of the handler is used as
|
||||||
the exitCode for the application.
|
the exitCode for the application.
|
||||||
@@ -71,7 +75,7 @@ namespace MyApp
|
|||||||
|
|
||||||
app.Configure(config =>
|
app.Configure(config =>
|
||||||
{
|
{
|
||||||
config.SetExceptionHandler(ex =>
|
config.SetExceptionHandler((ex, resolver) =>
|
||||||
{
|
{
|
||||||
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
|
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
|
||||||
return -99;
|
return -99;
|
||||||
@@ -84,9 +88,9 @@ namespace MyApp
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using `SetExceptionHandler(Action<Exception> handler)`
|
### Using `SetExceptionHandler(Action<Exception, ITypeResolver?> handler)`
|
||||||
|
|
||||||
Using this method exceptions can be handled in a custom way, much the same as with the `SetExceptionHandler(Func<Exception, int> handler)`.
|
Using this method exceptions can be handled in a custom way, much the same as with the `SetExceptionHandler(Func<Exception, ITypeResolver?, int> handler)`.
|
||||||
Using the `Action` as the handler however, it is not possible (or required) to supply a return value.
|
Using the `Action` as the handler however, it is not possible (or required) to supply a return value.
|
||||||
The exitCode for the application will be `-1`.
|
The exitCode for the application will be `-1`.
|
||||||
|
|
||||||
@@ -103,7 +107,7 @@ namespace MyApp
|
|||||||
|
|
||||||
app.Configure(config =>
|
app.Configure(config =>
|
||||||
{
|
{
|
||||||
config.SetExceptionHandler(ex =>
|
config.SetExceptionHandler((ex, resolver) =>
|
||||||
{
|
{
|
||||||
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
|
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ internal sealed class FileSizeCommand : Command<FileSizeCommand.Settings>
|
|||||||
public bool IncludeHidden { get; init; }
|
public bool IncludeHidden { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings)
|
public override int Execute(CommandContext context, Settings settings, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var searchOptions = new EnumerationOptions
|
var searchOptions = new EnumerationOptions
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
Title: Introduction
|
Title: Introduction
|
||||||
Order: 1
|
Order: 1
|
||||||
Description: "*Spectre.Console.Cli* is a modern library for parsing command line arguments. While it's extremely
|
Description: "*Spectre.Console.Cli* is a modern library for parsing command line arguments. While it's extremely
|
||||||
opinionated in what it does, it tries to follow established industry conventions, and draws
|
opinionated in what it does, it tries to follow established industry conventions, and draws
|
||||||
its inspiration from applications you use everyday."
|
its inspiration from applications you use everyday."
|
||||||
---
|
---
|
||||||
|
|
||||||
`Spectre.Console.Cli` is a modern library for parsing command line arguments. While it's extremely
|
`Spectre.Console.Cli` is a modern library for parsing command line arguments. While it's extremely
|
||||||
@@ -61,7 +61,7 @@ in the previous step.
|
|||||||
```csharp
|
```csharp
|
||||||
public class AddPackageCommand : Command<AddPackageSettings>
|
public class AddPackageCommand : Command<AddPackageSettings>
|
||||||
{
|
{
|
||||||
public override int Execute(CommandContext context, AddPackageSettings settings)
|
public override int Execute(CommandContext context, AddPackageSettings settings, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Omitted
|
// Omitted
|
||||||
return 0;
|
return 0;
|
||||||
@@ -70,7 +70,7 @@ public class AddPackageCommand : Command<AddPackageSettings>
|
|||||||
|
|
||||||
public class AddReferenceCommand : Command<AddReferenceSettings>
|
public class AddReferenceCommand : Command<AddReferenceSettings>
|
||||||
{
|
{
|
||||||
public override int Execute(CommandContext context, AddReferenceSettings settings)
|
public override int Execute(CommandContext context, AddReferenceSettings settings, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Omitted
|
// Omitted
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
22
docs/input/cli/opencli.md
Normal file
22
docs/input/cli/opencli.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
Title: OpenCLI Integration
|
||||||
|
Order: 15
|
||||||
|
Description: OpenCLI integration
|
||||||
|
Highlights:
|
||||||
|
- Generate OpenCLI descriptions
|
||||||
|
---
|
||||||
|
|
||||||
|
From version `0.52.0` and above, you will be able to generate [OpenCLI](https://opencli.org)
|
||||||
|
descriptions from your `Spectre.Console.Cli` applications.
|
||||||
|
|
||||||
|
Simply add the `--help-dump-opencli` option to your application, and an
|
||||||
|
OpenCLI description will be written to stdout.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ ./myapp --help-dump-opencli
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to save it to disk, pipe it to a file.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ ./myapp --help-dump-opencli > myapp.openapi.json
|
||||||
|
```
|
||||||
@@ -105,7 +105,7 @@ A `CommandOption` can be defined as an array like the following:
|
|||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[CommandOption("-n|--name <VALUES>")]
|
[CommandOption("-n|--name <VALUES>")]
|
||||||
public string[] Names { get; set; },
|
public string[] Names { get; set; }
|
||||||
```
|
```
|
||||||
|
|
||||||
This would allow the user to run `app.exe --name Dwayne --name Elizondo --name "Mountain Dew" --name Herbert --name Camacho` and would result in a 5 element array consisting of Dwayne, Elizondo, Mountain Dew, Herbert and Camacho.
|
This would allow the user to run `app.exe --name Dwayne --name Elizondo --name "Mountain Dew" --name Herbert --name Camacho` and would result in a 5 element array consisting of Dwayne, Elizondo, Mountain Dew, Herbert and Camacho.
|
||||||
|
|||||||
199
docs/input/cli/unit-testing.md
Normal file
199
docs/input/cli/unit-testing.md
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
Title: Unit Testing
|
||||||
|
Order: 14
|
||||||
|
Description: Instructions for unit testing a Spectre.Console application.
|
||||||
|
Reference:
|
||||||
|
- T:Spectre.Console.Testing.CommandAppTester
|
||||||
|
- T:Spectre.Console.Testing.TestConsole
|
||||||
|
- T:Spectre.Console.Testing.TestConsoleInput
|
||||||
|
---
|
||||||
|
|
||||||
|
`Spectre.Console` has a separate project that contains test harnesses for unit testing your own console applications.
|
||||||
|
|
||||||
|
The fastest way of getting started is to install the `Spectre.Console.Testing` NuGet package.
|
||||||
|
|
||||||
|
```text
|
||||||
|
> dotnet add package Spectre.Console.Testing
|
||||||
|
```
|
||||||
|
|
||||||
|
`Spectre.Console.Testing` is also the namespace containing the test classes.
|
||||||
|
|
||||||
|
## Testing a CommandApp
|
||||||
|
|
||||||
|
The `CommandAppTester` is a test implementation of `CommandApp` that's configured in a similar manner but designed for unit testing.
|
||||||
|
|
||||||
|
The following example validates the exit code and terminal output of a `Spectre.Console` command:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
/// <summary>
|
||||||
|
/// A Spectre.Console Command
|
||||||
|
/// </summary>
|
||||||
|
public class HelloWorldCommand : Command
|
||||||
|
{
|
||||||
|
private readonly IAnsiConsole _console;
|
||||||
|
|
||||||
|
public HelloWorldCommand(IAnsiConsole console)
|
||||||
|
{
|
||||||
|
// nb. AnsiConsole should not be called directly by the command
|
||||||
|
// since this doesn't play well with testing. Instead,
|
||||||
|
// the command should inject a IAnsiConsole and use that.
|
||||||
|
|
||||||
|
_console = console;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Execute(CommandContext context, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_console.WriteLine("Hello world.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Should_Output_Hello_World()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var app = new CommandAppTester();
|
||||||
|
app.SetDefaultCommand<HelloWorldCommand>();
|
||||||
|
|
||||||
|
// When
|
||||||
|
var result = app.Run();
|
||||||
|
|
||||||
|
// Then
|
||||||
|
Assert.AreEqual(result.ExitCode, 0);
|
||||||
|
Assert.AreEqual(result.Output, "Hello world.");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The following example demonstrates how to mock user inputs for an interactive command.
|
||||||
|
This test (InteractiveCommand_WithMockedUserInputs_ProducesExpectedOutput) simulates user interactions by pushing predefined inputs to the console, then verifies that the resulting output is as expected.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public sealed class InteractiveCommandTests
|
||||||
|
{
|
||||||
|
private sealed class InteractiveCommand : Command
|
||||||
|
{
|
||||||
|
private readonly IAnsiConsole _console;
|
||||||
|
|
||||||
|
public InteractiveCommand(IAnsiConsole console)
|
||||||
|
{
|
||||||
|
_console = console;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Execute(CommandContext context, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var fruits = _console.Prompt(
|
||||||
|
new MultiSelectionPrompt<string>()
|
||||||
|
.Title("What are your [green]favorite fruits[/]?")
|
||||||
|
.NotRequired() // Not required to have a favorite fruit
|
||||||
|
.PageSize(10)
|
||||||
|
.MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
|
||||||
|
.InstructionsText(
|
||||||
|
"[grey](Press [blue]<space>[/] to toggle a fruit, " +
|
||||||
|
"[green]<enter>[/] to accept)[/]")
|
||||||
|
.AddChoices(new[] {
|
||||||
|
"Apple", "Apricot", "Avocado",
|
||||||
|
"Banana", "Blackcurrant", "Blueberry",
|
||||||
|
"Cherry", "Cloudberry", "Coconut",
|
||||||
|
}));
|
||||||
|
|
||||||
|
var fruit = _console.Prompt(
|
||||||
|
new SelectionPrompt<string>()
|
||||||
|
.Title("What's your [green]favorite fruit[/]?")
|
||||||
|
.PageSize(10)
|
||||||
|
.MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
|
||||||
|
.AddChoices(new[] {
|
||||||
|
"Apple", "Apricot", "Avocado",
|
||||||
|
"Banana", "Blackcurrant", "Blueberry",
|
||||||
|
"Cherry", "Cloudberry", "Cocunut",
|
||||||
|
}));
|
||||||
|
|
||||||
|
var name = _console.Ask<string>("What's your name?");
|
||||||
|
|
||||||
|
_console.WriteLine($"[{string.Join(',', fruits)};{fruit};{name}]");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InteractiveCommand_WithMockedUserInputs_ProducesExpectedOutput()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
TestConsole console = new();
|
||||||
|
console.Interactive();
|
||||||
|
|
||||||
|
// Your mocked inputs must always end with "Enter" for each prompt!
|
||||||
|
|
||||||
|
// Multi selection prompt: Choose first option
|
||||||
|
console.Input.PushKey(ConsoleKey.Spacebar);
|
||||||
|
console.Input.PushKey(ConsoleKey.Enter);
|
||||||
|
|
||||||
|
// Selection prompt: Choose second option
|
||||||
|
console.Input.PushKey(ConsoleKey.DownArrow);
|
||||||
|
console.Input.PushKey(ConsoleKey.Enter);
|
||||||
|
|
||||||
|
// Ask text prompt: Enter name
|
||||||
|
console.Input.PushTextWithEnter("Spectre Console");
|
||||||
|
|
||||||
|
var app = new CommandAppTester(null, new CommandAppTesterSettings(), console);
|
||||||
|
app.SetDefaultCommand<InteractiveCommand>();
|
||||||
|
|
||||||
|
// When
|
||||||
|
var result = app.Run();
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ExitCode.ShouldBe(0);
|
||||||
|
result.Output.EndsWith("[Apple;Apricot;Spectre Console]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing console behaviour
|
||||||
|
|
||||||
|
`TestConsole` and `TestConsoleInput` are testable implementations of `IAnsiConsole` and `IAnsiConsoleInput`, allowing you fine-grain control over testing console output and interactivity.
|
||||||
|
|
||||||
|
The following example renders some widgets before then validating the console output:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
[TestMethod]
|
||||||
|
public void Should_Render_Panel()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var console = new TestConsole();
|
||||||
|
|
||||||
|
// When
|
||||||
|
console.Write(new Panel(new Text("Hello World")));
|
||||||
|
|
||||||
|
// Then
|
||||||
|
Assert.AreEqual(console.Output, """"
|
||||||
|
┌─────────────┐
|
||||||
|
│ Hello World │
|
||||||
|
└─────────────┘
|
||||||
|
|
||||||
|
"""");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
While `Assert` is fine for validating simple output, more complex output may benefit from a tool like [Verify](https://github.com/VerifyTests/Verify).
|
||||||
|
|
||||||
|
The following example prompts the user for input before then validating the expected choice was made:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
[TestMethod]
|
||||||
|
public void Should_Select_Orange()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var console = new TestConsole();
|
||||||
|
console.Input.PushTextWithEnter("Orange");
|
||||||
|
|
||||||
|
// When
|
||||||
|
console.Prompt(
|
||||||
|
new TextPrompt<string>("Favorite fruit?")
|
||||||
|
.AddChoice("Banana")
|
||||||
|
.AddChoice("Orange"));
|
||||||
|
|
||||||
|
// Then
|
||||||
|
Assert.AreEqual(console.Output, "Favorite fruit? [Banana/Orange]: Orange\n");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`CommandAppTester` uses `TestConsole` internally, which in turn uses `TestConsoleInput`, offering a fully testable harness for `Spectre.Console` widgets, prompts and commands.
|
||||||
@@ -6,7 +6,7 @@ Order: 0
|
|||||||
Spectre.Console is a `.NET` library that makes it easier
|
Spectre.Console is a `.NET` library that makes it easier
|
||||||
to create beautiful console applications.
|
to create beautiful console applications.
|
||||||
|
|
||||||
## Spectre.Console.AnsiConsole Features
|
## Spectre.Console.AnsiConsole
|
||||||
|
|
||||||
* Easily output text with different colors and even styles such as bold, italic and blinking with a Rich inspired [markup language](markup).
|
* Easily output text with different colors and even styles such as bold, italic and blinking with a Rich inspired [markup language](markup).
|
||||||
* Supports `3`/`4`/`8`/`24`-bit colors in the terminal with auto-detection of the current terminal's capabilities.
|
* Supports `3`/`4`/`8`/`24`-bit colors in the terminal with auto-detection of the current terminal's capabilities.
|
||||||
@@ -14,16 +14,19 @@ to create beautiful console applications.
|
|||||||
* Display progress for long running tasks with live displays of [progress](live/progress) and [status](live/status) controls.
|
* Display progress for long running tasks with live displays of [progress](live/progress) and [status](live/status) controls.
|
||||||
* Prompt user input with strongly typed [text input](prompts/text) or via [single-item select](prompts/selection) and [multiple item select](prompts/multiselection) controls.
|
* Prompt user input with strongly typed [text input](prompts/text) or via [single-item select](prompts/selection) and [multiple item select](prompts/multiselection) controls.
|
||||||
* Format .NET [exceptions](exceptions) with custom color coded themes and styles.
|
* Format .NET [exceptions](exceptions) with custom color coded themes and styles.
|
||||||
* Written with unit testing in mind.
|
|
||||||
|
|
||||||
Spectre.Console.AnsiConsole has been heavily inspired
|
Spectre.Console.AnsiConsole has been heavily inspired by the excellent [Rich](https://github.com/willmcgugan/rich) library for Python written by Will McGugan.
|
||||||
by the excellent [Rich](https://github.com/willmcgugan/rich) library
|
|
||||||
for Python written by Will McGugan.
|
|
||||||
|
|
||||||
## Spectre.Console.Cli
|
## Spectre.Console.Cli
|
||||||
|
|
||||||
* Create strongly typed settings and commands for parsing `args[]` to create complex command line applications like `git`, `gh`, or `dotnet`
|
* Create strongly typed settings and commands for parsing `args[]` to create complex command line applications like `git`, `gh`, or `dotnet`
|
||||||
|
|
||||||
|
## Spectre.Console.Testing
|
||||||
|
|
||||||
|
* Spectre.Console has been developed with unit testing in mind. The Spectre.Console library itself is covered by an extensive test suite, project maintainers require test coverage for all new commits, and the same extension points and test harnesses used internally for testing are available to you.
|
||||||
|
|
||||||
|
* The [Unit Testing](cli/unit-testing) page provides instructions for testing a Spectre.Console application.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||

|

|
||||||
@@ -36,3 +39,4 @@ for Python written by Will McGugan.
|
|||||||
Sorry, your browser doesn't support embedded videos.
|
Sorry, your browser doesn't support embedded videos.
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
|
The Spectre.Console [examples repository](https://github.com/spectreconsole/examples) contains many other examples.
|
||||||
73
docs/input/live/async.md
Normal file
73
docs/input/live/async.md
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
Title: Async Extensions
|
||||||
|
Order: 11
|
||||||
|
Description: "Async Extensions provides extension methods for running tasks with an inline animations."
|
||||||
|
Highlights:
|
||||||
|
- Extension methods for running tasks with spinner animations
|
||||||
|
- Support for both void and generic Task types
|
||||||
|
- Customizable spinner styles and console output
|
||||||
|
Reference:
|
||||||
|
- T:Spectre.Console.Extensions.SpinnerExtensions
|
||||||
|
Xref: spinner-extensions
|
||||||
|
---
|
||||||
|
|
||||||
|
The Async Spinner Extension provides convenient extension methods for running tasks with an inline spinner animations in the console.
|
||||||
|
|
||||||
|
<?# AsciiCast cast="await-spinner" /?>
|
||||||
|
|
||||||
|
<?# Alert ?>
|
||||||
|
The spinner animation is not thread safe, and using it together with other interactive
|
||||||
|
components such as prompts, progress displays or other status displays is not supported.
|
||||||
|
<?#/ Alert ?>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The extension methods allow you to easily add spinner animations to any Task execution:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Basic usage with void Task
|
||||||
|
await someTask.Spinner();
|
||||||
|
|
||||||
|
// With generic Task<T>
|
||||||
|
var result = await someTaskWithResult.Spinner(
|
||||||
|
Spinner.Known.Star,
|
||||||
|
new Style(foreground: Color.Green));
|
||||||
|
|
||||||
|
// With custom console
|
||||||
|
await someTask.Spinner(
|
||||||
|
Spinner.Known.Dots,
|
||||||
|
style: Style.Plain,
|
||||||
|
ansiConsole: customConsole);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
The spinner extensions provide:
|
||||||
|
|
||||||
|
- Support for both void Tasks and Tasks with return values
|
||||||
|
- Customizable spinner animations using any Spectre.Console Spinner
|
||||||
|
- Optional styling for the spinner animation
|
||||||
|
- Ability to specify a custom IAnsiConsole instance
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Here's a more complete example showing different ways to use the spinner extensions:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Basic spinner with default settings
|
||||||
|
await Task.Delay(1000)
|
||||||
|
.Spinner(Spinner.Known.Dots);
|
||||||
|
|
||||||
|
// Customized spinner with style
|
||||||
|
var result = await CalculateSomething()
|
||||||
|
.Spinner(
|
||||||
|
Spinner.Known.Star,
|
||||||
|
new Style(foreground: Color.Green));
|
||||||
|
|
||||||
|
// Using with a custom console
|
||||||
|
await ProcessData()
|
||||||
|
.Spinner(
|
||||||
|
new Spinner(new[] { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" }, 80),
|
||||||
|
new Style(foreground: Color.Blue),
|
||||||
|
customConsole);
|
||||||
|
```
|
||||||
|
|
||||||
@@ -9,6 +9,7 @@ Highlights:
|
|||||||
Reference:
|
Reference:
|
||||||
- T:Spectre.Console.Progress
|
- T:Spectre.Console.Progress
|
||||||
- M:Spectre.Console.AnsiConsole.Progress
|
- M:Spectre.Console.AnsiConsole.Progress
|
||||||
|
Xref: live-progress
|
||||||
---
|
---
|
||||||
|
|
||||||
Spectre.Console can display information about long running tasks in the console.
|
Spectre.Console can display information about long running tasks in the console.
|
||||||
@@ -85,6 +86,8 @@ AnsiConsole.Progress()
|
|||||||
new PercentageColumn(), // Percentage
|
new PercentageColumn(), // Percentage
|
||||||
new RemainingTimeColumn(), // Remaining time
|
new RemainingTimeColumn(), // Remaining time
|
||||||
new SpinnerColumn(), // Spinner
|
new SpinnerColumn(), // Spinner
|
||||||
|
new DownloadedColumn(), // Downloaded
|
||||||
|
new TransferSpeedColumn(), // Transfer speed
|
||||||
})
|
})
|
||||||
.Start(ctx =>
|
.Start(ctx =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ Highlights:
|
|||||||
Reference:
|
Reference:
|
||||||
- T:Spectre.Console.Status
|
- T:Spectre.Console.Status
|
||||||
- M:Spectre.Console.AnsiConsole.Status
|
- M:Spectre.Console.AnsiConsole.Status
|
||||||
|
Xref: live-status
|
||||||
---
|
---
|
||||||
|
|
||||||
Spectre.Console can display information about long running tasks in the console.
|
Spectre.Console can display information about long running tasks in the console.
|
||||||
|
|||||||
@@ -1,119 +1,119 @@
|
|||||||
Title: Markup
|
Title: Markup
|
||||||
Order: 30
|
Order: 30
|
||||||
Description: The Markup class allows you to output rich text to the console.
|
Description: The Markup class allows you to output rich text to the console.
|
||||||
Highlights:
|
Highlights:
|
||||||
- Easily add *color*.
|
- Easily add *color*.
|
||||||
- Add hyperlinks to for supported terminals.
|
- Add hyperlinks to for supported terminals.
|
||||||
- Emoji 🚀 parsing.
|
- Emoji 🚀 parsing.
|
||||||
Reference:
|
Reference:
|
||||||
- M:Spectre.Console.AnsiConsole.Markup(System.String)
|
- M:Spectre.Console.AnsiConsole.Markup(System.String)
|
||||||
- M:Spectre.Console.AnsiConsole.MarkupLine(System.String)
|
- M:Spectre.Console.AnsiConsole.MarkupLine(System.String)
|
||||||
- T:Spectre.Console.Markup
|
- T:Spectre.Console.Markup
|
||||||
---
|
---
|
||||||
|
|
||||||
The `Markup` class allows you to output rich text to the console.
|
The `Markup` class allows you to output rich text to the console.
|
||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
Console markup uses a syntax inspired by bbcode. If you write the style (see [Styles](xref:styles))
|
Console markup uses a syntax inspired by bbcode. If you write the style (see [Styles](xref:styles))
|
||||||
in square brackets, e.g. `[bold red]`, that style will apply until it is closed with a `[/]`.
|
in square brackets, e.g. `[bold red]`, that style will apply until it is closed with a `[/]`.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Write(new Markup("[bold yellow]Hello[/] [red]World![/]"));
|
AnsiConsole.Write(new Markup("[bold yellow]Hello[/] [red]World![/]"));
|
||||||
```
|
```
|
||||||
|
|
||||||
The `Markup` class implements `IRenderable` which means that you
|
The `Markup` class implements `IRenderable` which means that you
|
||||||
can use this in tables, grids, and panels. Most classes that support
|
can use this in tables, grids, and panels. Most classes that support
|
||||||
rendering of `IRenderable` also have overloads for rendering rich text.
|
rendering of `IRenderable` also have overloads for rendering rich text.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
var table = new Table();
|
var table = new Table();
|
||||||
table.AddColumn(new TableColumn(new Markup("[yellow]Foo[/]")));
|
table.AddColumn(new TableColumn(new Markup("[yellow]Foo[/]")));
|
||||||
table.AddColumn(new TableColumn("[blue]Bar[/]"));
|
table.AddColumn(new TableColumn("[blue]Bar[/]"));
|
||||||
AnsiConsole.Write(table);
|
AnsiConsole.Write(table);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Convenience methods
|
## Convenience methods
|
||||||
|
|
||||||
There are also convenience methods on `AnsiConsole` that can be used
|
There are also convenience methods on `AnsiConsole` that can be used
|
||||||
to write markup text to the console without instantiating a new `Markup`
|
to write markup text to the console without instantiating a new `Markup`
|
||||||
instance.
|
instance.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Markup("[underline green]Hello[/] ");
|
AnsiConsole.Markup("[underline green]Hello[/] ");
|
||||||
AnsiConsole.MarkupLine("[bold]World[/]");
|
AnsiConsole.MarkupLine("[bold]World[/]");
|
||||||
```
|
```
|
||||||
|
|
||||||
## Escaping format characters
|
## Escaping format characters
|
||||||
|
|
||||||
To output a `[` you use `[[`, and to output a `]` you use `]]`.
|
To output a `[` you use `[[`, and to output a `]` you use `]]`.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Markup("[[Hello]] "); // [Hello]
|
AnsiConsole.Markup("[[Hello]] "); // [Hello]
|
||||||
AnsiConsole.Markup("[red][[World]][/]"); // [World]
|
AnsiConsole.Markup("[red][[World]][/]"); // [World]
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also use the `EscapeMarkup` extension method.
|
You can also use the `EscapeMarkup` extension method.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Markup("[red]{0}[/]", "Hello [World]".EscapeMarkup());
|
AnsiConsole.Markup("[red]{0}[/]", "Hello [World]".EscapeMarkup());
|
||||||
```
|
```
|
||||||
You can also use the `Markup.Escape` method.
|
You can also use the `Markup.Escape` method.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Markup("[red]{0}[/]", Markup.Escape("Hello [World]"));
|
AnsiConsole.Markup("[red]{0}[/]", Markup.Escape("Hello [World]"));
|
||||||
```
|
```
|
||||||
|
|
||||||
## Escaping Interpolated Strings
|
## Escaping Interpolated Strings
|
||||||
|
|
||||||
When working with interpolated strings, you can use the `MarkupInterpolated` and `MarkupLineInterpolated` methods to automatically escape the values in the interpolated string "holes".
|
When working with interpolated strings, you can use the `MarkupInterpolated` and `MarkupLineInterpolated` methods to automatically escape the values in the interpolated string "holes".
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
string hello = "Hello [World]";
|
string hello = "Hello [World]";
|
||||||
AnsiConsole.MarkupInterpolated($"[red]{hello}[/]");
|
AnsiConsole.MarkupInterpolated($"[red]{hello}[/]");
|
||||||
```
|
```
|
||||||
|
|
||||||
## Setting background color
|
## Setting background color
|
||||||
|
|
||||||
You can set the background color in markup by prefixing the color with `on`.
|
You can set the background color in markup by prefixing the color with `on`.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Markup("[bold yellow on blue]Hello[/]");
|
AnsiConsole.Markup("[bold yellow on blue]Hello[/]");
|
||||||
AnsiConsole.Markup("[default on blue]World[/]");
|
AnsiConsole.Markup("[default on blue]World[/]");
|
||||||
```
|
```
|
||||||
|
|
||||||
## Rendering emojis
|
## Rendering emojis
|
||||||
|
|
||||||
To output an emoji as part of markup, you can use emoji shortcodes.
|
To output an emoji as part of markup, you can use emoji shortcodes.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Markup("Hello :globe_showing_europe_africa:!");
|
AnsiConsole.Markup("Hello :globe_showing_europe_africa:!");
|
||||||
```
|
```
|
||||||
|
|
||||||
For a list of emoji, see the [Emojis](xref:emojis) appendix section.
|
For a list of emoji, see the [Emojis](xref:emojis) appendix section.
|
||||||
|
|
||||||
## Colors
|
## Colors
|
||||||
|
|
||||||
In the examples above, all colors were referenced by their name,
|
In the examples above, all colors were referenced by their name,
|
||||||
but you can also use the hex or rgb representation for colors in markdown.
|
but you can also use the hex or rgb representation for colors in markdown.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Markup("[red]Foo[/] ");
|
AnsiConsole.Markup("[red]Foo[/] ");
|
||||||
AnsiConsole.Markup("[#ff0000]Bar[/] ");
|
AnsiConsole.Markup("[#ff0000]Bar[/] ");
|
||||||
AnsiConsole.Markup("[rgb(255,0,0)]Baz[/] ");
|
AnsiConsole.Markup("[rgb(255,0,0)]Baz[/] ");
|
||||||
```
|
```
|
||||||
|
|
||||||
For a list of colors, see the [Colors](xref:colors) appendix section.
|
For a list of colors, see the [Colors](xref:colors) appendix section.
|
||||||
|
|
||||||
## Links
|
## Links
|
||||||
|
|
||||||
To output a clickable link, you can use the `[link]` style.
|
To output a clickable link, you can use the `[link]` style.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
AnsiConsole.Markup("[link]https://spectreconsole.net[/]");
|
AnsiConsole.Markup("[link]https://spectreconsole.net[/]");
|
||||||
AnsiConsole.Markup("[link=https://spectreconsole.net]Spectre Console Documentation[/]");
|
AnsiConsole.Markup("[link=https://spectreconsole.net]Spectre Console Documentation[/]");
|
||||||
```
|
```
|
||||||
|
|
||||||
## Styles
|
## Styles
|
||||||
|
|
||||||
For a list of styles, see the [Styles](xref:styles) appendix section.
|
For a list of styles, see the [Styles](xref:styles) appendix section.
|
||||||
|
|||||||
@@ -27,6 +27,32 @@ you can use the `Prompt<TResult>`.
|
|||||||
Run prompt example? [y/n] (y): _
|
Run prompt example? [y/n] (y): _
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask the user to confirm
|
||||||
|
var confirmation = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<bool>("Run prompt example?")
|
||||||
|
.AddChoice(true)
|
||||||
|
.AddChoice(false)
|
||||||
|
.DefaultValue(true)
|
||||||
|
.WithConverter(choice => choice ? "y" : "n"));
|
||||||
|
|
||||||
|
// Echo the confirmation back to the terminal
|
||||||
|
Console.WriteLine(confirmation ? "Confirmed" : "Declined");
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise it is possible to use the `ConfirmationPrompt`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask the user to confirm
|
||||||
|
var confirmation = AnsiConsole.Prompt(
|
||||||
|
new ConfirmationPrompt("Run prompt example?"));
|
||||||
|
|
||||||
|
// Echo the confirmation back to the terminal
|
||||||
|
Console.WriteLine(confirmation ? "Confirmed" : "Declined");
|
||||||
|
```
|
||||||
|
|
||||||
## Simple
|
## Simple
|
||||||
|
|
||||||
<?# Example symbol="M:Prompt.Program.AskName" project="Prompt" /?>
|
<?# Example symbol="M:Prompt.Program.AskName" project="Prompt" /?>
|
||||||
@@ -36,6 +62,30 @@ What's your name? Patrik
|
|||||||
What's your age? 37
|
What's your age? 37
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask the user a couple of simple questions
|
||||||
|
var name = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("What's your name?"));
|
||||||
|
var age = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<int>("What's your age?"));
|
||||||
|
|
||||||
|
// Echo the name and age back to the terminal
|
||||||
|
AnsiConsole.WriteLine($"So you're {name} and you're {age} years old");
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise it is possible to use the `Ask` method
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask the user a couple of simple questions
|
||||||
|
var name = AnsiConsole.Ask<string>("What's your name?");
|
||||||
|
var age = AnsiConsole.Ask<int>("What's your age?");
|
||||||
|
|
||||||
|
// Echo the name and age back to the terminal
|
||||||
|
AnsiConsole.WriteLine($"So you're {name} and you're {age} years old");
|
||||||
|
```
|
||||||
|
|
||||||
## Choices
|
## Choices
|
||||||
|
|
||||||
<?# Example symbol="M:Prompt.Program.AskFruit" project="Prompt" /?>
|
<?# Example symbol="M:Prompt.Program.AskFruit" project="Prompt" /?>
|
||||||
@@ -44,6 +94,19 @@ What's your age? 37
|
|||||||
What's your favorite fruit? [Apple/Banana/Orange] (Orange): _
|
What's your favorite fruit? [Apple/Banana/Orange] (Orange): _
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask for the user's favorite fruit
|
||||||
|
var fruit = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("What's your favorite fruit?")
|
||||||
|
.AddChoices(["Apple", "Banana", "Orange"])
|
||||||
|
.DefaultValue("Orange"));
|
||||||
|
|
||||||
|
// Echo the fruit back to the terminal
|
||||||
|
Console.WriteLine($"I agree. {fruit} is tasty!");
|
||||||
|
```
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
<?# Example symbol="M:Prompt.Program.AskAge" project="Prompt" /?>
|
<?# Example symbol="M:Prompt.Program.AskAge" project="Prompt" /?>
|
||||||
@@ -56,6 +119,23 @@ Too high
|
|||||||
What's the secret number? _
|
What's the secret number? _
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask the user to guess the secret number
|
||||||
|
var number = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<int>("What's the secret number?")
|
||||||
|
.Validate((n) => n switch
|
||||||
|
{
|
||||||
|
< 50 => ValidationResult.Error("Too low"),
|
||||||
|
50 => ValidationResult.Success(),
|
||||||
|
> 50 => ValidationResult.Error("Too high"),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Echo the user's success back to the terminal
|
||||||
|
Console.WriteLine($"Correct! The secret number is {number}.");
|
||||||
|
```
|
||||||
|
|
||||||
## Secrets
|
## Secrets
|
||||||
|
|
||||||
<?# Example symbol="M:Prompt.Program.AskPassword" project="Prompt" /?>
|
<?# Example symbol="M:Prompt.Program.AskPassword" project="Prompt" /?>
|
||||||
@@ -63,29 +143,67 @@ What's the secret number? _
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
Enter password: ************_
|
Enter password: ************_
|
||||||
```
|
```
|
||||||
|
|
||||||
## Masks
|
### Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask the user to enter the password
|
||||||
|
var password = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("Enter password:")
|
||||||
|
.Secret());
|
||||||
|
|
||||||
|
// Echo the password back to the terminal
|
||||||
|
Console.WriteLine($"Your password is {password}");
|
||||||
|
```
|
||||||
|
|
||||||
|
## Masks
|
||||||
|
|
||||||
<?# Example symbol="M:Prompt.Program.AskPasswordWithCustomMask" project="Prompt" /?>
|
<?# Example symbol="M:Prompt.Program.AskPasswordWithCustomMask" project="Prompt" /?>
|
||||||
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Enter password: ------------_
|
Enter password: ------------_
|
||||||
```
|
```
|
||||||
|
|
||||||
You can utilize a null character to completely hide input.
|
You can utilize a null character to completely hide input.
|
||||||
|
|
||||||
<?# Example symbol="M:Prompt.Program.AskPasswordWithNullMask" project="Prompt" /?>
|
<?# Example symbol="M:Prompt.Program.AskPasswordWithNullMask" project="Prompt" /?>
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Enter password: _
|
Enter password: _
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask the user to enter the password
|
||||||
|
var password = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("Enter password:")
|
||||||
|
.Secret('-'));
|
||||||
|
|
||||||
|
// Echo the password back to the terminal
|
||||||
|
Console.WriteLine($"Your password is {password}");
|
||||||
|
```
|
||||||
|
|
||||||
## Optional
|
## Optional
|
||||||
|
|
||||||
<?# Example symbol="M:Prompt.Program.AskColor" project="Prompt" /?>
|
<?# Example symbol="M:Prompt.Program.AskColor" project="Prompt" /?>
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[Optional] Favorite color? _
|
[Optional] Favorite color? _
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask for the user's favorite color (optional)
|
||||||
|
var color = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("[[Optional]] Favorite color?")
|
||||||
|
.AllowEmpty());
|
||||||
|
|
||||||
|
// Echo the color back to the terminal
|
||||||
|
Console.WriteLine(string.IsNullOrWhiteSpace(color)
|
||||||
|
? "You're right, all colors are beautiful"
|
||||||
|
: $"I agree. {color} is a very beautiful color");
|
||||||
```
|
```
|
||||||
@@ -8,9 +8,10 @@ to install the NuGet package.
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
> dotnet add package Spectre.Console
|
> dotnet add package Spectre.Console
|
||||||
|
> dotnet add package Spectre.Console.Cli
|
||||||
```
|
```
|
||||||
|
|
||||||
After that you will need to reference the `Spectre.Console` namespace.
|
After that you will need to reference the `Spectre.Console` and `Spectre.Console.Cli` namespaces.
|
||||||
Once that is done, you can start using all the available features.
|
Once that is done, you can start using all the available features.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ and the ascii terminal player.
|
|||||||
/* temp styling for alerts */
|
/* temp styling for alerts */
|
||||||
|
|
||||||
.alert-warning {
|
.alert-warning {
|
||||||
@apply p-4 border border-yellow-300 bg-yellow-100 text-yellow-800 dark:border-orange-700/50 dark:bg-orange-800/50 dark:text-orange-300/90 rounded shadow-sm text-sm;
|
@apply p-4 border border-yellow-300 bg-yellow-100 text-yellow-800 dark:border-red-700/50 dark:bg-red-800/50 dark:text-red-100/90 rounded shadow-sm text-sm;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-warning p {
|
.alert-warning p {
|
||||||
|
|||||||
66
docs/input/widgets/align.md
Normal file
66
docs/input/widgets/align.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
Title: Align
|
||||||
|
Description: "Use **Align** to render and position widgets in the console."
|
||||||
|
Highlights:
|
||||||
|
- Custom colors
|
||||||
|
- Labels
|
||||||
|
- Use your own data with a converter.
|
||||||
|
Reference: T:Spectre.Console.Align
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Use `Align` to render and position widgets in the console.
|
||||||
|
|
||||||
|
<?# AsciiCast cast="align" /?>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Render an item and align it in the bottom-left corner of the console
|
||||||
|
AnsiConsole.Write(new Align(
|
||||||
|
new Text("Spectre!"),
|
||||||
|
HorizontalAlignment.Left,
|
||||||
|
VerticalAlignment.Bottom
|
||||||
|
));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Align items from an IEnumerable
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Create a list of items
|
||||||
|
var alignItems = new List<Text>(){
|
||||||
|
new Text("Spectre"),
|
||||||
|
new Text("Console"),
|
||||||
|
new Text("Is Awesome!")
|
||||||
|
};
|
||||||
|
|
||||||
|
// Render the items in the middle-right of the console
|
||||||
|
AnsiConsole.Write(new Align(
|
||||||
|
alignItems,
|
||||||
|
HorizontalAlignment.Right,
|
||||||
|
VerticalAlignment.Middle
|
||||||
|
));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dynamically align with different widgets
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Create a table
|
||||||
|
var table = new Table()
|
||||||
|
.AddColumn("ID")
|
||||||
|
.AddColumn("Methods")
|
||||||
|
.AddColumn("Purpose")
|
||||||
|
.AddRow("1", "Center()", "Initializes a new instance that is center aligned")
|
||||||
|
.AddRow("2", "Measure()", "Measures the renderable object")
|
||||||
|
.AddRow("3", "Right()", "Initializes a new instance that is right aligned.");
|
||||||
|
|
||||||
|
// Create a panel
|
||||||
|
var panel = new Panel(table)
|
||||||
|
.Header("Other Align Methods")
|
||||||
|
.Border(BoxBorder.Double);
|
||||||
|
|
||||||
|
// Renders the panel in the top-center of the console
|
||||||
|
AnsiConsole.Write(new Align(panel, HorizontalAlignment.Center, VerticalAlignment.Top));
|
||||||
|
```
|
||||||
|
|
||||||
@@ -132,3 +132,13 @@ AnsiConsole.Write(new BreakdownChart()
|
|||||||
.AddItem(new Fruit("Mango", 3, Color.Orange4))
|
.AddItem(new Fruit("Mango", 3, Color.Orange4))
|
||||||
.AddItems(items));
|
.AddItems(items));
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Add value formatter to chart numbers
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
var chart = new BreakdownChart();
|
||||||
|
chart.UseValueFormater(value => value.ToString("N0"));
|
||||||
|
|
||||||
|
// This can be simplified as extension methods are chainable.
|
||||||
|
var chart = new BreakdownChart().UseValueFormatter(v => v.ToString("N0"));
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Title: Calendar
|
Title: Calendar
|
||||||
Order: 40
|
Order: 40
|
||||||
RedirectFrom: calendar
|
RedirectFrom: calendar
|
||||||
Description: "The **Calendar** is used to render a calendar to the terminal."
|
Description: "The **Calendar** is used to render a calendar to the terminal."
|
||||||
|
|||||||
@@ -137,4 +137,11 @@ table.Columns[0].NoWrap();
|
|||||||
```csharp
|
```csharp
|
||||||
// Set the column width
|
// Set the column width
|
||||||
table.Columns[0].Width(15);
|
table.Columns[0].Width(15);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Show row separators
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Shows separator between each row
|
||||||
|
table.ShowRowSeparators();
|
||||||
```
|
```
|
||||||
282
docs/package-lock.json
generated
282
docs/package-lock.json
generated
@@ -123,12 +123,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.17.0",
|
"version": "7.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
||||||
"integrity": "sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ==",
|
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.14.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -315,12 +316,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@@ -475,10 +477,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"path-key": "^3.1.0",
|
"path-key": "^3.1.0",
|
||||||
"shebang-command": "^2.0.0",
|
"shebang-command": "^2.0.0",
|
||||||
@@ -500,6 +503,13 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/csstype": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/defined": {
|
"node_modules/defined": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
|
||||||
@@ -587,10 +597,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
},
|
},
|
||||||
@@ -737,6 +748,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
@@ -802,13 +814,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/micromatch": {
|
"node_modules/micromatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||||
"integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
|
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"braces": "^3.0.1",
|
"braces": "^3.0.3",
|
||||||
"picomatch": "^2.2.3"
|
"picomatch": "^2.3.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.6"
|
"node": ">=8.6"
|
||||||
@@ -824,16 +837,27 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimist": {
|
"node_modules/minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.2.0",
|
"version": "3.3.11",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"nanoid": "bin/nanoid.cjs"
|
"nanoid": "bin/nanoid.cjs"
|
||||||
},
|
},
|
||||||
@@ -931,10 +955,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
@@ -949,21 +974,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.6",
|
"version": "8.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
||||||
"integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==",
|
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.2.0",
|
"nanoid": "^3.3.8",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.1.1",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/postcss/"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss-js": {
|
"node_modules/postcss-js": {
|
||||||
@@ -1093,10 +1129,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/regenerator-runtime": {
|
"node_modules/regenerator-runtime": {
|
||||||
"version": "0.13.9",
|
"version": "0.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
|
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.0",
|
"version": "1.22.0",
|
||||||
@@ -1157,6 +1194,29 @@
|
|||||||
"queue-microtask": "^1.2.2"
|
"queue-microtask": "^1.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/seroval": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/seroval/-/seroval-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-yBxFFs3zmkvKNmR0pFSU//rIsYjuX418TnlDmc2weaq5XFDqDIV/NOMPBoLrbxjLH42p4UzRuXHryXh9dYcKcw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/seroval-plugins": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-H5vs53+39+x4Udwp4J5rNZfgFuA+Lt+uU+09w1gYBVWomtAl98B+E9w7yC05Xc81/HgLvJdlyqJbU0fJCKCmdw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"seroval": "^1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -1179,16 +1239,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/solid-js": {
|
"node_modules/solid-js": {
|
||||||
"version": "1.3.5",
|
"version": "1.9.5",
|
||||||
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.5.tgz",
|
||||||
"integrity": "sha512-PUom2cCARfvvgxI7cwOhfXMrZZZxjp+vIrb5fzVNBFyICy8A30wTqExwfUv457eJYgKpii2D3qStW9ILtKnShw==",
|
"integrity": "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"csstype": "^3.1.0",
|
||||||
|
"seroval": "^1.1.0",
|
||||||
|
"seroval-plugins": "^1.1.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.0.2",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@@ -1274,6 +1341,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-number": "^7.0.0"
|
"is-number": "^7.0.0"
|
||||||
},
|
},
|
||||||
@@ -1407,12 +1475,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.17.0",
|
"version": "7.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
||||||
"integrity": "sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ==",
|
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@nodelib/fs.scandir": {
|
"@nodelib/fs.scandir": {
|
||||||
@@ -1547,12 +1615,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"braces": {
|
"braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
@@ -1652,9 +1720,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"path-key": "^3.1.0",
|
"path-key": "^3.1.0",
|
||||||
@@ -1668,6 +1736,12 @@
|
|||||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"csstype": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"defined": {
|
"defined": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
|
||||||
@@ -1743,9 +1817,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
@@ -1905,13 +1979,13 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"micromatch": {
|
"micromatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||||
"integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
|
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"braces": "^3.0.1",
|
"braces": "^3.0.3",
|
||||||
"picomatch": "^2.2.3"
|
"picomatch": "^2.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mini-svg-data-uri": {
|
"mini-svg-data-uri": {
|
||||||
@@ -1921,15 +1995,15 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"nanoid": {
|
"nanoid": {
|
||||||
"version": "3.2.0",
|
"version": "3.3.11",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-releases": {
|
"node-releases": {
|
||||||
@@ -1998,9 +2072,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"picocolors": {
|
"picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"picomatch": {
|
"picomatch": {
|
||||||
@@ -2010,14 +2084,14 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
"version": "8.4.6",
|
"version": "8.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
||||||
"integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==",
|
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"nanoid": "^3.2.0",
|
"nanoid": "^3.3.8",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.1.1",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postcss-js": {
|
"postcss-js": {
|
||||||
@@ -2086,9 +2160,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.13.9",
|
"version": "0.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
|
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"resolve": {
|
"resolve": {
|
||||||
@@ -2123,6 +2197,19 @@
|
|||||||
"queue-microtask": "^1.2.2"
|
"queue-microtask": "^1.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"seroval": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/seroval/-/seroval-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-yBxFFs3zmkvKNmR0pFSU//rIsYjuX418TnlDmc2weaq5XFDqDIV/NOMPBoLrbxjLH42p4UzRuXHryXh9dYcKcw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"seroval-plugins": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-H5vs53+39+x4Udwp4J5rNZfgFuA+Lt+uU+09w1gYBVWomtAl98B+E9w7yC05Xc81/HgLvJdlyqJbU0fJCKCmdw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"shebang-command": {
|
"shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -2139,15 +2226,20 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"solid-js": {
|
"solid-js": {
|
||||||
"version": "1.3.5",
|
"version": "1.9.5",
|
||||||
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.5.tgz",
|
||||||
"integrity": "sha512-PUom2cCARfvvgxI7cwOhfXMrZZZxjp+vIrb5fzVNBFyICy8A30wTqExwfUv457eJYgKpii2D3qStW9ILtKnShw==",
|
"integrity": "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"csstype": "^3.1.0",
|
||||||
|
"seroval": "^1.1.0",
|
||||||
|
"seroval-plugins": "^1.1.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"source-map-js": {
|
"source-map-js": {
|
||||||
"version": "1.0.2",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Statiq.App;
|
using Statiq.App;
|
||||||
using Statiq.Common;
|
using Statiq.Common;
|
||||||
using Statiq.Web;
|
using Statiq.Web;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Docs.Extensions
|
namespace Docs.Extensions
|
||||||
{
|
{
|
||||||
public static class StringExtensions
|
public static class StringExtensions
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Docs.Models
|
namespace Docs.Models
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Docs.Utilities;
|
using Docs.Utilities;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@@ -99,8 +99,7 @@ public class Api : Pipeline
|
|||||||
new ConcatDocuments(nameof(Code)),
|
new ConcatDocuments(nameof(Code)),
|
||||||
new CacheDocuments(
|
new CacheDocuments(
|
||||||
new AnalyzeCSharp()
|
new AnalyzeCSharp()
|
||||||
.WhereNamespaces(ns => ns.StartsWith("Spectre.Console") && !ns.Contains("Analyzer") &&
|
.WhereNamespaces(ns => ns.StartsWith("Spectre.Console") && !ns.Contains("Analyzer") && !ns.Contains("Examples"))
|
||||||
!ns.Contains("Testing") && !ns.Contains("Examples"))
|
|
||||||
.WherePublic(true)
|
.WherePublic(true)
|
||||||
.WithCssClasses("code", "cs")
|
.WithCssClasses("code", "cs")
|
||||||
.WithDestinationPrefix("api")
|
.WithDestinationPrefix("api")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Statiq.Common;
|
using Statiq.Common;
|
||||||
using Statiq.Web.GitHub;
|
using Statiq.Web.GitHub;
|
||||||
using Statiq.Web.Netlify;
|
using Statiq.Web.Netlify;
|
||||||
|
|
||||||
|
|||||||
@@ -1,119 +1,119 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Playwright;
|
using Microsoft.Playwright;
|
||||||
using Statiq.Common;
|
using Statiq.Common;
|
||||||
using Statiq.Core;
|
using Statiq.Core;
|
||||||
using Statiq.Web;
|
using Statiq.Web;
|
||||||
using Statiq.Web.Modules;
|
using Statiq.Web.Modules;
|
||||||
using Statiq.Web.Pipelines;
|
using Statiq.Web.Pipelines;
|
||||||
|
|
||||||
namespace Docs.Pipelines
|
namespace Docs.Pipelines
|
||||||
{
|
{
|
||||||
public class SocialImages : Pipeline
|
public class SocialImages : Pipeline
|
||||||
{
|
{
|
||||||
public SocialImages()
|
public SocialImages()
|
||||||
{
|
{
|
||||||
Dependencies.AddRange(nameof(Inputs));
|
Dependencies.AddRange(nameof(Inputs));
|
||||||
|
|
||||||
ProcessModules = new ModuleList
|
ProcessModules = new ModuleList
|
||||||
{
|
{
|
||||||
new GetPipelineDocuments(ContentType.Content),
|
new GetPipelineDocuments(ContentType.Content),
|
||||||
|
|
||||||
// Filter to non-archive content
|
// Filter to non-archive content
|
||||||
new FilterDocuments(Config.FromDocument(doc => !Archives.IsArchive(doc))),
|
new FilterDocuments(Config.FromDocument(doc => !Archives.IsArchive(doc))),
|
||||||
|
|
||||||
// Process the content
|
// Process the content
|
||||||
new CacheDocuments
|
new CacheDocuments
|
||||||
{
|
{
|
||||||
new AddTitle(),
|
new AddTitle(),
|
||||||
new SetDestination(true),
|
new SetDestination(true),
|
||||||
new ExecuteIf(Config.FromSetting(WebKeys.OptimizeContentFileNames, true))
|
new ExecuteIf(Config.FromSetting(WebKeys.OptimizeContentFileNames, true))
|
||||||
{
|
{
|
||||||
new OptimizeFileName()
|
new OptimizeFileName()
|
||||||
},
|
},
|
||||||
new GenerateSocialImage(),
|
new GenerateSocialImage(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
OutputModules = new ModuleList { new WriteFiles() };
|
OutputModules = new ModuleList { new WriteFiles() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GenerateSocialImage : ParallelModule
|
class GenerateSocialImage : ParallelModule
|
||||||
{
|
{
|
||||||
private IPlaywright _playwright;
|
private IPlaywright _playwright;
|
||||||
private IBrowser _browser;
|
private IBrowser _browser;
|
||||||
private WebApplication _app;
|
private WebApplication _app;
|
||||||
private IBrowserContext _context;
|
private IBrowserContext _context;
|
||||||
|
|
||||||
protected override async Task BeforeExecutionAsync(IExecutionContext context)
|
protected override async Task BeforeExecutionAsync(IExecutionContext context)
|
||||||
{
|
{
|
||||||
var builder = WebApplication.CreateBuilder();
|
var builder = WebApplication.CreateBuilder();
|
||||||
builder.Logging.ClearProviders();
|
builder.Logging.ClearProviders();
|
||||||
|
|
||||||
builder.Services
|
builder.Services
|
||||||
.AddRazorPages()
|
.AddRazorPages()
|
||||||
.WithRazorPagesRoot("/src/SocialCards/");
|
.WithRazorPagesRoot("/src/SocialCards/");
|
||||||
|
|
||||||
_app = builder.Build();
|
_app = builder.Build();
|
||||||
_app.MapRazorPages();
|
_app.MapRazorPages();
|
||||||
_app.UseStaticFiles(new StaticFileOptions
|
_app.UseStaticFiles(new StaticFileOptions
|
||||||
{
|
{
|
||||||
FileProvider = new PhysicalFileProvider(
|
FileProvider = new PhysicalFileProvider(
|
||||||
Path.Combine(builder.Environment.ContentRootPath, "src/SocialCards")),
|
Path.Combine(builder.Environment.ContentRootPath, "src/SocialCards")),
|
||||||
RequestPath = "/static"
|
RequestPath = "/static"
|
||||||
});
|
});
|
||||||
|
|
||||||
await _app.StartAsync().ConfigureAwait(false);
|
await _app.StartAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
_playwright = await Playwright.CreateAsync().ConfigureAwait(false);
|
_playwright = await Playwright.CreateAsync().ConfigureAwait(false);
|
||||||
_browser = await _playwright.Chromium.LaunchAsync().ConfigureAwait(false);
|
_browser = await _playwright.Chromium.LaunchAsync().ConfigureAwait(false);
|
||||||
_context = await _browser.NewContextAsync(new BrowserNewContextOptions {
|
_context = await _browser.NewContextAsync(new BrowserNewContextOptions {
|
||||||
ViewportSize = new ViewportSize { Width = 1200, Height = 618 },
|
ViewportSize = new ViewportSize { Width = 1200, Height = 618 },
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task FinallyAsync(IExecutionContext context)
|
protected override async Task FinallyAsync(IExecutionContext context)
|
||||||
{
|
{
|
||||||
await _context.DisposeAsync().ConfigureAwait(false);
|
await _context.DisposeAsync().ConfigureAwait(false);
|
||||||
await _browser.DisposeAsync().ConfigureAwait(false);
|
await _browser.DisposeAsync().ConfigureAwait(false);
|
||||||
_playwright.Dispose();
|
_playwright.Dispose();
|
||||||
await _app.DisposeAsync().ConfigureAwait(false);
|
await _app.DisposeAsync().ConfigureAwait(false);
|
||||||
await base.FinallyAsync(context);
|
await base.FinallyAsync(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task<IEnumerable<IDocument>> ExecuteInputAsync(IDocument input, IExecutionContext context)
|
protected override async Task<IEnumerable<IDocument>> ExecuteInputAsync(IDocument input, IExecutionContext context)
|
||||||
{
|
{
|
||||||
var url = _app.Urls.FirstOrDefault(u => u.StartsWith("http://"));
|
var url = _app.Urls.FirstOrDefault(u => u.StartsWith("http://"));
|
||||||
var page = await _context.NewPageAsync().ConfigureAwait(false);
|
var page = await _context.NewPageAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
var title = input.GetString("Title");
|
var title = input.GetString("Title");
|
||||||
var description = input.GetString("Description");
|
var description = input.GetString("Description");
|
||||||
var highlights = input.GetList<string>("Highlights") ?? Array.Empty<string>();
|
var highlights = input.GetList<string>("Highlights") ?? Array.Empty<string>();
|
||||||
|
|
||||||
await page.GotoAsync($"{url}/?title={title}&desc={description}&highlights={string.Join("||", highlights)}");
|
await page.GotoAsync($"{url}/?title={title}&desc={description}&highlights={string.Join("||", highlights)}");
|
||||||
|
|
||||||
// This will not just wait for the page to load over the network, but it'll also give
|
// This will not just wait for the page to load over the network, but it'll also give
|
||||||
// chrome a chance to complete rendering of the fonts while the wait timeout completes.
|
// chrome a chance to complete rendering of the fonts while the wait timeout completes.
|
||||||
await page.WaitForLoadStateAsync(LoadState.NetworkIdle).ConfigureAwait(false);
|
await page.WaitForLoadStateAsync(LoadState.NetworkIdle).ConfigureAwait(false);
|
||||||
var bytes = await page.ScreenshotAsync().ConfigureAwait(false);
|
var bytes = await page.ScreenshotAsync().ConfigureAwait(false);
|
||||||
await page.CloseAsync().ConfigureAwait(false);
|
await page.CloseAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
var destination = input.Destination.InsertSuffix("-social").ChangeExtension("png");
|
var destination = input.Destination.InsertSuffix("-social").ChangeExtension("png");
|
||||||
var doc = context.CreateDocument(
|
var doc = context.CreateDocument(
|
||||||
input.Source,
|
input.Source,
|
||||||
destination,
|
destination,
|
||||||
new MetadataItems { { "DocId", input.Id }},
|
new MetadataItems { { "DocId", input.Id }},
|
||||||
context.GetContentProvider(bytes));
|
context.GetContentProvider(bytes));
|
||||||
|
|
||||||
return new[] { doc };
|
return new[] { doc };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Docs.Extensions;
|
using Docs.Extensions;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div id="console">
|
<div id="console">
|
||||||
<div class="line"><span style="color:var(--brightBlack)">╭─</span><span style="color:var(--folder)"></span><span style="background-color:var(--folder);color:var(--black)"> ~/spectre.console</span><span style="color:var(--folder);background-color:var(--dotnet)"></span><span style="background-color:var(--blue)"> .NET 7.0 </span><span style="color:var(--dotnet);background-color:var(--git)"></span><span style="background-color:var(--git);color:var(--background)">  main </span><span style="color:var(--git)"></span></div>
|
<div class="line"><span style="color:var(--brightBlack)">╭─</span><span style="color:var(--folder)"></span><span style="background-color:var(--folder);color:var(--black)"> ~/spectre.console</span><span style="color:var(--folder);background-color:var(--dotnet)"></span><span style="background-color:var(--blue)"> .NET 9.0 </span><span style="color:var(--dotnet);background-color:var(--git)"></span><span style="background-color:var(--git);color:var(--background)">  main </span><span style="color:var(--git)"></span></div>
|
||||||
<div class="line"><span style="color:var(--brightBlack)">╰─</span> dotnet run</div>
|
<div class="line"><span style="color:var(--brightBlack)">╰─</span> dotnet run</div>
|
||||||
<div class="line"></div>
|
<div class="line"></div>
|
||||||
<div class="line">╭────────────────────────────────────────────────────────╮</div>
|
<div class="line">╭────────────────────────────────────────────────────────╮</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -58,21 +58,31 @@ internal static class HighlightService
|
|||||||
}
|
}
|
||||||
|
|
||||||
var text = await syntaxReference.SyntaxTree.GetTextAsync();
|
var text = await syntaxReference.SyntaxTree.GetTextAsync();
|
||||||
// we need a workspace, but it seems it is only used to resolve a few services and nothing else so an empty one will suffice
|
|
||||||
return HighlightElement(_emptyWorkspace, model, text, textSpan, indent);
|
// we need a document for the syntax highlighter, so create a temporary solution and project to hold it.
|
||||||
|
var workspace = new AdhocWorkspace();
|
||||||
|
var solution = workspace.CurrentSolution
|
||||||
|
.AddProject("TempProject", "TempProject", "C#")
|
||||||
|
.AddDocument("TempDocument", await syntaxReference.SyntaxTree.GetTextAsync());
|
||||||
|
|
||||||
|
var document = solution.Project.Documents.First();
|
||||||
|
|
||||||
|
var highlightElement = await HighlightElement(document, text, textSpan, indent);
|
||||||
|
return highlightElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetIndent(SyntaxTriviaList leadingTrivia)
|
private static int GetIndent(SyntaxTriviaList leadingTrivia)
|
||||||
{
|
{
|
||||||
var whitespace = leadingTrivia.FirstOrDefault(i => i.Kind() == SyntaxKind.WhitespaceTrivia);
|
var whitespace = leadingTrivia.FirstOrDefault(i => i.IsKind(SyntaxKind.WhitespaceTrivia));
|
||||||
return whitespace == default ? 0 : whitespace.Span.Length;
|
return whitespace == default ? 0 : whitespace.Span.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string HighlightElement(Workspace workspace, SemanticModel semanticModel, SourceText fullSourceText,
|
private static async Task<string> HighlightElement(Document document,
|
||||||
|
SourceText fullSourceText,
|
||||||
TextSpan textSpan, int indent)
|
TextSpan textSpan, int indent)
|
||||||
{
|
{
|
||||||
|
|
||||||
var classifiedSpans = Classifier.GetClassifiedSpans(semanticModel, textSpan, workspace);
|
var classifiedSpans = await Classifier.GetClassifiedSpansAsync(document, textSpan);
|
||||||
return HighlightElement(classifiedSpans, fullSourceText, indent);
|
return HighlightElement(classifiedSpans, fullSourceText, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,15 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"cake.tool": {
|
"cake.tool": {
|
||||||
"version": "4.0.0",
|
"version": "5.1.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-cake"
|
"dotnet-cake"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dotnet-example": {
|
"verify.tool": {
|
||||||
"version": "2.0.0",
|
"version": "0.6.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-example"
|
"dotnet-verify"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Delegates;
|
|
||||||
|
|
||||||
public static partial class Program
|
|
||||||
{
|
|
||||||
public sealed class BarSettings : CommandSettings
|
|
||||||
{
|
|
||||||
[CommandOption("--count")]
|
|
||||||
[Description("The number of bars to print")]
|
|
||||||
[DefaultValue(3)]
|
|
||||||
public int Count { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
<ExampleName>Delegates</ExampleName>
|
|
||||||
<ExampleDescription>Demonstrates how to specify commands as delegates.</ExampleDescription>
|
|
||||||
<ExampleGroup>Cli</ExampleGroup>
|
|
||||||
<ExampleVisible>false</ExampleVisible>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Spectre.Console;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Delegates;
|
|
||||||
|
|
||||||
public static partial class Program
|
|
||||||
{
|
|
||||||
public static int Main(string[] args)
|
|
||||||
{
|
|
||||||
var app = new CommandApp();
|
|
||||||
app.Configure(config =>
|
|
||||||
{
|
|
||||||
config.AddDelegate("foo", Foo)
|
|
||||||
.WithDescription("Foos the bars");
|
|
||||||
|
|
||||||
config.AddDelegate<BarSettings>("bar", Bar)
|
|
||||||
.WithDescription("Bars the foos");
|
|
||||||
|
|
||||||
config.AddAsyncDelegate("fooAsync", FooAsync)
|
|
||||||
.WithDescription("Foos the bars asynchronously");
|
|
||||||
|
|
||||||
config.AddAsyncDelegate<BarSettings>("barAsync", BarAsync)
|
|
||||||
.WithDescription("Bars the foos asynchronously");
|
|
||||||
});
|
|
||||||
|
|
||||||
return app.Run(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int Foo(CommandContext context)
|
|
||||||
{
|
|
||||||
AnsiConsole.WriteLine("Foo");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int Bar(CommandContext context, BarSettings settings)
|
|
||||||
{
|
|
||||||
for (var index = 0; index < settings.Count; index++)
|
|
||||||
{
|
|
||||||
AnsiConsole.WriteLine("Bar");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Task<int> FooAsync(CommandContext context)
|
|
||||||
{
|
|
||||||
AnsiConsole.WriteLine("Foo");
|
|
||||||
return Task.FromResult(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Task<int> BarAsync(CommandContext context, BarSettings settings)
|
|
||||||
{
|
|
||||||
for (var index = 0; index < settings.Count; index++)
|
|
||||||
{
|
|
||||||
AnsiConsole.WriteLine("Bar");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.FromResult(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using Demo.Utilities;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Demo.Commands.Add;
|
|
||||||
|
|
||||||
[Description("Add a NuGet package reference to the project.")]
|
|
||||||
public sealed class AddPackageCommand : Command<AddPackageCommand.Settings>
|
|
||||||
{
|
|
||||||
public sealed class Settings : AddSettings
|
|
||||||
{
|
|
||||||
[CommandArgument(0, "<PACKAGENAME>")]
|
|
||||||
[Description("The package reference to add.")]
|
|
||||||
public string PackageName { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("-v|--version <VERSION>")]
|
|
||||||
[Description("The version of the package to add.")]
|
|
||||||
public string Version { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
|
||||||
[Description("Add the reference only when targeting a specific framework.")]
|
|
||||||
public string Framework { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--no-restore")]
|
|
||||||
[Description("Add the reference without performing restore preview and compatibility check.")]
|
|
||||||
public bool NoRestore { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--source <SOURCE>")]
|
|
||||||
[Description("The NuGet package source to use during the restore.")]
|
|
||||||
public string Source { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--package-directory <PACKAGEDIR>")]
|
|
||||||
[Description("The directory to restore packages to.")]
|
|
||||||
public string PackageDirectory { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--interactive")]
|
|
||||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
|
||||||
public bool Interactive { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Execute(CommandContext context, Settings settings)
|
|
||||||
{
|
|
||||||
SettingsDumper.Dump(settings);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using Demo.Utilities;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Demo.Commands.Add;
|
|
||||||
|
|
||||||
public sealed class AddReferenceCommand : Command<AddReferenceCommand.Settings>
|
|
||||||
{
|
|
||||||
public sealed class Settings : AddSettings
|
|
||||||
{
|
|
||||||
[CommandArgument(0, "<PROJECTPATH>")]
|
|
||||||
[Description("The package reference to add.")]
|
|
||||||
public string ProjectPath { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
|
||||||
[Description("Add the reference only when targeting a specific framework.")]
|
|
||||||
public string Framework { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--interactive")]
|
|
||||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
|
||||||
public bool Interactive { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Execute(CommandContext context, Settings settings)
|
|
||||||
{
|
|
||||||
SettingsDumper.Dump(settings);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Demo.Commands.Add;
|
|
||||||
|
|
||||||
public abstract class AddSettings : CommandSettings
|
|
||||||
{
|
|
||||||
[CommandArgument(0, "<PROJECT>")]
|
|
||||||
[Description("The project file to operate on. If a file is not specified, the command will search the current directory for one.")]
|
|
||||||
public string Project { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using Demo.Utilities;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Demo.Commands.Run;
|
|
||||||
|
|
||||||
[Description("Build and run a .NET project output.")]
|
|
||||||
public sealed class RunCommand : Command<RunCommand.Settings>
|
|
||||||
{
|
|
||||||
public sealed class Settings : CommandSettings
|
|
||||||
{
|
|
||||||
[CommandOption("-c|--configuration <CONFIGURATION>")]
|
|
||||||
[Description("The configuration to run for. The default for most projects is '[grey]Debug[/]'.")]
|
|
||||||
[DefaultValue("Debug")]
|
|
||||||
public string Configuration { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
|
||||||
[Description("The target framework to run for. The target framework must also be specified in the project file.")]
|
|
||||||
public string Framework { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("-r|--runtime <RUNTIMEIDENTIFIER>")]
|
|
||||||
[Description("The target runtime to run for.")]
|
|
||||||
public string RuntimeIdentifier { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("-p|--project <PROJECTPATH>")]
|
|
||||||
[Description("The path to the project file to run (defaults to the current directory if there is only one project).")]
|
|
||||||
public string ProjectPath { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--launch-profile <LAUNCHPROFILE>")]
|
|
||||||
[Description("The name of the launch profile (if any) to use when launching the application.")]
|
|
||||||
public string LaunchProfile { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--no-launch-profile")]
|
|
||||||
[Description("Do not attempt to use [grey]launchSettings.json[/] to configure the application.")]
|
|
||||||
public bool NoLaunchProfile { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--no-build")]
|
|
||||||
[Description("Do not build the project before running. Implies [grey]--no-restore[/].")]
|
|
||||||
public bool NoBuild { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--interactive")]
|
|
||||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
|
||||||
public string Interactive { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--no-restore")]
|
|
||||||
[Description("Do not restore the project before building.")]
|
|
||||||
public bool NoRestore { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--verbosity <VERBOSITY>")]
|
|
||||||
[Description("Set the MSBuild verbosity level. Allowed values are q[grey]uiet[/], m[grey]inimal[/], n[grey]ormal[/], d[grey]etailed[/], and diag[grey]nostic[/].")]
|
|
||||||
[TypeConverter(typeof(VerbosityConverter))]
|
|
||||||
[DefaultValue(Verbosity.Normal)]
|
|
||||||
public Verbosity Verbosity { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--no-dependencies")]
|
|
||||||
[Description("Do not restore project-to-project references and only restore the specified project.")]
|
|
||||||
public bool NoDependencies { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--force")]
|
|
||||||
[Description("Force all dependencies to be resolved even if the last restore was successful. This is equivalent to deleting [grey]project.assets.json[/].")]
|
|
||||||
public bool Force { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Execute(CommandContext context, Settings settings)
|
|
||||||
{
|
|
||||||
SettingsDumper.Dump(settings);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using Demo.Utilities;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Demo.Commands.Serve;
|
|
||||||
|
|
||||||
[Description("Launches a web server in the current working directory and serves all files in it.")]
|
|
||||||
public sealed class ServeCommand : Command<ServeCommand.Settings>
|
|
||||||
{
|
|
||||||
public sealed class Settings : CommandSettings
|
|
||||||
{
|
|
||||||
[CommandOption("-p|--port <PORT>")]
|
|
||||||
[Description("Port to use. Defaults to [grey]8080[/]. Use [grey]0[/] for a dynamic port.")]
|
|
||||||
public int Port { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("-o|--open-browser [BROWSER]")]
|
|
||||||
[Description("Open a web browser when the server starts. You can also specify which browser to use. If none is specified, the default one will be used.")]
|
|
||||||
public FlagValue<string> OpenBrowser { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Execute(CommandContext context, Settings settings)
|
|
||||||
{
|
|
||||||
if (settings.OpenBrowser.IsSet)
|
|
||||||
{
|
|
||||||
var browser = settings.OpenBrowser.Value;
|
|
||||||
if (browser != null)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Open in {browser}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Open in default browser.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsDumper.Dump(settings);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
<ExampleName>Demo</ExampleName>
|
|
||||||
<ExampleDescription>Demonstrates the most common use cases of Spectre.Cli.</ExampleDescription>
|
|
||||||
<ExampleGroup>Cli</ExampleGroup>
|
|
||||||
<ExampleVisible>false</ExampleVisible>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\..\src\Spectre.Console.Cli\Spectre.Console.Cli.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
using Demo.Commands;
|
|
||||||
using Demo.Commands.Add;
|
|
||||||
using Demo.Commands.Run;
|
|
||||||
using Demo.Commands.Serve;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Demo;
|
|
||||||
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
public static int Main(string[] args)
|
|
||||||
{
|
|
||||||
var app = new CommandApp();
|
|
||||||
app.Configure(config =>
|
|
||||||
{
|
|
||||||
config.SetApplicationName("fake-dotnet");
|
|
||||||
config.ValidateExamples();
|
|
||||||
config.AddExample("run", "--no-build");
|
|
||||||
|
|
||||||
// Run
|
|
||||||
config.AddCommand<RunCommand>("run");
|
|
||||||
|
|
||||||
// Add
|
|
||||||
config.AddBranch<AddSettings>("add", add =>
|
|
||||||
{
|
|
||||||
add.SetDescription("Add a package or reference to a .NET project");
|
|
||||||
add.AddCommand<AddPackageCommand>("package");
|
|
||||||
add.AddCommand<AddReferenceCommand>("reference");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Serve
|
|
||||||
config.AddCommand<ServeCommand>("serve")
|
|
||||||
.WithExample("serve", "-o", "firefox")
|
|
||||||
.WithExample("serve", "--port", "80", "-o", "firefox");
|
|
||||||
});
|
|
||||||
|
|
||||||
return app.Run(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using Spectre.Console;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Demo.Utilities;
|
|
||||||
|
|
||||||
public static class SettingsDumper
|
|
||||||
{
|
|
||||||
public static void Dump(CommandSettings settings)
|
|
||||||
{
|
|
||||||
var table = new Table().RoundedBorder();
|
|
||||||
table.AddColumn("[grey]Name[/]");
|
|
||||||
table.AddColumn("[grey]Value[/]");
|
|
||||||
|
|
||||||
var properties = settings.GetType().GetProperties();
|
|
||||||
foreach (var property in properties)
|
|
||||||
{
|
|
||||||
var value = property.GetValue(settings)
|
|
||||||
?.ToString()
|
|
||||||
?.Replace("[", "[[");
|
|
||||||
|
|
||||||
table.AddRow(
|
|
||||||
property.Name,
|
|
||||||
value ?? "[grey]null[/]");
|
|
||||||
}
|
|
||||||
|
|
||||||
AnsiConsole.Write(table);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
namespace Demo;
|
|
||||||
|
|
||||||
public enum Verbosity
|
|
||||||
{
|
|
||||||
Quiet,
|
|
||||||
Minimal,
|
|
||||||
Normal,
|
|
||||||
Detailed,
|
|
||||||
Diagnostic
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class VerbosityConverter : TypeConverter
|
|
||||||
{
|
|
||||||
private readonly Dictionary<string, Verbosity> _lookup;
|
|
||||||
|
|
||||||
public VerbosityConverter()
|
|
||||||
{
|
|
||||||
_lookup = new Dictionary<string, Verbosity>(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
|
||||||
{ "q", Verbosity.Quiet },
|
|
||||||
{ "quiet", Verbosity.Quiet },
|
|
||||||
{ "m", Verbosity.Minimal },
|
|
||||||
{ "minimal", Verbosity.Minimal },
|
|
||||||
{ "n", Verbosity.Normal },
|
|
||||||
{ "normal", Verbosity.Normal },
|
|
||||||
{ "d", Verbosity.Detailed },
|
|
||||||
{ "detailed", Verbosity.Detailed },
|
|
||||||
{ "diag", Verbosity.Diagnostic },
|
|
||||||
{ "diagnostic", Verbosity.Diagnostic }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
|
||||||
{
|
|
||||||
if (value is string stringValue)
|
|
||||||
{
|
|
||||||
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
const string format = "The value '{0}' is not a valid verbosity.";
|
|
||||||
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
|
||||||
throw new InvalidOperationException(message);
|
|
||||||
}
|
|
||||||
return verbosity;
|
|
||||||
}
|
|
||||||
throw new NotSupportedException("Can't convert value to verbosity.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
<ExampleName>Dynamic</ExampleName>
|
|
||||||
<ExampleDescription>Demonstrates how to define dynamic commands.</ExampleDescription>
|
|
||||||
<ExampleGroup>Cli</ExampleGroup>
|
|
||||||
<ExampleVisible>false</ExampleVisible>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Spectre.Console;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Dynamic;
|
|
||||||
|
|
||||||
public sealed class MyCommand : Command
|
|
||||||
{
|
|
||||||
public override int Execute(CommandContext context)
|
|
||||||
{
|
|
||||||
if (!(context.Data is int data))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Command has no associated data.");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
AnsiConsole.WriteLine("Value = {0}", data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Dynamic;
|
|
||||||
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
public static int Main(string[] args)
|
|
||||||
{
|
|
||||||
var app = new CommandApp();
|
|
||||||
app.Configure(config =>
|
|
||||||
{
|
|
||||||
foreach (var index in Enumerable.Range(1, 10))
|
|
||||||
{
|
|
||||||
config.AddCommand<MyCommand>($"c{index}")
|
|
||||||
.WithDescription($"Prints the number {index}")
|
|
||||||
.WithData(index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return app.Run(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using Spectre.Console;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
using Spectre.Console.Cli.Help;
|
|
||||||
using Spectre.Console.Rendering;
|
|
||||||
|
|
||||||
namespace Help;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Example showing how to extend the built-in Spectre.Console help provider
|
|
||||||
/// by rendering a custom banner at the top of the help information
|
|
||||||
/// </summary>
|
|
||||||
internal class CustomHelpProvider : HelpProvider
|
|
||||||
{
|
|
||||||
public CustomHelpProvider(ICommandAppSettings settings)
|
|
||||||
: base(settings)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<IRenderable> GetHeader(ICommandModel model, ICommandInfo? command)
|
|
||||||
{
|
|
||||||
return new[]
|
|
||||||
{
|
|
||||||
new Text("--------------------------------------"), Text.NewLine,
|
|
||||||
new Text("--- CUSTOM HELP PROVIDER ---"), Text.NewLine,
|
|
||||||
new Text("--------------------------------------"), Text.NewLine,
|
|
||||||
Text.NewLine,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using Spectre.Console;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Help;
|
|
||||||
|
|
||||||
public sealed class DefaultCommand : Command
|
|
||||||
{
|
|
||||||
private IAnsiConsole _console;
|
|
||||||
|
|
||||||
public DefaultCommand(IAnsiConsole console)
|
|
||||||
{
|
|
||||||
_console = console;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Execute(CommandContext context)
|
|
||||||
{
|
|
||||||
_console.WriteLine("Hello world");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<ExampleName>Help</ExampleName>
|
|
||||||
<ExampleDescription>Demonstrates how to extend the built-in Spectre.Console help provider to render a custom banner at the top of the help information.</ExampleDescription>
|
|
||||||
<ExampleGroup>Cli</ExampleGroup>
|
|
||||||
<ExampleVisible>false</ExampleVisible>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Help;
|
|
||||||
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
public static int Main(string[] args)
|
|
||||||
{
|
|
||||||
var app = new CommandApp<DefaultCommand>();
|
|
||||||
|
|
||||||
app.Configure(config =>
|
|
||||||
{
|
|
||||||
// Register the custom help provider
|
|
||||||
config.SetHelpProvider(new CustomHelpProvider(config.Settings));
|
|
||||||
});
|
|
||||||
|
|
||||||
return app.Run(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Injection.Commands;
|
|
||||||
|
|
||||||
public sealed class DefaultCommand : Command<DefaultCommand.Settings>
|
|
||||||
{
|
|
||||||
private readonly IGreeter _greeter;
|
|
||||||
|
|
||||||
public sealed class Settings : CommandSettings
|
|
||||||
{
|
|
||||||
[CommandOption("-n|--name <NAME>")]
|
|
||||||
[Description("The person or thing to greet.")]
|
|
||||||
[DefaultValue("World")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public DefaultCommand(IGreeter greeter)
|
|
||||||
{
|
|
||||||
_greeter = greeter ?? throw new ArgumentNullException(nameof(greeter));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Execute(CommandContext context, Settings settings)
|
|
||||||
{
|
|
||||||
_greeter.Greet(settings.Name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using Spectre.Console;
|
|
||||||
|
|
||||||
namespace Injection;
|
|
||||||
|
|
||||||
public interface IGreeter
|
|
||||||
{
|
|
||||||
void Greet(string name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class HelloWorldGreeter : IGreeter
|
|
||||||
{
|
|
||||||
public void Greet(string name)
|
|
||||||
{
|
|
||||||
AnsiConsole.WriteLine($"Hello {name}!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Injection.Infrastructure;
|
|
||||||
|
|
||||||
public sealed class TypeRegistrar : ITypeRegistrar
|
|
||||||
{
|
|
||||||
private readonly IServiceCollection _builder;
|
|
||||||
|
|
||||||
public TypeRegistrar(IServiceCollection builder)
|
|
||||||
{
|
|
||||||
_builder = builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ITypeResolver Build()
|
|
||||||
{
|
|
||||||
return new TypeResolver(_builder.BuildServiceProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Register(Type service, Type implementation)
|
|
||||||
{
|
|
||||||
_builder.AddSingleton(service, implementation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterInstance(Type service, object implementation)
|
|
||||||
{
|
|
||||||
_builder.AddSingleton(service, implementation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterLazy(Type service, Func<object> func)
|
|
||||||
{
|
|
||||||
if (func is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(func));
|
|
||||||
}
|
|
||||||
|
|
||||||
_builder.AddSingleton(service, (provider) => func());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Injection.Infrastructure;
|
|
||||||
|
|
||||||
public sealed class TypeResolver : ITypeResolver, IDisposable
|
|
||||||
{
|
|
||||||
private readonly IServiceProvider _provider;
|
|
||||||
|
|
||||||
public TypeResolver(IServiceProvider provider)
|
|
||||||
{
|
|
||||||
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Resolve(Type type)
|
|
||||||
{
|
|
||||||
if (type == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _provider.GetService(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_provider is IDisposable disposable)
|
|
||||||
{
|
|
||||||
disposable.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
<ExampleName>Injection</ExampleName>
|
|
||||||
<ExampleDescription>Demonstrates how to use dependency injection with Spectre.Cli.</ExampleDescription>
|
|
||||||
<ExampleGroup>Cli</ExampleGroup>
|
|
||||||
<ExampleVisible>false</ExampleVisible>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
using Injection.Commands;
|
|
||||||
using Injection.Infrastructure;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Injection;
|
|
||||||
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
public static int Main(string[] args)
|
|
||||||
{
|
|
||||||
// Create a type registrar and register any dependencies.
|
|
||||||
// A type registrar is an adapter for a DI framework.
|
|
||||||
var registrations = new ServiceCollection();
|
|
||||||
registrations.AddSingleton<IGreeter, HelloWorldGreeter>();
|
|
||||||
var registrar = new TypeRegistrar(registrations);
|
|
||||||
|
|
||||||
// Create a new command app with the registrar
|
|
||||||
// and run it with the provided arguments.
|
|
||||||
var app = new CommandApp<DefaultCommand>(registrar);
|
|
||||||
return app.Run(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Spectre.Console;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Logging.Commands;
|
|
||||||
|
|
||||||
public class HelloCommand : Command<HelloCommand.Settings>
|
|
||||||
{
|
|
||||||
private ILogger<HelloCommand> _logger;
|
|
||||||
private IAnsiConsole _console;
|
|
||||||
|
|
||||||
public HelloCommand(IAnsiConsole console, ILogger<HelloCommand> logger)
|
|
||||||
{
|
|
||||||
_console = console;
|
|
||||||
_logger = logger;
|
|
||||||
_logger.LogDebug("{0} initialized", nameof(HelloCommand));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Settings : LogCommandSettings
|
|
||||||
{
|
|
||||||
[CommandArgument(0, "[Name]")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override int Execute(CommandContext context, Settings settings)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Starting my command");
|
|
||||||
AnsiConsole.MarkupLine($"Hello, [blue]{settings.Name}[/]");
|
|
||||||
_logger.LogInformation("Completed my command");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Globalization;
|
|
||||||
using Serilog.Events;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Logging.Commands;
|
|
||||||
|
|
||||||
public class LogCommandSettings : CommandSettings
|
|
||||||
{
|
|
||||||
[CommandOption("--logFile")]
|
|
||||||
[Description("Path and file name for logging")]
|
|
||||||
public string LogFile { get; set; }
|
|
||||||
|
|
||||||
[CommandOption("--logLevel")]
|
|
||||||
[Description("Minimum level for logging")]
|
|
||||||
[TypeConverter(typeof(VerbosityConverter))]
|
|
||||||
[DefaultValue(LogEventLevel.Information)]
|
|
||||||
public LogEventLevel LogLevel { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class VerbosityConverter : TypeConverter
|
|
||||||
{
|
|
||||||
private readonly Dictionary<string, LogEventLevel> _lookup;
|
|
||||||
|
|
||||||
public VerbosityConverter()
|
|
||||||
{
|
|
||||||
_lookup = new Dictionary<string, LogEventLevel>(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
|
||||||
{"d", LogEventLevel.Debug},
|
|
||||||
{"v", LogEventLevel.Verbose},
|
|
||||||
{"i", LogEventLevel.Information},
|
|
||||||
{"w", LogEventLevel.Warning},
|
|
||||||
{"e", LogEventLevel.Error},
|
|
||||||
{"f", LogEventLevel.Fatal}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
|
||||||
{
|
|
||||||
if (value is string stringValue)
|
|
||||||
{
|
|
||||||
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
const string format = "The value '{0}' is not a valid verbosity.";
|
|
||||||
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
|
||||||
throw new InvalidOperationException(message);
|
|
||||||
}
|
|
||||||
return verbosity;
|
|
||||||
}
|
|
||||||
throw new NotSupportedException("Can't convert value to verbosity.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using Logging.Commands;
|
|
||||||
using Serilog.Core;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Logging.Infrastructure;
|
|
||||||
|
|
||||||
public class LogInterceptor : ICommandInterceptor
|
|
||||||
{
|
|
||||||
public static readonly LoggingLevelSwitch LogLevel = new();
|
|
||||||
|
|
||||||
public void Intercept(CommandContext context, CommandSettings settings)
|
|
||||||
{
|
|
||||||
if (settings is LogCommandSettings logSettings)
|
|
||||||
{
|
|
||||||
LoggingEnricher.Path = logSettings.LogFile ?? "application.log";
|
|
||||||
LogLevel.MinimumLevel = logSettings.LogLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using Serilog.Core;
|
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Logging.Infrastructure;
|
|
||||||
|
|
||||||
internal class LoggingEnricher : ILogEventEnricher
|
|
||||||
{
|
|
||||||
private string _cachedLogFilePath;
|
|
||||||
private LogEventProperty _cachedLogFilePathProperty;
|
|
||||||
|
|
||||||
// this path and level will be set by the LogInterceptor.cs after parsing the settings
|
|
||||||
public static string Path = string.Empty;
|
|
||||||
|
|
||||||
public const string LogFilePathPropertyName = "LogFilePath";
|
|
||||||
|
|
||||||
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
|
|
||||||
{
|
|
||||||
// the settings might not have a path or we might not be within a command in which case
|
|
||||||
// we won't have the setting so a default value for the log file will be required
|
|
||||||
LogEventProperty logFilePathProperty;
|
|
||||||
|
|
||||||
if (_cachedLogFilePathProperty != null && Path.Equals(_cachedLogFilePath))
|
|
||||||
{
|
|
||||||
// Path hasn't changed, so let's use the cached property
|
|
||||||
logFilePathProperty = _cachedLogFilePathProperty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We've got a new path for the log. Let's create a new property
|
|
||||||
// and cache it for future log events to use
|
|
||||||
_cachedLogFilePath = Path;
|
|
||||||
_cachedLogFilePathProperty = logFilePathProperty = propertyFactory.CreateProperty(LogFilePathPropertyName, Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
logEvent.AddPropertyIfAbsent(logFilePathProperty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Spectre.Console.Cli;
|
|
||||||
|
|
||||||
namespace Logging.Infrastructure;
|
|
||||||
|
|
||||||
public sealed class TypeRegistrar : ITypeRegistrar
|
|
||||||
{
|
|
||||||
private readonly IServiceCollection _builder;
|
|
||||||
|
|
||||||
public TypeRegistrar(IServiceCollection builder)
|
|
||||||
{
|
|
||||||
_builder = builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ITypeResolver Build()
|
|
||||||
{
|
|
||||||
return new TypeResolver(_builder.BuildServiceProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Register(Type service, Type implementation)
|
|
||||||
{
|
|
||||||
_builder.AddSingleton(service, implementation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterInstance(Type service, object implementation)
|
|
||||||
{
|
|
||||||
_builder.AddSingleton(service, implementation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterLazy(Type service, Func<object> func)
|
|
||||||
{
|
|
||||||
if (func is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(func));
|
|
||||||
}
|
|
||||||
|
|
||||||
_builder.AddSingleton(service, _ => func());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user