Compare commits
9 Commits
0dfacc31d4
...
195b936de6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
195b936de6 | ||
|
|
f6b5186f31 | ||
|
|
ea16ba8430 | ||
|
|
96ce572792 | ||
|
|
d638f201fe | ||
|
|
e09bdd78c2 | ||
|
|
0034a6f4e2 | ||
|
|
aa66695665 | ||
|
|
a7e4c501e4 |
160
.gitea/workflows/pr-validation.yml
Normal file
160
.gitea/workflows/pr-validation.yml
Normal file
@@ -0,0 +1,160 @@
|
||||
name: Pull Request Validation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
ARTEFACT_BUCKET_NAME: ${{ vars.ARTEFACT_BUCKET_NAME }}
|
||||
ARTEFACT_BUCKET_ENDPONT: ${{ vars.ARTEFACT_BUCKET_ENDPONT }}
|
||||
ARTEFACT_BUCKET_REGION: ${{ vars.ARTEFACT_BUCKET_REGION }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.ARTEFACT_BUCKET_WRITE_ACCESS_KEY }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.ARTEFACT_BUCKET_WRITE_ACCESS_SECRET }}
|
||||
AWS_DEFAULT_REGION: ${{ vars.ARTEFACT_BUCKET_REGION }}
|
||||
AWS_EC2_METADATA_DISABLED: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Ensure tooling is available
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if ! command -v aws >/dev/null 2>&1; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y awscli jq
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y jq
|
||||
fi
|
||||
|
||||
- name: Run full unit test suite with coverage
|
||||
id: coverage
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
go test -covermode=atomic -coverprofile=coverage.out ./...
|
||||
go tool cover -html=coverage.out -o coverage.html
|
||||
|
||||
total="$(go tool cover -func=coverage.out | awk '/^total:/ {sub(/%/, "", $3); print $3}')"
|
||||
printf '{\n "total": "%s"\n}\n' "$total" > coverage-summary.json
|
||||
printf 'total=%s\n' "$total" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate coverage badge
|
||||
env:
|
||||
COVERAGE_TOTAL: ${{ steps.coverage.outputs.total }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
color="$(awk -v total="$COVERAGE_TOTAL" 'BEGIN {
|
||||
if (total >= 80) print "brightgreen";
|
||||
else if (total >= 70) print "green";
|
||||
else if (total >= 60) print "yellowgreen";
|
||||
else if (total >= 50) print "yellow";
|
||||
else print "red";
|
||||
}')"
|
||||
|
||||
cat > coverage-badge.svg <<EOF
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="126" height="20" role="img" aria-label="coverage: ${COVERAGE_TOTAL}%">
|
||||
<linearGradient id="smooth" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
||||
<stop offset="1" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="round">
|
||||
<rect width="126" height="20" rx="3" fill="#fff"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#round)">
|
||||
<rect width="63" height="20" fill="#555"/>
|
||||
<rect x="63" width="63" height="20" fill="${color}"/>
|
||||
<rect width="126" height="20" fill="url(#smooth)"/>
|
||||
</g>
|
||||
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
||||
<text x="32.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
|
||||
<text x="32.5" y="14">coverage</text>
|
||||
<text x="93.5" y="15" fill="#010101" fill-opacity=".3">${COVERAGE_TOTAL}%</text>
|
||||
<text x="93.5" y="14">${COVERAGE_TOTAL}%</text>
|
||||
</g>
|
||||
</svg>
|
||||
EOF
|
||||
|
||||
- name: Upload PR coverage artefacts
|
||||
id: upload
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
aws configure set default.s3.addressing_style path
|
||||
|
||||
repo_name="${GITHUB_REPOSITORY##*/}"
|
||||
prefix="${repo_name}/pull-requests/${{ github.event.pull_request.number }}"
|
||||
report_url="${ARTEFACT_BUCKET_ENDPONT%/}/${ARTEFACT_BUCKET_NAME}/${prefix}/coverage.html"
|
||||
badge_url="${ARTEFACT_BUCKET_ENDPONT%/}/${ARTEFACT_BUCKET_NAME}/${prefix}/coverage-badge.svg"
|
||||
|
||||
aws --endpoint-url "${ARTEFACT_BUCKET_ENDPONT}" s3 cp coverage.html "s3://${ARTEFACT_BUCKET_NAME}/${prefix}/coverage.html" --content-type text/html
|
||||
aws --endpoint-url "${ARTEFACT_BUCKET_ENDPONT}" s3 cp coverage-badge.svg "s3://${ARTEFACT_BUCKET_NAME}/${prefix}/coverage-badge.svg" --content-type image/svg+xml
|
||||
aws --endpoint-url "${ARTEFACT_BUCKET_ENDPONT}" s3 cp coverage-summary.json "s3://${ARTEFACT_BUCKET_NAME}/${prefix}/coverage-summary.json" --content-type application/json
|
||||
|
||||
printf 'report_url=%s\n' "$report_url" >> "$GITHUB_OUTPUT"
|
||||
printf 'badge_url=%s\n' "$badge_url" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Comment coverage report on pull request
|
||||
env:
|
||||
COVERAGE_BADGE_URL: ${{ steps.upload.outputs.badge_url }}
|
||||
COVERAGE_REPORT_URL: ${{ steps.upload.outputs.report_url }}
|
||||
COVERAGE_TOTAL: ${{ steps.coverage.outputs.total }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
marker='<!-- gosick-coverage-report -->'
|
||||
api_base="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
|
||||
|
||||
payload="$(jq -n \
|
||||
--arg marker "$marker" \
|
||||
--arg total "$COVERAGE_TOTAL" \
|
||||
--arg report "$COVERAGE_REPORT_URL" \
|
||||
--arg badge "$COVERAGE_BADGE_URL" \
|
||||
'{body: ($marker + "\n## Coverage Report\n\nCoverage total: **" + $total + "%**\n\n[HTML report](" + $report + ")\n\n")}')"
|
||||
|
||||
comments="$(curl -sS -H "Authorization: token ${GITHUB_TOKEN}" "${api_base}/issues/${{ github.event.pull_request.number }}/comments")"
|
||||
comment_id="$(printf '%s' "$comments" | jq -r '.[] | select(.body | contains("<!-- gosick-coverage-report -->")) | .id' | tail -n 1)"
|
||||
|
||||
if [[ -n "$comment_id" ]]; then
|
||||
curl -sS -X PATCH \
|
||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "$payload" \
|
||||
"${api_base}/issues/comments/${comment_id}" >/dev/null
|
||||
else
|
||||
curl -sS -X POST \
|
||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "$payload" \
|
||||
"${api_base}/issues/${{ github.event.pull_request.number }}/comments" >/dev/null
|
||||
fi
|
||||
|
||||
- name: Add coverage summary
|
||||
run: |
|
||||
{
|
||||
echo '## Coverage'
|
||||
echo
|
||||
echo '- Total: `${{ steps.coverage.outputs.total }}%`'
|
||||
echo '- Report: ${{ steps.upload.outputs.report_url }}'
|
||||
echo '- Badge: ${{ steps.upload.outputs.badge_url }}'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: Run behavior suite
|
||||
run: ./script/run-behavior-suite-docker.sh
|
||||
119
.gitea/workflows/push-validation.yml
Normal file
119
.gitea/workflows/push-validation.yml
Normal file
@@ -0,0 +1,119 @@
|
||||
name: Push Validation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "*"
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
ARTEFACT_BUCKET_NAME: ${{ vars.ARTEFACT_BUCKET_NAME }}
|
||||
ARTEFACT_BUCKET_ENDPONT: ${{ vars.ARTEFACT_BUCKET_ENDPONT }}
|
||||
ARTEFACT_BUCKET_REGION: ${{ vars.ARTEFACT_BUCKET_REGION }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.ARTEFACT_BUCKET_WRITE_ACCESS_KEY }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.ARTEFACT_BUCKET_WRITE_ACCESS_SECRET }}
|
||||
AWS_DEFAULT_REGION: ${{ vars.ARTEFACT_BUCKET_REGION }}
|
||||
AWS_EC2_METADATA_DISABLED: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Ensure tooling is available
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if ! command -v aws >/dev/null 2>&1; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y awscli
|
||||
fi
|
||||
|
||||
- name: Run full unit test suite with coverage
|
||||
id: coverage
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
go test -covermode=atomic -coverprofile=coverage.out ./...
|
||||
go tool cover -html=coverage.out -o coverage.html
|
||||
|
||||
total="$(go tool cover -func=coverage.out | awk '/^total:/ {sub(/%/, "", $3); print $3}')"
|
||||
printf '{\n "total": "%s"\n}\n' "$total" > coverage-summary.json
|
||||
printf 'total=%s\n' "$total" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate coverage badge
|
||||
env:
|
||||
COVERAGE_TOTAL: ${{ steps.coverage.outputs.total }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
color="$(awk -v total="$COVERAGE_TOTAL" 'BEGIN {
|
||||
if (total >= 80) print "brightgreen";
|
||||
else if (total >= 70) print "green";
|
||||
else if (total >= 60) print "yellowgreen";
|
||||
else if (total >= 50) print "yellow";
|
||||
else print "red";
|
||||
}')"
|
||||
|
||||
cat > coverage-badge.svg <<EOF
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="126" height="20" role="img" aria-label="coverage: ${COVERAGE_TOTAL}%">
|
||||
<linearGradient id="smooth" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
||||
<stop offset="1" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="round">
|
||||
<rect width="126" height="20" rx="3" fill="#fff"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#round)">
|
||||
<rect width="63" height="20" fill="#555"/>
|
||||
<rect x="63" width="63" height="20" fill="${color}"/>
|
||||
<rect width="126" height="20" fill="url(#smooth)"/>
|
||||
</g>
|
||||
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
||||
<text x="32.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
|
||||
<text x="32.5" y="14">coverage</text>
|
||||
<text x="93.5" y="15" fill="#010101" fill-opacity=".3">${COVERAGE_TOTAL}%</text>
|
||||
<text x="93.5" y="14">${COVERAGE_TOTAL}%</text>
|
||||
</g>
|
||||
</svg>
|
||||
EOF
|
||||
|
||||
- name: Upload branch coverage artefacts
|
||||
id: upload
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
aws configure set default.s3.addressing_style path
|
||||
|
||||
repo_name="${GITHUB_REPOSITORY##*/}"
|
||||
prefix="${repo_name}/branch/${GITHUB_REF_NAME}"
|
||||
report_url="${ARTEFACT_BUCKET_ENDPONT%/}/${ARTEFACT_BUCKET_NAME}/${prefix}/coverage.html"
|
||||
badge_url="${ARTEFACT_BUCKET_ENDPONT%/}/${ARTEFACT_BUCKET_NAME}/${prefix}/coverage-badge.svg"
|
||||
|
||||
aws --endpoint-url "${ARTEFACT_BUCKET_ENDPONT}" s3 cp coverage.html "s3://${ARTEFACT_BUCKET_NAME}/${prefix}/coverage.html" --content-type text/html
|
||||
aws --endpoint-url "${ARTEFACT_BUCKET_ENDPONT}" s3 cp coverage-badge.svg "s3://${ARTEFACT_BUCKET_NAME}/${prefix}/coverage-badge.svg" --content-type image/svg+xml
|
||||
aws --endpoint-url "${ARTEFACT_BUCKET_ENDPONT}" s3 cp coverage-summary.json "s3://${ARTEFACT_BUCKET_NAME}/${prefix}/coverage-summary.json" --content-type application/json
|
||||
|
||||
printf 'report_url=%s\n' "$report_url" >> "$GITHUB_OUTPUT"
|
||||
printf 'badge_url=%s\n' "$badge_url" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Add coverage summary
|
||||
run: |
|
||||
{
|
||||
echo '## Coverage'
|
||||
echo
|
||||
echo '- Total: `${{ steps.coverage.outputs.total }}%`'
|
||||
echo '- Report: ${{ steps.upload.outputs.report_url }}'
|
||||
echo '- Badge: ${{ steps.upload.outputs.badge_url }}'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: Run behavior suite on main pushes
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
run: ./script/run-behavior-suite-docker.sh
|
||||
107
.gitea/workflows/tag-build-artifacts.yml
Normal file
107
.gitea/workflows/tag-build-artifacts.yml
Normal file
@@ -0,0 +1,107 @@
|
||||
name: Tag Build Artifacts
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- goos: linux
|
||||
goarch: amd64
|
||||
- goos: linux
|
||||
goarch: arm64
|
||||
- goos: darwin
|
||||
goarch: amd64
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Build binary
|
||||
run: |
|
||||
mkdir -p dist
|
||||
GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} CGO_ENABLED=0 \
|
||||
go build -o dist/gosick_${{ matrix.goos }}_${{ matrix.goarch }} ./cmd/homesick
|
||||
|
||||
- name: Package artifact
|
||||
run: |
|
||||
cd dist
|
||||
tar -czf gosick_${{ matrix.goos }}_${{ matrix.goarch }}.tar.gz gosick_${{ matrix.goos }}_${{ matrix.goarch }}
|
||||
|
||||
- name: Publish workflow artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: gosick_${{ matrix.goos }}_${{ matrix.goarch }}
|
||||
path: dist/gosick_${{ matrix.goos }}_${{ matrix.goarch }}.tar.gz
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: dist
|
||||
|
||||
- name: Ensure jq is installed
|
||||
run: |
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y jq
|
||||
fi
|
||||
|
||||
- name: Create release if needed and upload assets
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [[ -z "${RELEASE_TOKEN:-}" ]]; then
|
||||
echo "RELEASE_TOKEN is empty. Expected secrets.GITHUB_TOKEN to be available." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tag="${GITHUB_REF_NAME}"
|
||||
api_base="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
|
||||
|
||||
release_json="$(curl -sS -H "Authorization: token ${RELEASE_TOKEN}" "${api_base}/releases/tags/${tag}" || true)"
|
||||
release_id="$(printf '%s' "${release_json}" | jq -r '.id // empty')"
|
||||
|
||||
if [[ -z "${release_id}" ]]; then
|
||||
create_payload="$(jq -n --arg tag "${tag}" --arg name "${tag}" '{tag_name:$tag, name:$name, draft:false, prerelease:false}')"
|
||||
release_json="$(curl -sS -X POST \
|
||||
-H "Authorization: token ${RELEASE_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "${create_payload}" \
|
||||
"${api_base}/releases")"
|
||||
release_id="$(printf '%s' "${release_json}" | jq -r '.id // empty')"
|
||||
fi
|
||||
|
||||
if [[ -z "${release_id}" ]]; then
|
||||
echo "Unable to determine or create release id for tag ${tag}" >&2
|
||||
printf '%s\n' "${release_json}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
find dist -type f -name '*.tar.gz' -print0 | while IFS= read -r -d '' file; do
|
||||
asset_name="$(basename "${file}")"
|
||||
curl -sS -X POST \
|
||||
-H "Authorization: token ${RELEASE_TOKEN}" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary @"${file}" \
|
||||
"${api_base}/releases/${release_id}/assets?name=${asset_name}"
|
||||
echo "Uploaded ${asset_name}"
|
||||
done
|
||||
@@ -1,5 +1,9 @@
|
||||
# homesick
|
||||
|
||||
[](https://git.hrafn.xyz/aether/gosick/actions/workflows/push-validation.yml)
|
||||
[](https://git.hrafn.xyz/aether/gosick/actions/workflows/pr-validation.yml)
|
||||
[](https://git.hrafn.xyz/aether/gosick/actions/workflows/tag-build-artifacts.yml)
|
||||
|
||||
Your home directory is your castle. Don't leave your dotfiles behind.
|
||||
|
||||
This repository now contains a Go implementation of Homesick. A dotfiles repository is called a castle and should contain a `home/` directory with files to link into your `$HOME`.
|
||||
|
||||
@@ -13,12 +13,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Containerized behavior test suite for command parity validation.
|
||||
- Dedicated test suites for `list`, `show_path`, `status`, `diff`, and `version`.
|
||||
- Just workflow support for building and running the Linux behavior binary.
|
||||
- Coverage reports and badges published to shared object storage for branches and pull requests.
|
||||
- Pull requests now receive coverage report links in CI comments.
|
||||
|
||||
### Changed
|
||||
|
||||
- CLI argument parsing migrated to Kong.
|
||||
- Git operations for clone and track migrated to `go-git`.
|
||||
- Build and behavior workflows now produce and run the `gosick` binary name.
|
||||
- CI validation is unified into push events, running behavior tests only on `main` pushes.
|
||||
- Gitea workflow and README badge updated from `push-unit-tests` to `push-validation`.
|
||||
- CLI help now uses the invoked binary name (defaulting to `gosick`) in usage output.
|
||||
- CLI help description now reflects Homesick's purpose for managing precious dotfiles.
|
||||
- Release notes standardized to Keep a Changelog format.
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"git.hrafn.xyz/aether/gosick/internal/homesick/core"
|
||||
@@ -21,8 +22,8 @@ func Run(args []string, stdout io.Writer, stderr io.Writer) int {
|
||||
|
||||
parser, err := kong.New(
|
||||
&cliModel{},
|
||||
kong.Name("homesick"),
|
||||
kong.Description("Go scaffold"),
|
||||
kong.Name(programName()),
|
||||
kong.Description("Your home is your castle. Don't leave your precious dotfiles behind."),
|
||||
kong.Writers(stdout, stderr),
|
||||
kong.Exit(func(int) {}),
|
||||
kong.ConfigureHelp(kong.HelpOptions{Compact: true}),
|
||||
@@ -192,6 +193,16 @@ func defaultCastle(castle string) string {
|
||||
return castle
|
||||
}
|
||||
|
||||
func programName() string {
|
||||
if len(os.Args) > 0 {
|
||||
if name := strings.TrimSpace(filepath.Base(os.Args[0])); name != "" {
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
return "gosick"
|
||||
}
|
||||
|
||||
func normalizeArgs(args []string) []string {
|
||||
if len(args) == 0 {
|
||||
return []string{"--help"}
|
||||
|
||||
@@ -59,4 +59,18 @@ func (s *CLISuite) TestRun_CloneSubcommandHelp() {
|
||||
require.Contains(s.T(), s.stdout.String(), "clone")
|
||||
require.Contains(s.T(), s.stdout.String(), "URI")
|
||||
require.Empty(s.T(), s.stderr.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CLISuite) TestRun_Help_UsesProgramNameAndDescription() {
|
||||
originalArgs := os.Args
|
||||
s.T().Cleanup(func() { os.Args = originalArgs })
|
||||
os.Args = []string{"gosick"}
|
||||
|
||||
exitCode := cli.Run([]string{"--help"}, s.stdout, s.stderr)
|
||||
|
||||
require.Equal(s.T(), 0, exitCode)
|
||||
require.Contains(s.T(), s.stdout.String(), "Usage: gosick")
|
||||
require.NotContains(s.T(), s.stdout.String(), "Usage: homesick")
|
||||
require.Contains(s.T(), s.stdout.String(), "precious dotfiles")
|
||||
require.Empty(s.T(), s.stderr.String())
|
||||
}
|
||||
|
||||
@@ -510,10 +510,6 @@ func matchesIgnoredDir(castleHome string, candidate string, subdirs []string) (b
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
func runGit(dir string, args ...string) error {
|
||||
return runGitWithIO(dir, os.Stdout, os.Stderr, args...)
|
||||
}
|
||||
|
||||
func runGitWithIO(dir string, stdout io.Writer, stderr io.Writer, args ...string) error {
|
||||
cmd := exec.Command("git", args...)
|
||||
cmd.Dir = dir
|
||||
|
||||
Reference in New Issue
Block a user