diff --git a/.asdf b/.asdf deleted file mode 100644 index 4a1a18ea..00000000 --- a/.asdf +++ /dev/null @@ -1,37 +0,0 @@ -### Examples: ### -# Employ asdf for go, ruby, and python used by this project only: -# source .asdf -# Employ asdf for python used by this project only: -# source .asdf python - -# Define the URL of setup_asdf.sh -setup_asdf_url="https://raw.githubusercontent.com/l50/dotfiles/main/files/setup_asdf.sh" - -# Define the local path of setup_asdf.sh -setup_asdf_path="/tmp/setup_asdf.sh" - -# Check if setup_asdf.sh exists locally -if [[ ! -f "${setup_asdf_path}" ]]; then - # setup_asdf.sh doesn't exist locally, so download it - curl -s "${setup_asdf_url}" -o "${setup_asdf_path}" -fi - -# Source /tmp/setup_asdf.sh -# shellcheck source=/dev/null -source "${setup_asdf_path}" - -# Function to setup language -setup_language_if_requested() { - local language="$1" - - # Check if the language is requested or if no language is specified - if [[ " $* " =~ ${language} ]] || [[ $# -eq 0 ]]; then - # Setup the language - setup_language "$language" "local" - fi -} - -# Call setup_language_if_requested for each language -setup_language_if_requested "$@" "golang" -setup_language_if_requested "$@" "python" -setup_language_if_requested "$@" "ruby" diff --git a/.devcontainer/bash/Dockerfile b/.devcontainer/bash/Dockerfile deleted file mode 100644 index 46179b94..00000000 --- a/.devcontainer/bash/Dockerfile +++ /dev/null @@ -1,96 +0,0 @@ -FROM golang:1.21.3-alpine - -LABEL org.opencontainers.image.source=https://github.com/facebookincubator/TTPForge -LABEL org.opencontainers.image.description="Dev Container with dependencies and tools for building and testing the TTPForge project" - -ARG GITHUB_CLI_VERSION=2.32.1 -ARG SETUP_TOOLS_VER=65.5.1 # Avoid vulnerable versions - -# Install dependencies -RUN apk add --no-cache \ - bash \ - binutils-gold \ - build-base \ - curl \ - gcc \ - git \ - gpgme \ - libc-dev \ - make \ - nodejs \ - npm \ - openssl-dev \ - python3 \ - python3-dev \ - py3-pip \ - readline-dev \ - ruby-dev \ - ruby-full \ - shellcheck \ - sqlite-dev \ - unzip \ - vim \ - yaml-dev \ - zlib-dev - -# Create the ttpforge user and change ownership of the necessary directories -RUN adduser -D -s /bin/sh ttpforge \ - && mkdir -p /home/ttpforge/go/src/github.com/facebookincubator/TTPForge \ - && chown -R ttpforge:ttpforge /home/ttpforge - -# Copy mage_completion.sh -COPY .devcontainer/bash/files/mage_completion.sh /etc/bash_completion.d/ - -# Install GitHub CLI -RUN export ARCH="$(uname -m)" \ - && case ${ARCH} in \ - x86_64) ARCH='amd64' ;; \ - aarch64) ARCH='arm64' ;; \ - arm*) ARCH='armv6' ;; \ - *) echo "Unsupported architecture: ${ARCH}" && exit 1 ;; \ - esac \ - && curl -sSL "https://github.com/cli/cli/releases/download/v${GITHUB_CLI_VERSION}/gh_${GITHUB_CLI_VERSION}_linux_${ARCH}.tar.gz" | tar xz \ - && mv "gh_${GITHUB_CLI_VERSION}_linux_${ARCH}/bin/gh" /usr/local/bin \ - && gh --version - -USER ttpforge -ENV HOME=/home/ttpforge \ - GOPATH=/home/ttpforge/go \ - PATH=$PATH:/usr/local/go/bin:$GOPATH/bin:/home/ttpforge/.local/bin - -# Add the completion script to the user's .bashrc -RUN echo "source /etc/bash_completion.d/mage_completion.sh" >> $HOME/.bashrc - -WORKDIR /home/ttpforge/go/src/github.com/facebookincubator/ttpforge -COPY --chown=ttpforge . . - -# Setup Python environment, Go dependencies, and build -RUN python3 -m venv $HOME/venv \ - && . $HOME/venv/bin/activate \ - && pip3 install --upgrade pip \ - "setuptools>=${SETUP_TOOLS_VER}" \ - pre-commit \ - && pre-commit install-hooks \ - && go install github.com/magefile/mage@latest \ - && go install mvdan.cc/sh/v3/cmd/shfmt@latest \ - && PATH=$HOME/venv/bin:$GOPATH/bin:$PATH \ - && mage installDeps \ - && mage \ - && go mod tidy \ - && go build -o ttpforge \ - && rm ttpforge - -# Update PATH to include virtual environment and Go binaries -ENV PATH=$HOME/venv/bin:$GOPATH/bin:$PATH - -# Add the completion script to the user's .bashrc -RUN echo '### Mage Autocomplete ###' >> $HOME/.bashrc \ - && echo '# This section will not run during a bats test.' >> $HOME/.bashrc \ - && echo 'if [[ $RUNNING_BATS_TEST != 1 ]]; then' >> $HOME/.bashrc \ - && echo ' # The functions below are required for mage autocomplete' >> $HOME/.bashrc \ - && echo ' _get_comp_words_by_ref() { :; }' >> $HOME/.bashrc \ - && echo ' __ltrim_colon_completions() { :; }' >> $HOME/.bashrc \ - && echo " source \"/etc/bash_completion.d/mage_completion.sh\"" >> $HOME/.bashrc \ - && echo 'fi' >> $HOME/.bashrc - -CMD ["bash"] diff --git a/.devcontainer/bash/devcontainer.json b/.devcontainer/bash/devcontainer.json deleted file mode 100644 index d45793de..00000000 --- a/.devcontainer/bash/devcontainer.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "TTPForge Bash Container", - "image": "ghcr.io/facebookincubator/ttpforge:latest", - "remoteUser": "ttpforge", - "customizations": { - "vscode": { - "extensions": [ - "golang.go", - "ms-python.python", - "mads-hartmann.bash-ide-vscode", - "redhat.vscode-yaml", - "hashicorp.terraform" - ] - } - } -} diff --git a/.devcontainer/bash/files/mage_completion.sh b/.devcontainer/bash/files/mage_completion.sh deleted file mode 100755 index 5d249ebe..00000000 --- a/.devcontainer/bash/files/mage_completion.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -# https://github.com/magefile/mage/issues/113 -_mage_completions() -{ - local cur prev opts - - # namespaces with colon - _get_comp_words_by_ref -n : cur - - # prev word. - prev="${COMP_WORDS[COMP_CWORD - 1]}" - - case "${prev}" in - -compile) - COMPREPLY+=("$( compgen -f -- "${cur}")") - ;; - -d) - COMPREPLY+=("$( compgen -d -- "${cur}")") - ;; - -gocmd) - COMPREPLY+=("$( compgen -W "${opts}" -- "${cur}")") - ;; - -t) - opts="30s 1m 1m30s 2m 2m30s 3m 3m30s 4m 4m30s 5m 10m 20m 30m 1h" - COMPREPLY+=("$( compgen -W "${opts}" -- "${cur}")") - ;; - *) - if [[ ${cur} == -* ]]; then - opts="$(mage -h | grep "^\\s*-" | awk '{print $1}')" - else - opts="$(mage -l | tail -n +2 | awk '{print tolower($1)}')" - fi - COMPREPLY+=("$( compgen -W "${opts}" -- "${cur}")") - ;; - esac - - __ltrim_colon_completions "$cur" -} - -complete -F _mage_completions mage diff --git a/.docgenignore b/.docgenignore deleted file mode 100644 index 808f06c5..00000000 --- a/.docgenignore +++ /dev/null @@ -1 +0,0 @@ -ttps diff --git a/.editorconfig b/.editorconfig deleted file mode 100755 index e407b18b..00000000 --- a/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -[*.sh] -# like -i=4 -indent_style = space -indent_size = 4 - -binary_next_line = true # like -bn -switch_case_indent = true # like -ci -space_redirects = true # like -sr -keep_padding = true # like -kp -function_next_line = true # like -fn diff --git a/.github/labels.yaml b/.github/labels.yaml index 0af8b35f..34a8e39b 100755 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -20,13 +20,6 @@ color: "#c5def5" description: >- Changes made to ttps -# Renovate -- name: renovate/container - color: "ffc300" -- name: renovate/github-action - color: "ffc300" -- name: renovate/github-release - color: "ffc300" # Semantic Type - name: type/digest color: "FFEC19" diff --git a/.github/workflows/container.yaml b/.github/workflows/container.yaml deleted file mode 100644 index 384e55d9..00000000 --- a/.github/workflows/container.yaml +++ /dev/null @@ -1,47 +0,0 @@ ---- -name: Build, Publish, and Test Container Images -on: - push: - branches: - - main - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: - IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/ttpforge - -jobs: - build_test_push: - runs-on: ubuntu-latest - steps: - - name: Set up git repository - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - - - name: Set up QEMU - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3 - - - name: Log in to the GitHub Container Registry - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build and export to Docker (Test Image) - uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5 - with: - context: . - file: .devcontainer/bash/Dockerfile - load: true - tags: ${{ env.IMAGE_NAME }}:latest - - - name: Test - run: docker run --rm ${{ env.IMAGE_NAME }}:latest - - - name: Push image - run: docker push ${{ env.IMAGE_NAME }}:latest diff --git a/.github/workflows/licenses.yaml b/.github/workflows/licenses.yaml new file mode 100644 index 00000000..bdd04b15 --- /dev/null +++ b/.github/workflows/licenses.yaml @@ -0,0 +1,30 @@ +--- +name: go-licenses +on: + pull_request: + types: + - opened + - synchronize +jobs: + licenses: + name: run go-licenses against this project's dependencies + runs-on: ubuntu-latest + steps: + - name: Checkout Git repository + uses: actions/checkout@v4 + - name: Setup Build Environment + uses: actions/setup-go@v4 + with: + go-version: "1.21" + - name: Install go-licenses + run: go install github.com/google/go-licenses@latest + - name: Run go-licenses + run: | + output=$(go-licenses check ./... 2> /dev/null) + if [[ "${output}" == *"ERROR: forbidden license found"* ]]; then + echo "Forbidden licenses found. Please remove them." + exit 1 + else + echo "No forbidden licenses found." + fi + shell: bash diff --git a/.github/workflows/markdownlint.yaml b/.github/workflows/markdownlint.yaml new file mode 100644 index 00000000..27e6bb77 --- /dev/null +++ b/.github/workflows/markdownlint.yaml @@ -0,0 +1,18 @@ +--- +name: markdownlint +on: + pull_request: + types: + - opened + - synchronize +jobs: + markdownlint: + name: run markdownlint against this codebase + runs-on: ubuntu-latest + steps: + - name: Checkout Git repository + uses: actions/checkout@v4 + - name: Run markdownlint + uses: DavidAnson/markdownlint-cli2-action@v13 + with: + globs: '**/*.md' diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 61ade602..b2c17911 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -5,51 +5,14 @@ on: types: - opened - synchronize - # Run once a week (see https://crontab.guru) - schedule: - - cron: "0 0 * * 0" - workflow_dispatch: jobs: pre-commit: name: Update pre-commit hooks and run pre-commit runs-on: ubuntu-latest steps: - - name: Set up git repository - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - - - name: Set up Python - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4 - with: - python-version: "3.x" - - - name: Set up Go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 - with: - go-version: "1.21.0" - - - name: Install go module dependencies - run: | - go install mvdan.cc/sh/v3/cmd/shfmt@latest - go install github.com/magefile/mage@latest - + - name: Checkout Git repository + uses: actions/checkout@v4 - name: Install pre-commit run: pip3 install pre-commit - - - name: Run go mod tidy - necessary to avoid errors with renovatebot PRs - run: | - go mod tidy - pushd magefiles; go mod tidy; popd - - - name: Commit go.mod and go.sum changes to keep pre-commit happy - run: | - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - git add go.mod go.sum magefiles/go.mod magefiles/go.sum - git diff --quiet && git diff --staged --quiet || \ - git commit -m "Update go.mod and go.sum" - - - name: Install pre-commit dependencies - run: mage installDeps - - name: Run pre-commit - run: mage runPreCommit + run: pre-commit run --all-files diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 1bee02b8..a59db595 100755 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -7,27 +7,21 @@ on: - synchronize jobs: tests: - name: Run tests - includes pre-commit hooks and determining code coverage % + name: Run Unit + Integration Tests runs-on: ubuntu-latest steps: - - name: Set up git repository - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - - - name: Set up Go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + - name: Checkout Git repository + uses: actions/checkout@v4 + - name: Setup Build Environment + uses: actions/setup-go@v4 with: - go-version: "1.20" - - - name: Set git config + go-version: "1.21" + - name: Run TTPForge Unit Tests run: | - git config --global user.name "John Doe" - git config --global user.email johndoe@example.com - - - name: Generate the coverage output + go test -v ./... + - name: Build the TTPForge Binary run: | - bash .hooks/run-go-tests.sh coverage - - - name: Send the coverage output - uses: shogo82148/actions-goveralls@7b1bd2871942af030d707d6574e5f684f9891fb2 # v1 - with: - path-to-profile: coverage-all.out + go build -o ttpforge + - name: Run Integration Tests + run: | + ./integration_tests.sh ./ttpforge diff --git a/.gitignore b/.gitignore index 2bcebfe8..9d916eed 100755 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Code coverage output file coverage-all.out +# Python Virtual Environment +venv + # Compiled binary ttpforge ttpforge-windows @@ -8,6 +11,3 @@ dist # vscode debugger __debug_bin - -# Container -.secrets diff --git a/.hooks/generate-docs.sh b/.hooks/generate-docs.sh deleted file mode 100755 index c0ac78c8..00000000 --- a/.hooks/generate-docs.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -# -# This script is a pre-commit hook that checks if the mage command is -# installed and if not, prompts the user to install it. If mage is -# installed, the script navigates to the repository root by calling the -# `repo_root` function and runs the `mage generatepackagedocs` command. -# This command generates documentation for all Go packages in the current -# directory and its subdirectories by traversing the file tree and creating -# a new README.md file in each directory containing a Go package. -# The script also ensures the presence of a specific utility bash file -# (bashutils.sh) and sources it if found. If the command fails, the commit -# is stopped, and an error message is shown. -set -e - -# Define the URL of bashutils.sh -bashutils_url="https://raw.githubusercontent.com/l50/dotfiles/main/bashutils" - -# Define the local path of bashutils.sh -bashutils_path="/tmp/bashutils" - -# Check if bashutils.sh exists locally -if [[ ! -f "${bashutils_path}" ]]; then - # bashutils.sh doesn't exist locally, so download it - curl -s "${bashutils_url}" -o "${bashutils_path}" -fi - -# Source bashutils -# shellcheck source=/dev/null -source "${bashutils_path}" - -repo_root || exit 1 - -# Check if mage is installed -if command -v mage > /dev/null 2>&1; then - echo "mage is installed" -else - echo -e "mage is not installed\n" - echo -e "Please install mage by running the following command:\n" - echo -e "go install github.com/magefile/mage@latest\n" - exit 1 -fi - -# Run the mage generatepackagedocs command -mage generatepackagedocs -# Catch the exit code -exit_status=$? - -# If the exit code is not zero (i.e., the command failed), -# then stop the commit and show an error message -if [ $exit_status -ne 0 ]; then - echo "failed to generate package docs" - exit 1 -fi diff --git a/.hooks/go-critic.sh b/.hooks/go-critic.sh deleted file mode 100755 index 7a744784..00000000 --- a/.hooks/go-critic.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -set -eu -o pipefail - -if ! command -v gocritic &> /dev/null; then - echo "gocritic not installed or available in the PATH" >&2 - echo "please check https://github.com/go-critic/go-critic" >&2 - exit 1 -fi - -subcommand=$1 -shift - -failed=false - -for file in "$@"; do - # redirect stderr so that violations and summaries are properly interleaved. - if ! gocritic "$subcommand" "$file" 2>&1; then - failed=true - fi -done - -if [[ $failed == "true" ]]; then - exit 1 -fi diff --git a/.hooks/go-licenses.sh b/.hooks/go-licenses.sh deleted file mode 100755 index fc82f5e3..00000000 --- a/.hooks/go-licenses.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -# Function to check if go mod vendor should run or not -run_vendor() - { - echo "Running go mod vendor..." - go mod vendor -} - -# Function to check licenses -check_licenses() - { - action=$1 - - go install github.com/google/go-licenses@latest - - # Decide action based on input - if [[ $action == "check_forbidden" ]]; then - echo "Checking for forbidden licenses..." - output=$(go-licenses check ./... 2> /dev/null) - if [[ "${output}" == *"ERROR: forbidden license found"* ]]; then - echo "Forbidden licenses found. Please remove them." - exit 1 - else - echo "No forbidden licenses found." - fi - elif [[ $action == "output_csv" ]]; then - echo "Outputting licenses to csv..." - status=go-licenses csv ./... 2> /dev/null - elif [[ $action == "vendor" ]]; then - echo "Vendoring dependencies..." - run_vendor - fi -} - -# Ensure input is provided -if [[ $# -lt 1 ]]; then - echo "Incorrect number of arguments." - echo "Usage: $0 " - echo "Example: $0 check_forbidden" - exit 1 -fi - -# Run checks -check_licenses "${1}" diff --git a/.hooks/go-vet.sh b/.hooks/go-vet.sh deleted file mode 100755 index e2c62d00..00000000 --- a/.hooks/go-vet.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -set -ex - -pkgs=$(go list ./...) - -for pkg in $pkgs; do - dir="$(basename "$pkg")/" - if [[ "${dir}" != ".hooks/" ]] \ - && [[ "${dir}" != ".github/" ]] \ - && [[ "${dir}" != "bin/" ]] \ - && [[ "${dir}" != "docs/" ]] \ - && [[ "${dir}" != "logging/" ]] \ - && [[ "${dir}" != "magefiles/" ]] \ - && [[ "${dir}" != "modules/" ]] \ - && [[ "${dir}" != "resources/" ]] \ - && [[ "${dir}" != "templates/" ]]; then - go vet "${pkg}" - fi -done diff --git a/.hooks/linters/mdstyle.rb b/.hooks/linters/mdstyle.rb deleted file mode 100755 index 190fe1c8..00000000 --- a/.hooks/linters/mdstyle.rb +++ /dev/null @@ -1,44 +0,0 @@ -################################################################################ -# Style file for markdownlint. -# -# https://github.com/markdownlint/markdownlint/blob/master/docs/configuration.md -# -# This file is referenced by the project `.mdlrc`. -################################################################################ - -#=============================================================================== -# Start with all built-in rules. -# https://github.com/markdownlint/markdownlint/blob/master/docs/RULES.md -all - -#=============================================================================== -# Override default parameters for some built-in rules. -# https://github.com/markdownlint/markdownlint/blob/master/docs/creating_styles.md#parameters - -exclude_tag :line_length -# Allow long lines in code blocks and tables -rule 'MD013', line_length: 120, ignore_code_blocks: true, tables: false - -#=============================================================================== -# Exclude the rules I disagree with. - -# IMHO it's easier to read lists like: -# * outmost indent -# - one indent -# - second indent -# * Another major bullet -exclude_rule 'MD004' # Unordered list style - -exclude_rule 'MD007' # Unordered list indentation - -# Ordered lists are fine. -exclude_rule 'MD029' - -# The first line doesn't always need to be a top level header. -exclude_rule 'MD041' - -# I find it necessary to use '
' to force line breaks. -exclude_rule 'MD033' # Inline HTML - -# Using bare URLs is fine. -exclude_rule 'MD034' diff --git a/.hooks/run-go-tests.sh b/.hooks/run-go-tests.sh deleted file mode 100755 index 8aae83bd..00000000 --- a/.hooks/run-go-tests.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -set -e - -TESTS_TO_RUN=$1 -RETURN_CODE=0 - -if [[ -z "${TESTS_TO_RUN}" ]]; then - echo "No tests input" - echo "Example - Run all tests: bash run-go-tests.sh all" - echo "Example - Run all tests and generate coverage report: bash run-go-tests.sh coverage" - exit 1 -fi - -if [[ "${TESTS_TO_RUN}" == 'coverage' ]]; then - go test -v -race -failfast \ - -tags=integration -coverprofile=coverage-all.out ./... - RETURN_CODE=$? -elif [[ "${TESTS_TO_RUN}" == 'all' ]]; then - go test -v -race -failfast ./... - RETURN_CODE=$? -elif [[ "${TESTS_TO_RUN}" == 'short' ]] \ - && [[ "${GITHUB_ACTIONS}" != "true" ]]; then - go test -v -short -failfast -race ./... - RETURN_CODE=$? -else - if [[ "${GITHUB_ACTIONS}" != 'true' ]]; then - go test -v -race -failfast "./.../${TESTS_TO_RUN}" - RETURN_CODE=$? - fi -fi - -if [[ "${RETURN_CODE}" -ne 0 ]]; then - echo "unit tests failed" - exit 1 -fi diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 00000000..20de1609 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1 @@ +MD034: false diff --git a/.mdlrc b/.mdlrc deleted file mode 100755 index 984d7633..00000000 --- a/.mdlrc +++ /dev/null @@ -1 +0,0 @@ -style '.hooks/linters/mdstyle.rb' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6df51cc8..e115ad79 100755 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,31 +12,6 @@ repos: - id: detect-private-key - id: check-shebang-scripts-are-executable - - repo: https://github.com/adrienverge/yamllint.git - rev: v1.32.0 - hooks: - - id: yamllint - entry: yamllint --strict -c .hooks/linters/yamllint.yaml - - - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.3 - hooks: - - id: prettier - files: \.(json)$ - exclude: docs/container.md - - - repo: https://github.com/jumanjihouse/pre-commit-hooks - rev: 3.0.0 - hooks: - - id: script-must-have-extension - name: Ensure shell scripts end with .sh - types: [shell] - exclude: .bats - - id: shellcheck - - id: shfmt - # Configuration in .mdlrc and .hooks/linters/mdstyle.rb - - id: markdownlint - - repo: https://github.com/codespell-project/codespell rev: v2.2.6 hooks: @@ -45,19 +20,6 @@ repos: codespell -q 3 -f -S ".git,.github,README.md,docs/*,go.*,magefiles/go.*,*test.go" - - repo: https://github.com/dnephin/pre-commit-golang - rev: v0.5.1 - hooks: - - id: go-fmt - - id: go-lint - - id: go-imports - - id: go-cyclo - args: [-over=15] - - id: golangci-lint - args: [--timeout=5m] - - id: go-build - - id: go-mod-tidy - - repo: local hooks: - id: go-no-replacement @@ -71,20 +33,3 @@ repos: language: script entry: .hooks/go-copyright.sh files: '\.go$' - - - id: go-unit-tests - name: Go unit tests - language: script - entry: .hooks/run-go-tests.sh coverage - files: '\.go$' - - - id: go-vet - name: Run go vet - language: script - entry: .hooks/go-vet.sh - files: '\.go$' - - - id: go-licenses - name: Run go-licenses - language: script - entry: .hooks/go-licenses.sh check_forbidden diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index 1f103a9b..00000000 --- a/.tool-versions +++ /dev/null @@ -1,3 +0,0 @@ -ruby 3.2.2 -golang 1.21.3 -python 3.12.0 diff --git a/README.md b/README.md index 7495cb5f..51934a6a 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,6 @@ to learn more! - [Documentation](docs/foundations/README.md) - [Getting Started - Developer](docs/dev/README.md) - [Go Package Documentation](https://pkg.go.dev/github.com/facebookincubator/ttpforge@main) -- [Using the TTPForge Dev Container](docs/container.md) -- [Code Standards](docs/code-standards.md) - [Creating a new release](docs/release.md) --- diff --git a/docs/code-standards.md b/docs/code-standards.md deleted file mode 100755 index 95ddfbab..00000000 --- a/docs/code-standards.md +++ /dev/null @@ -1,315 +0,0 @@ -# Code Standards - ---- - -## Table of Contents - -- [Testing](#testing) - - [General Testing Guidelines](#general-testing-guidelines) - - [Unit Testing](#unit-testing) - - [Integration Testing](#integration-testing) - - [Example Tests](#example-tests) - - [Test Architecture](#test-architecture) - - [Test Maintenance](#test-maintenance) -- [Documentation](#documentation) - - [Documenting Exported Functions](#documenting-exported-functions) - - [Documenting Exported Structs](#documenting-exported-structs) - - [Documenting Exported Interfaces](#documenting-exported-interfaces) - ---- - -## Testing - -We employ [table-driven tests](https://semaphoreci.com/blog/table-driven-unit-tests-go) for the TTPForge. -This format facilitates testing a function with a variety of cases. - -```go -package some_test - -import ( - "testing" -) - -func TestSomething(t *testing.T) { - tests := []struct{ - name string - // input and output go here - }{ - { - name: "something" - // input and output go here - }, - { - name: "another thing" - // input and output go here - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - // call function or method being tested - // check outcome - }) - } -} -``` - -Numerous examples of comprehensive tests can be found throughout the TTPForge repo. - -### General Testing Guidelines - -In a nutshell, TTPForge adheres to the following testing standards: - -1. All exported functions should be paired with a corresponding test. - -1. Any new functionality must be accompanied by integration tests to ensure - compatibility with existing logic and future code. - -1. If tests interact with the filesystem, they should execute within a temporary - directory specific to that test. Refer to `pkg/file/file_test.go` for examples. - -1. Test packages should be separate from the package under test to prevent - test code from being included in the compiled binary. E.g., tests for - `pkg/foo` should be `in pkg/foo_test`. - -### Unit Testing - -When crafting unit tests for the TTPForge, please heed the following criteria: - -1. **Functionality:** Unit tests should be focused on a single function or method, isolating - it from dependencies wherever possible. - -1. **Inputs and Outputs:** Specify the function's required input types and - expected output types. - -1. **Edge Cases:** Provide handling strategies for edge cases, including null - inputs, empty strings, extreme values, etc. - -1. **Mocking:** Mock dependencies if the function under test relies on - other services or functions. - -1. **Error Handling:** Elucidate strategies for testing error handling within the function. - -### Integration Testing - -When formulating integration tests for TTPForge, keep the following points in mind: - -1. **Components:** Identify the components being tested together. This could be a combination - of functions, methods, or even modules or services. - -1. **Data Flow:** Describe how data flows between the components and what the expected outcomes are. - -1. **Setup and Tear Down:** Provide instructions for the setup and tear down of the test environment. - -1. **Mocking:** Explain when and how to mock dependencies. Unlike unit tests, integration tests - may demand more actual services and fewer mocks. - -1. **Error Handling:** Explain how to test for errors at the integration level. - This might include testing how one component handles another component's failure. - -### Example Tests - -When creating your tests, it's beneficial to provide examples of how to utilize your code. -This can be achieved by constructing a test prefixed with "Example". - -In the following example, we demonstrate how to use a function called `FixCodeBlocks`: - -````go -package docs_test - -import ( - "fmt" - "log" - "os" - "strings" - - "github.com/example/docs" - "github.com/example/fileutils" -) - -func ExampleFixCodeBlocks() { - input := `Driver represents an interface to Google Chrome using go. - -It contains a context.Context associated with this Driver and -Options for the execution of Google Chrome. - -` + "```go" + ` -browser, err := cdpchrome.Init(true, true) - -if err != nil { - fmt.Printf("failed to initialize a chrome browser: %v", err) - return -} -` + "```" - language := "go" - - // Create a temporary file - tmpfile, err := os.CreateTemp("", "example.*.md") - if err != nil { - fmt.Printf("failed to create temp file: %v", err) - return - } - - defer os.Remove(tmpfile.Name()) // clean up - - // Write the input to the temp file - if _, err := tmpfile.Write([]byte(input)); err != nil { - fmt.Printf("failed to write to temp file: %v", err) - return - } - - if err := tmpfile.Close(); err != nil { - fmt.Printf("failed to close temp file: %v", err) - return - } - - // Run the function - file := fileutils.RealFile(tmpfile.Name()) - if err := docs.FixCodeBlocks(file, language); err != nil { - fmt.Printf("failed to fix code blocks: %v", err) - return - } - - // Read the modified content - content, err := os.ReadFile(tmpfile.Name()) - if err != nil { - fmt.Printf("failed to read file: %v", err) - return - } - - // Print the result - fmt.Println(strings.TrimSpace(string(content))) - // Output: - // Driver represents an interface to Google Chrome using go. - // - // It contains a context.Context associated with this Driver and - // Options for the execution of Google Chrome. - // - // ```go - // browser, err := cdpchrome.Init(true, true) - // - // if err != nil { - // log.Fatalf("failed to initialize a chrome browser: %v", err) - // } - // ``` -} -```` - -Note: The use of the "Example" prefix in these tests indicates that their -primary purpose is to serve as executable documentation for your code. They -are designed to provide developers with clear, practical examples of how to -use your functions. - -When these Example tests are run, the actual output from the function is -compared with the expected output, as specified in the `// Output:` -comment. - -**Resource:** - -### Test Architecture - -Tests should reside in a separate package from the one containing the code -under test. We advocate for this convention due to several reasons: - -**Encapsulation and separation of concerns:** - -- Keeping test code distinct from production code simplifies comprehension - and maintenance. - -**Testing exported functionality:** - -- External test packages promote testing of only the exported functionality, - mirroring the package consumers' perspective. This emphasizes the public - API's behavior. - -**Avoiding test-only dependencies:** - -- External test packages eliminate test-only dependencies from the compiled - binary, reducing its size and warding off accidental usage in production code. - -**Resources:** - -- -- - -### Test Maintenance - -Test maintenance is pivotal. If library code is updated in a way that modifies -functionality (add, update, remove, etc.), the corresponding tests should -also be updated. - -For instance, if an exported function is updated to support -`github.com/spf13/afero`, its associated tests should also be updated to -ensure they still function correctly. - ---- - -## Documentation - -Automated package documentation is an essential part of our work. It benefits -us in terms of reducing manual effort and standardizing documentation. That's -why we utilize the following templates. They're designed to support autogen -package docs, enabling us to parse this format and create READMEs -for each package automatically. - -### Documenting Exported Functions - -```go -// FindExportedFunctionsInPackage locates all exported functions in a specific Go -// package by parsing all non-test Go files in the package directory. It returns -// a slice of FuncInfo structs. Each struct contains the file path and the name of an -// exported function. If the package contains no exported functions, an -// error is returned. -// -// **Parameters:** -// -// pkgPath: A string representing the path to the directory containing the package -// to search for exported functions. -// -// **Returns:** -// -// []FuncInfo: A slice of FuncInfo structs, each containing the file path and the -// name of an exported function found in the package. -// error: An error if no exported functions are found. -``` - -### Documenting Exported Structs - -```go -// LogInfo encapsulates parameters that aid in managing logging throughout -// a program. -// -// **Attributes:** -// -// Dir: A string denoting the directory where the log file is located. -// File: An afero.File object that represents the log file. -// FileName: A string denoting the log file's name. -// Path: A string indicating the full path to the log file. -type LogInfo struct { - Dir string - File afero.File - FileName string - Path string -} -``` - -### Documenting Exported Interfaces - -```go -// File is an interface representing a system file. -// -// **Methods:** -// -// Open: Opens the file, returns a io.ReadCloser and an error. -// Write: Writes contents to the file, returns an error. -// RemoveAll: Removes a file or directory at the specified path, returns an error. -// Stat: Retrieves the FileInfo for the specified file or directory, returns an os.FileInfo and an error. -// Remove: Removes the specified file or directory, returns an error. -type File interface { - Open() (io.ReadCloser, error) - Write(contents []byte, perm os.FileMode) error - RemoveAll() error - Stat() (os.FileInfo, error) - Remove() error -} -``` diff --git a/docs/container.md b/docs/container.md deleted file mode 100755 index f46dda7b..00000000 --- a/docs/container.md +++ /dev/null @@ -1,108 +0,0 @@ -# TTPForge Dev Container - -We provide a development container hosted on -GitHub Container Registry (ghcr) to serve as a -complete development environment. - ---- - -## Table of Contents - -- [Prerequisites](#prerequisites) -- [Using in VSCode](#using-in-vscode) -- [Using on the Command Line Interface (CLI)](#using-on-the-command-line-interface-cli) -- [Local Build Process](#local-build-process) -- [Run container action locally](#run-container-action-locally) - ---- - -## Prerequisites - -- [Create a classic GitHub Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token) - (fine-grained isn't supported yet) with the following permissions - taken from [here](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry): - - - `read:packages` - - `write:packages` - - `delete:packages` - -## Using in VSCode - -1. If you haven't already, install the - [Remote - Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) - in Visual Studio Code. - -1. Open the command palette in Visual Studio Code by - pressing Ctrl + Shift + P (or Cmd + Shift + P on macOS) - and run the `Remote-Containers: Reopen in Container` - command. Visual Studio Code will build the Docker - container using the provided Dockerfile and open - the project inside the container. - - You can now work on your project within the container, - and Visual Studio Code will utilize the Go, Python, - and other tools installed in the container for tasks - such as running, debugging, and linting. - -To return to working on your project locally, open the command palette -and run the `Remote-Containers: Reopen Locally` command. - ---- - -## Using on the Command Line Interface (CLI) - -1. Pull the latest image from ghcr: - - ```bash - docker pull ghcr.io/facebookincubator/ttpforge:latest - ``` - -1. Run container and mount local project directory: - - ```bash - docker run -it --rm \ - -v "$(pwd)":/home/ttpforge/go/src/github.com/facebookincubator/ttpforge \ - ghcr.io/facebookincubator/ttpforge:latest - ``` - ---- - -## Local Build Process - -If, for any reason, you need to build the container image -locally, follow the steps below. - -Run the following commands to build the image locally: - -```bash -docker build \ - -t ghcr.io/facebookincubator/ttpforge \ - -f .devcontainer/bash/Dockerfile . -``` - ---- - -## Run container action locally - -1. Create a file called `.secrets` with the following: - - ```bash - export BOT_TOKEN=YOUR_PAT_GOES_HERE - export GITHUB_USERNAME=YOUR_GITHUB_USERNAME_GOES_HERE - ``` - -1. Install [Act](https://github.com/nektos/act) - -1. Run one of the actions: - - ```bash - # Run the container build, push, and test action - - act -j "test_pushed_images" \ - --secret-file .secrets - - # Run the pre-commit action - act -j "pre-commit" \ - --secret-file .secrets \ - --container-architecture linux/amd64 - ``` diff --git a/docs/dev/README.md b/docs/dev/README.md index aefaa9bf..abcd7e92 100755 --- a/docs/dev/README.md +++ b/docs/dev/README.md @@ -8,42 +8,14 @@ and follow along. ## Install Golang -We recommend building and testing TTPForge using Golang version `1.21.1`, -although older versions are also supported for compatibility reasons. -You can install this Golang version from the official Golang [website](https://go.dev/doc/install). -Alternatively, you can use `asdf` to manage your tool versions as described below - -this is highly recommended if you will be juggling multiple tool versions across -various projects. +TTPForge is build and tested in [Github Actions](https://github.com/features/actions) +using the Golang version from this configuration file: -## Using asdf to manage tool versions +https://github.com/facebookincubator/TTPForge/blob/main/.github/workflows/tests.yaml -The tool versions recommended for use with TTPForge are specified -in the `.tool-versions` file found in the repository root. - -Setup [asdf](https://asdf-vm.com/) for usage with TTPForge by running -the following commands: - -```bash -git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1 -# we recommend adding the below line to your ~/.bashrc, ~/.zshrc etc -. "$HOME/.asdf/asdf.sh" -asdf plugin add golang https://github.com/asdf-community/asdf-golang.git -``` - -You can then install the correct Golang version for this project by -running the following command **from inside the repo root directory**: - -```bash -asdf install golang -``` - -You now may need to run `rehash` (zsh) or `hash -r` (bash) - after that, you -can verify that your asdf version of Go is being used: - -```bash -which go -go version -``` +it is recommended to use the same version when developing locally. +You can install this Golang version from the official +Golang [website](https://go.dev/doc/install). ## Testing and Building TTPForge @@ -60,72 +32,39 @@ and subsequently build your own copy of the TTPForge binary: go build -o ttpforge ``` -## Running Pre-Commit Locally (Optional) - -This step is not required to build and run your own copy of TTPForge, -but may help you iterate more quickly when responding to Pull Request -checks that our repository automatically runs to test/lint new code. -Otherwise, you'll need to wait for Github Actions to vet your PR. - -### Install pre-commit Dependencies - -- [Install pre-commit](https://pre-commit.com/): - - ```bash - python3 -m pip install --upgrade pip - python3 -m pip install pre-commit - ``` - -- [Install Mage](https://magefile.org/): - - ```bash - go install github.com/magefile/mage@latest - ``` - -- [Install Docker](https://docs.docker.com/get-docker/) - ---- - -### Configure environment - -1. Install additional dependencies: - - ```bash - mage installDeps - ``` - -1. Update and run pre-commit hooks locally: - - ```bash - mage runPreCommit - ``` - -1. Compile ttpforge: - - ```bash - go build -o ttpforge - ``` - -### Uninstall pre-commit - -If you want to hold off on pre-commit until your code is at a certain point, -you can disable it locally: +Finally, you can run our integration tests against your binary +with the command: ```bash -pre-commit uninstall +./integration-tests.sh ./ttpforge ``` -Once you want to get feedback from pre-commit, reinstall it with: +## Github Actions CI/CD + +When you submit your change as a pull request to our repository, +a variety of linting and testing workflows will be triggered. +If you wish to run any of these workflows locally +to fix a failure, you can do so with the [act](https://github.com/nektos/act) +tool. For example, you can run the markdownlint action as follows: ```bash -pre-commit install +act -W .github/workflows/markdownlint ``` -### Test all mage functions +## Running Pre-Commit Locally -Run the following command to execute all mage functions -and ensure they are working as expected: +Several of the linters in this project may be used as pre-commit hooks +if desired - you can install and setup pre-commit according to +the [official instructions](https://pre-commit.com/). + +For quick ad hoc runs, you may with to run pre-commit in a virtual environment: ```bash -bash magefiles/scripts/magefile_test.sh +python3 -m venv venv +. venv/bin/activate +pip3 install pre-commit +pre-commit run --all-files ``` + +You can also run pre-commit locally using `act`, as described +in the previous section. diff --git a/docs/dev/update-go.md b/docs/dev/update-go.md deleted file mode 100755 index 752255a8..00000000 --- a/docs/dev/update-go.md +++ /dev/null @@ -1,13 +0,0 @@ -# Updating the Golang Version for TTPForge - ---- - -If you want to change the supported/recommended Golang version(s) for TTPForge, -you must do all of the following: - -- Update minimum required Golang version specified in `go.mod` -- Make a corresponding update to `magefiles/go.mod` -- Update the version referenced in `.devcontainer/bash/Dockerfile` (example: - `FROM golang:1.21.1-alpine`) -- Update recommended Golang version for asdf in `.tool-versions` -- Update the [developer documentation](README.md) to indicate the new version(s) diff --git a/integration_tests.sh b/integration_tests.sh new file mode 100644 index 00000000..984a4802 --- /dev/null +++ b/integration_tests.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# This runs the commands from the README.md +# Will shortly add `ttpforge test` invocation +# to run all the examples +set -ex + +# ensure we have a valid ttpforge binary path +ttpforge_binary="$1" +if [ ! -e "${ttpforge_binary}" ] +then + echo "Provided TTPForge Binary Path Does Not Exist: ${ttpforge_binary}" + exit 1 +fi +ttpforge_binary=$(realpath "${ttpforge_binary}") + +# run all commands from the README.md +"${ttpforge_binary}" init +"${ttpforge_binary}" list repos +"${ttpforge_binary}" list ttps +"${ttpforge_binary}" show ttp examples//args/basic.yaml +"${ttpforge_binary}" run examples//args/basic.yaml \ + --arg str_to_print=hello \ + --arg run_second_step=true + +# run all the TTP test cases +./run_all_ttp_tests.sh "${ttpforge_binary}" diff --git a/magefiles/README.md b/magefiles/README.md deleted file mode 100644 index 74482a6e..00000000 --- a/magefiles/README.md +++ /dev/null @@ -1,160 +0,0 @@ -# TTPForge/magefiles - -`magefiles` provides utilities that would normally be managed -and executed with a `Makefile`. Instead of being written in the make language, -magefiles are crafted in Go and leverage the [Mage](https://magefile.org/) library. - ---- - -## Table of contents - -- [Functions](#functions) -- [Contributing](#contributing) -- [License](#license) - ---- - -## Functions - -### Compile() - -```go -Compile() error -``` - -Compile compiles the Go project using goreleaser. The behavior is -controlled by the 'release' environment variable. If the GOOS and -GOARCH environment variables are not set, the function defaults -to the current system's OS and architecture. - -**Environment Variables:** - -release: Determines the compilation mode. - -If "true", compiles all supported releases for TTPForge. -If "false", compiles only the binary for the specified OS -and architecture (based on GOOS and GOARCH) or the current -system's default if the vars aren't set. - -GOOS: Target operating system for compilation. Defaults to the -current system's OS if not set. - -GOARCH: Target architecture for compilation. Defaults to the -current system's architecture if not set. - -Example usage: - -```go -release=true mage compile # Compiles all supported releases for TTPForge -GOOS=darwin GOARCH=arm64 mage compile false # Compiles the binary for darwin/arm64 -GOOS=linux GOARCH=amd64 mage compile false # Compiles the binary for linux/amd64 -``` - -**Returns:** - -error: An error if any issue occurs during compilation. - ---- - -### InstallDeps() - -```go -InstallDeps() error -``` - -InstallDeps installs the Go dependencies necessary for developing -on the project. - -Example usage: - -```go -mage installdeps -``` - -**Returns:** - -error: An error if any issue occurs while trying to -install the dependencies. - ---- - -### RunIntegrationTests() - -```go -RunIntegrationTests() error -``` - -RunIntegrationTests executes all integration tests by extracting the commands -described in README files of TTP examples and then executing them. - -Example usage: - -```go -mage runintegrationtests -``` - -**Returns:** - -error: An error if any issue occurs while running the tests. - ---- - -### RunPreCommit() - -```go -RunPreCommit() error -``` - -RunPreCommit updates, clears, and executes all pre-commit hooks -locally. The function follows a three-step process: - -First, it updates the pre-commit hooks. -Next, it clears the pre-commit cache to ensure a clean environment. -Lastly, it executes all pre-commit hooks locally. - -Example usage: - -```go -mage runprecommit -``` - -**Returns:** - -error: An error if any issue occurs at any of the three stages -of the process. - ---- - -### RunTests() - -```go -RunTests() error -``` - -RunTests executes all unit tests. - -Example usage: - -```go -mage runtests -``` - -**Returns:** - -error: An error if any issue occurs while running the tests. - ---- - -## Contributing - -Pull requests are welcome. For major changes, -please open an issue first to discuss what -you would like to change. - ---- - -## License - -This project is licensed under the MIT -License - see the [LICENSE](https://github.com/facebookincubator/TTPForge/blob/main/LICENSE) -file for details. diff --git a/magefiles/go.mod b/magefiles/go.mod deleted file mode 100755 index 6f846341..00000000 --- a/magefiles/go.mod +++ /dev/null @@ -1,49 +0,0 @@ -module magefile - -go 1.21 - -toolchain go1.21.2 - -require ( - github.com/fatih/color v1.15.0 - github.com/l50/goutils/v2 v2.1.3 - github.com/magefile/mage v1.15.0 - github.com/spf13/afero v1.10.0 -) - -require ( - dario.cat/mergo v1.0.0 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect - github.com/acomagu/bufpipe v1.0.4 // indirect - github.com/bitfield/script v0.22.0 // indirect - github.com/cloudflare/circl v1.3.3 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/emirpasic/gods v1.18.1 // indirect - github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-git/go-git/v5 v5.9.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/itchyny/gojq v0.12.13 // indirect - github.com/itchyny/timefmt-go v0.1.5 // indirect - github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/otiai10/copy v1.14.0 // indirect - github.com/pjbgf/sha1cd v0.3.0 // indirect - github.com/sergi/go-diff v1.3.1 // indirect - github.com/skeema/knownhosts v1.2.0 // indirect - github.com/xanzy/ssh-agent v0.3.3 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect - gopkg.in/warnings.v0 v0.1.2 // indirect - mvdan.cc/sh/v3 v3.6.0 // indirect -) - -replace github.com/spf13/afero => github.com/spf13/afero v1.2.1 diff --git a/magefiles/go.sum b/magefiles/go.sum deleted file mode 100755 index 01c11cfd..00000000 --- a/magefiles/go.sum +++ /dev/null @@ -1,193 +0,0 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= -github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/bitfield/script v0.22.0 h1:LA7QHuEsXMPD52YLtxWrlqCCy+9FOpzNYfsRHC5Gsrc= -github.com/bitfield/script v0.22.0/go.mod h1:ms4w+9B8f2/W0mbsgWDVTtl7K94bYuZc3AunnJC4Ebs= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= -github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= -github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= -github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY= -github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= -github.com/itchyny/gojq v0.12.12/go.mod h1:j+3sVkjxwd7A7Z5jrbKibgOLn0ZfLWkV+Awxr/pyzJE= -github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU= -github.com/itchyny/gojq v0.12.13/go.mod h1:JzwzAqenfhrPUuwbmEz3nu3JQmFLlQTQMUcOdnu/Sf4= -github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= -github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/l50/goutils/v2 v2.1.3 h1:/exzYFw89LfxlLz8ArErirSKCgRDZkHRo4wBBnlpS5M= -github.com/l50/goutils/v2 v2.1.3/go.mod h1:TRwb4J9shutlQb/XqadyaqQ2mSBVoxq+AfOHTSzDmhY= -github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= -github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= -github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= -github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= -github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= -github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= -github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= -github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= -github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= -github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M= -github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= -github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -mvdan.cc/editorconfig v0.2.0/go.mod h1:lvnnD3BNdBYkhq+B4uBuFFKatfp02eB6HixDvEz91C0= -mvdan.cc/sh/v3 v3.6.0 h1:gtva4EXJ0dFNvl5bHjcUEvws+KRcDslT8VKheTYkbGU= -mvdan.cc/sh/v3 v3.6.0/go.mod h1:U4mhtBLZ32iWhif5/lD+ygy1zrgaQhUu+XFy7C8+TTA= diff --git a/magefiles/magefile.go b/magefiles/magefile.go deleted file mode 100644 index b60488a4..00000000 --- a/magefiles/magefile.go +++ /dev/null @@ -1,125 +0,0 @@ -//go:build mage -// +build mage - -/* -Copyright © 2023-present, Meta Platforms, Inc. and affiliates -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -package main - -import ( - "fmt" - "os" - - "github.com/fatih/color" - "github.com/l50/goutils/v2/dev/lint" - mageutils "github.com/l50/goutils/v2/dev/mage" - "github.com/l50/goutils/v2/sys" -) - -func init() { - os.Setenv("GO111MODULE", "on") -} - -// InstallDeps installs the Go dependencies necessary for developing -// on the project. -// -// Example usage: -// -// ```go -// mage installdeps -// ``` -// -// **Returns:** -// -// error: An error if any issue occurs while trying to -// install the dependencies. -func InstallDeps() error { - fmt.Println(color.YellowString("Running go mod tidy in magefiles.")) - cwd := sys.Gwd() - if err := sys.Cd("magefiles"); err != nil { - return fmt.Errorf("failed to cd into magefiles directory: %v", err) - } - - if err := mageutils.Tidy(); err != nil { - return fmt.Errorf("failed to install dependencies: %v", err) - } - - if err := sys.Cd(cwd); err != nil { - return fmt.Errorf("failed to cd back into repo root: %v", err) - } - - fmt.Println(color.YellowString("Running go mod tidy.")) - if err := mageutils.Tidy(); err != nil { - return fmt.Errorf("failed to install dependencies: %v", err) - } - - fmt.Println(color.YellowString("Installing go dependencies for pre-commit hooks.")) - if err := lint.InstallGoPCDeps(); err != nil { - return fmt.Errorf("failed to install pre-commit dependencies: %v", err) - } - - fmt.Println(color.YellowString("Installing go dependencies required by the vscode-go extension")) - if err := mageutils.InstallVSCodeModules(); err != nil { - return fmt.Errorf("failed to install vscode-go modules: %v", err) - } - - return nil -} - -// RunPreCommit updates, clears, and executes all pre-commit hooks -// locally. The function follows a three-step process: -// -// First, it updates the pre-commit hooks. -// Next, it clears the pre-commit cache to ensure a clean environment. -// Lastly, it executes all pre-commit hooks locally. -// -// Example usage: -// -// ```go -// mage runprecommit -// ``` -// -// **Returns:** -// -// error: An error if any issue occurs at any of the three stages -// of the process. -func RunPreCommit() error { - if !sys.CmdExists("pre-commit") { - return fmt.Errorf("pre-commit is not installed, please follow the " + - "instructions in the dev doc: " + - "https://github.com/facebookincubator/TTPForge/tree/main/docs/dev") - } - - fmt.Println(color.YellowString("Updating pre-commit hooks.")) - if err := lint.UpdatePCHooks(); err != nil { - return err - } - - fmt.Println(color.YellowString("Clearing the pre-commit cache to ensure we have a fresh start.")) - if err := lint.ClearPCCache(); err != nil { - return err - } - - fmt.Println(color.YellowString("Running all pre-commit hooks locally.")) - if err := lint.RunPCHooks(); err != nil { - return err - } - - return nil -} diff --git a/magefiles/scripts/magefile_test.sh b/magefiles/scripts/magefile_test.sh deleted file mode 100755 index ca93eacf..00000000 --- a/magefiles/scripts/magefile_test.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -set -e # Stop on any error - -echo "Starting the test of magefile commands..." - -# Compile for all supported OS and architectures -echo "Testing 'Compile' for all supported OS and architectures..." -release=true mage Compile - -# Compile for specific OS and architectures -echo "Testing 'Compile' for macOS on arm64..." -GOOS=darwin GOARCH=arm64 release=false mage compile - -echo "Testing 'Compile' for Linux on amd64..." -GOOS=linux GOARCH=amd64 release=false mage compile - -echo "Testing 'Compile' for Windows on amd64..." -GOOS=windows GOARCH=amd64 release=false mage compile - -# Install Dependencies -echo "Testing 'InstallDeps'..." -mage InstallDeps - -# Run PreCommit -echo "Testing 'RunPreCommit'..." -mage RunPreCommit - -# Run Tests -echo "Testing 'RunTests'..." -mage RunTests - -# Run Integration Tests -echo "Testing 'RunIntegrationTests'..." -mage RunIntegrationTests - -echo "All magefile commands executed successfully!" diff --git a/magefiles/testing.go b/magefiles/testing.go deleted file mode 100644 index dc7c0d89..00000000 --- a/magefiles/testing.go +++ /dev/null @@ -1,426 +0,0 @@ -//go:build mage -// +build mage - -/* -Copyright © 2023-present, Meta Platforms, Inc. and affiliates -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -package main - -import ( - "bufio" - "fmt" - "io" - "os" - "path/filepath" - "runtime" - "strings" - - "github.com/l50/goutils/v2/git" - "github.com/l50/goutils/v2/sys" - - // mage utility functions - "github.com/magefile/mage/mg" - "github.com/magefile/mage/sh" -) - -type compileParams struct { - GOOS string - GOARCH string -} - -func (p *compileParams) populateFromEnv() { - if p.GOOS == "" { - p.GOOS = os.Getenv("GOOS") - if p.GOOS == "" { - p.GOOS = runtime.GOOS - } - } - - if p.GOARCH == "" { - p.GOARCH = os.Getenv("GOARCH") - if p.GOARCH == "" { - p.GOARCH = runtime.GOARCH - } - } -} - -// Compile compiles the Go project using goreleaser. The behavior is -// controlled by the 'release' environment variable. If the GOOS and -// GOARCH environment variables are not set, the function defaults -// to the current system's OS and architecture. -// -// **Environment Variables:** -// -// release: Determines the compilation mode. -// -// If "true", compiles all supported releases for TTPForge. -// If "false", compiles only the binary for the specified OS -// and architecture (based on GOOS and GOARCH) or the current -// system's default if the vars aren't set. -// -// GOOS: Target operating system for compilation. Defaults to the -// current system's OS if not set. -// -// GOARCH: Target architecture for compilation. Defaults to the -// current system's architecture if not set. -// -// Example usage: -// -// ```go -// release=true mage compile # Compiles all supported releases for TTPForge -// GOOS=darwin GOARCH=arm64 mage compile false # Compiles the binary for darwin/arm64 -// GOOS=linux GOARCH=amd64 mage compile false # Compiles the binary for linux/amd64 -// ``` -// -// **Returns:** -// -// error: An error if any issue occurs during compilation. -func Compile() error { - // Check for the presence of the 'release' environment variable - release, ok := os.LookupEnv("release") - if !ok { - return fmt.Errorf("'release' environment variable not set. It should be 'true' or 'false'. Example: release=true mage Compile") - } - - isRelease := false - if release == "true" { - isRelease = true - } else if release != "false" { - return fmt.Errorf("invalid value for 'release' environment variable. It should be 'true' or 'false'") - } - - if !sys.CmdExists("goreleaser") { - return fmt.Errorf("goreleaser is not installed, please run mage installdeps") - } - - cwd, err := changeToRepoRoot() - if err != nil { - return err - } - defer os.Chdir(cwd) - - doCompile := func(release bool) error { - var p compileParams - p.populateFromEnv() // Populate the GOOS and GOARCH parameters - - var args []string - - if release { - fmt.Println("Compiling all supported releases for TTPForge with goreleaser") - args = []string{"release", "--snapshot", "--clean", "--skip", "validate"} - } else { - fmt.Printf("Compiling the TTPForge binary for %s/%s, please wait.\n", p.GOOS, p.GOARCH) - args = []string{"build", "--snapshot", "--clean", "--skip", "validate", "--single-target"} - } - - if err := sh.RunV("goreleaser", args...); err != nil { - return fmt.Errorf("goreleaser failed to execute: %v", err) - } - return nil - } - - return doCompile(isRelease) -} - -// RunTests executes all unit tests. -// -// Example usage: -// -// ```go -// mage runtests -// ``` -// -// **Returns:** -// -// error: An error if any issue occurs while running the tests. -func RunTests() error { - fmt.Println("Running unit tests.") - if _, err := sys.RunCommand(filepath.Join(".hooks", "run-go-tests.sh"), "all"); err != nil { - return fmt.Errorf("failed to run unit tests: %v", err) - } - - fmt.Println("Running integration tests.") - if err := RunIntegrationTests(); err != nil { - return fmt.Errorf("failed to run integration tests: %v", err) - } - - return nil -} - -// RunIntegrationTests executes all integration tests by extracting the commands -// described in README files of TTP examples and then executing them. -// -// Example usage: -// -// ```go -// mage runintegrationtests -// ``` -// -// **Returns:** -// -// error: An error if any issue occurs while running the tests. -func RunIntegrationTests() error { - // Call Compile to generate the binary. - mg.Deps(func() error { - os.Setenv("release", "false") - return Compile() - }) - - home, err := sys.GetHomeDir() - if err != nil { - return err - } - - originalPath := os.Getenv("PATH") - - // Change to repo root and defer returning to the original directory. - cwd, err := changeToRepoRoot() - if err != nil { - return err - } - defer os.Chdir(cwd) - - binaryDirName, err := getBinaryDirName() - if err != nil { - return err - } - binDirectory := filepath.Join("dist", binaryDirName) - // Clean up the dist directory built by goreleaser. - defer os.RemoveAll(filepath.Dir(binDirectory)) - - // Get the absolute path to the binary. - repoRoot, err := git.RepoRoot() - if err != nil { - return fmt.Errorf("failed to get repo root: %v", err) - } - absoluteBinPath := filepath.Join(repoRoot, binDirectory) - - // Ensure the binary is in the expected location. - binaryPath := filepath.Join(absoluteBinPath, "ttpforge") - if _, err := os.Stat(binaryPath); os.IsNotExist(err) { - return fmt.Errorf("binary not found in expected location: %s", binaryPath) - } - - if err := os.Chmod(binaryPath, 0755); err != nil { - return fmt.Errorf("failed to set executable permissions on ttpforge binary: %v", err) - } - - // Adjust the PATH to prioritize the freshly built binary. - newPath := absoluteBinPath + string(os.PathListSeparator) + originalPath - os.Setenv("PATH", newPath) - - armoryTTPs := filepath.Join(home, ".ttpforge", "repos", "forgearmory", "ttps") - - // Parse README files to extract and run example commands, ensuring the - // validity of our examples. - return findReadmeFiles(armoryTTPs) -} - -func changeToRepoRoot() (originalCwd string, err error) { - repoRoot, err := git.RepoRoot() - if err != nil { - return "", fmt.Errorf("failed to get repo root: %v", err) - } - - cwd, err := os.Getwd() - if err != nil { - return "", fmt.Errorf("failed to get current working directory: %v", err) - } - - if cwd != repoRoot { - if err := os.Chdir(repoRoot); err != nil { - return "", fmt.Errorf("failed to change directory to repo root: %v", err) - } - } - - return cwd, nil -} - -func getBinaryDirName() (string, error) { - goos := os.Getenv("GOOS") - if goos == "" { - goos = runtime.GOOS - } - goarch := os.Getenv("GOARCH") - if goarch == "" { - goarch = runtime.GOARCH - } - baseBinaryDir := fmt.Sprintf("ttpforge_%s_%s", goos, goarch) - - dirs, err := os.ReadDir("dist") - if err != nil { - return "", err - } - - for _, dir := range dirs { - if strings.HasPrefix(dir.Name(), baseBinaryDir) { - return dir.Name(), nil - } - } - - return "", fmt.Errorf("binary directory matching pattern %s not found", baseBinaryDir) -} - -// processLines parses an io.Reader, identifying and marking code blocks -// found in a TTP README. -func processLines(r io.Reader, language string) ([]string, error) { - scanner := bufio.NewScanner(r) - var lines, codeBlockLines []string - var inCodeBlock bool - - for scanner.Scan() { - line := scanner.Text() - - inCodeBlock, codeBlockLines = handleLineInCodeBlock(strings.TrimSpace(line), line, inCodeBlock, language, codeBlockLines) - - if !inCodeBlock { - lines = append(lines, codeBlockLines...) - codeBlockLines = codeBlockLines[:0] - if !strings.HasPrefix(line, "```") { - lines = append(lines, line) - } - } - } - - if inCodeBlock { - codeBlockLines = append(codeBlockLines, "\t\t\t// ```") - lines = append(lines, codeBlockLines...) - } - - return lines, scanner.Err() -} - -// handleLineInCodeBlock categorizes and handles each line based on its -// content and relation to code blocks found in a TTP README. -func handleLineInCodeBlock(trimmedLine, line string, inCodeBlock bool, language string, codeBlockLines []string) (bool, []string) { - switch { - case strings.HasPrefix(trimmedLine, "```"+language): - if !inCodeBlock { - codeBlockLines = append(codeBlockLines, line) - } - return !inCodeBlock, codeBlockLines - case inCodeBlock: - codeBlockLines = append(codeBlockLines, line) - case strings.Contains(trimmedLine, "```"): - inCodeBlock = false - } - return inCodeBlock, codeBlockLines -} - -// extractTTPForgeCommand extracts the TTPForge run commands from the provided -// reader (parsed README content). This approach automates the testing of -// examples by leveraging the commands documented in READMEs. -func extractTTPForgeCommand(r io.Reader) ([]string, error) { - lines, err := processLines(r, "bash") - if err != nil { - return nil, err - } - - var inCodeBlock bool - var currentCommand string - var commands []string - - for _, line := range lines { - trimmedLine := strings.TrimSpace(line) - - // Remove the backslashes at the end - trimmedLine = strings.TrimSuffix(trimmedLine, "\\") - - switch { - case strings.Contains(trimmedLine, "```bash"): - inCodeBlock = true - currentCommand = "" - case inCodeBlock && strings.Contains(trimmedLine, "```"): - inCodeBlock = false - if currentCommand != "" { - commands = append(commands, strings.TrimSpace(currentCommand)) - } - case inCodeBlock: - if currentCommand != "" { - currentCommand += " " + trimmedLine - } else { - currentCommand = trimmedLine - } - } - } - - return commands, nil -} - -// findReadmeFiles looks for README.md files in the specified directory. -// The READMEs are expected to contain TTPForge commands that serve as -// user-facing instructions for the examples. By parsing these READMEs, we can -// automatically test and validate these instructions. -func findReadmeFiles(rootDir string) error { - return filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return fmt.Errorf("error accessing path %q: %v", path, err) - } - - if !info.IsDir() && info.Name() == "README.md" && strings.Contains(path, "ttps/examples") { - return processReadme(path, info) - } - return nil - }) -} - -// processReadme reads the content of a given README file, extracts the -// TTPForge commands, and runs them. This acts as a verification step to -// ensure the examples work as described in the README. -func processReadme(path string, info os.FileInfo) error { - contents, err := os.ReadFile(path) - if err != nil { - return fmt.Errorf("error reading %s:%v", path, err) - } - - commands, err := extractTTPForgeCommand(strings.NewReader(string(contents))) - if err != nil { - return fmt.Errorf("failed to parse %v: %v", path, err) - } - - for _, command := range commands { - if err := runExtractedCommand(command, info); err != nil { - return err - } - } - return nil -} - -// runExtractedCommand executes the input TTPForge command, acting as a -// dynamic validation step. -func runExtractedCommand(command string, info os.FileInfo) error { - if command == "" { - return nil - } - - parts := strings.Fields(command) - if len(parts) < 3 { - return fmt.Errorf("unexpected command format: %s", command) - } - - mainCommand, action, ttp := parts[0], parts[1], parts[2] - args := parts[3:] - - fmt.Printf("Running command extracted from %s: %s %s %s\n\n", info.Name(), mainCommand, action, strings.Join(args, " ")) - - if _, err := sys.RunCommand(mainCommand, append([]string{action, ttp}, args...)...); err != nil { - return fmt.Errorf("failed to run command %s %s %s: %v", mainCommand, action, strings.Join(args, " "), err) - } - return nil -} diff --git a/pkg/platforms/spec.go b/pkg/platforms/spec.go index b9e7a17c..6bd47deb 100644 --- a/pkg/platforms/spec.go +++ b/pkg/platforms/spec.go @@ -96,7 +96,7 @@ func (s *Spec) Validate() error { "linux": true, "netbsd": true, "openbsd": true, - // if you run this on plan9 I wil buy you a beer + // if you run this on plan9 I will buy you a beer "plan9": true, "solaris": true, "windows": true,