diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3200405af0..b2d65094d7 100755 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,13 +39,12 @@ jobs: - 1.22.x sys: - {os: ubuntu-latest} - - {os: macos-12, shell: zsh} + - {os: macos-13, shell: zsh} - {os: windows-2019} fail-fast: false runs-on: ${{ matrix.sys.os }} env: ACTIVESTATE_CI: true - ACTIVESTATE_CLI_DISABLE_RUNTIME: true SHELL: bash GITHUB_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_SHA_OVERRIDE: ${{ github.event.pull_request.head.sha || github.sha }} @@ -69,7 +68,7 @@ jobs: - # === Install Go === name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} @@ -393,20 +392,44 @@ jobs: - # === Upload Session Artifacts === name: Upload Session Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: session-build-${{ matrix.sys.os }} path: build/ + scan: + name: Scan + needs: + - os_specific + runs-on: ubuntu-latest + steps: + - name: Download All Build Session Artifacts + uses: actions/download-artifact@v4 + with: + path: build/ + merge-multiple: true + + - name: Scan for CVEs + if: runner.os == 'Linux' + uses: aquasecurity/trivy-action@0.26.0 + env: + TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db + with: + scan-type: rootfs + scan-ref: build + list-all-pkgs: true + ignore-unfixed: true + format: table + exit-code: 1 + # === Deploy job (runs once with combined artifacts from OS specific job) === deploy: name: Deploy needs: - - os_specific + - scan runs-on: ubuntu-20.04 env: ACTIVESTATE_CI: true - ACTIVESTATE_CLI_DISABLE_RUNTIME: true SHELL: bash GITHUB_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_SHA_OVERRIDE: ${{ github.event.pull_request.head.sha || github.sha }} @@ -424,9 +447,9 @@ jobs: - # === Install Go === name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: ${{ matrix.go-version }} + go-version: 1.22.x - # === Install State Tool === name: Install State Tool @@ -434,9 +457,10 @@ jobs: - # === Download All Build Session Artifacts === name: Download All Build Session Artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: path: build/ + merge-multiple: true - # === Sanitize All Session Artifacts === name: Sanitize All Session Artifacts @@ -481,16 +505,9 @@ jobs: - # === Cleanup Session Artifacts === name: Cleanup Session Artifacts - uses: geekyeggo/delete-artifact@v1 + uses: geekyeggo/delete-artifact@v5 with: name: | session-build-ubuntu-20.04 session-build-macos-11 session-build-windows-2019 - - - # === Upload Artifacts === - name: Upload Artifacts - uses: actions/upload-artifact@v2 - with: - name: build - path: build/ diff --git a/.github/workflows/propagate.yml b/.github/workflows/propagate.yml index 5b44a7cad4..6e5f7247bf 100644 --- a/.github/workflows/propagate.yml +++ b/.github/workflows/propagate.yml @@ -25,14 +25,14 @@ jobs: - # === Checkout code === name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GH_AUTOMATION_TOKEN }} - # === Install Go === name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: '1.22.x' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 48c9728f30..b76d7809b3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: steps: - # Checkout Code name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v5 - # === Install Go === name: Install Go diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml new file mode 100644 index 0000000000..569fc6cb69 --- /dev/null +++ b/.github/workflows/scan.yml @@ -0,0 +1,44 @@ +name: Scan + +on: + schedule: + - cron: 0 0 * * * + +jobs: + fetch-binaries: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Install State Tool + uses: ActiveState/setup-state-tool@v1 + + - name: Copy State Tool binaries to workspace dir + shell: bash + run: | + exe=`which state` + dir=`dirname $exe` + cp -r $dir/* '${{ github.workspace }}' + + - name: Upload binaries + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.os }}-binaries + path: . + + scan: + needs: fetch-binaries + runs-on: ubuntu-latest + steps: + - name: Download binaries + uses: actions/download-artifact@v4 + + - name: Scan binaries + uses: aquasecurity/trivy-action@0.20.0 + with: + scan-type: rootfs + scan-ref: '.' + ignore-unfixed: true + format: table + exit-code: 1 diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index f3c81c6357..1f72fcb663 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -34,7 +34,7 @@ jobs: - # === Install Go === name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: '1.22.x' diff --git a/.golangci.yaml b/.golangci.yaml index 576ed08e01..1006da06b7 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -32,7 +32,6 @@ linters-settings: - (*github.com/ActiveState/cli/internal/testhelpers/e2e.SpawnedCmd).Wait - (*github.com/ActiveState/cli/internal/testhelpers/e2e.Session).ClearCache - (*github.com/ActiveState/cli/internal/testhelpers/e2e.Dirs).Close - - (*github.com/ActiveState/cli/pkg/platform/runtime/artifactcache.testArtifactCache).Store - github.com/ActiveState/cli/internal/testhelpers/osutil.RemoveConfigFile - (*github.com/ActiveState/cli/internal/logging.standardHandler).Emit - (*github.com/ActiveState/cli/internal/logging.fileHandler).Emit diff --git a/activestate.generators.yaml b/activestate.generators.yaml index 50b5c40a50..e84712a169 100644 --- a/activestate.generators.yaml +++ b/activestate.generators.yaml @@ -84,7 +84,8 @@ scripts: language: bash description: Generates graph server and client files value: | - go install github.com/99designs/gqlgen@v0.17.24 + set -e + go install github.com/99designs/gqlgen@v0.17.48 cd ./cmd/state-svc && gqlgen --verbose - name: generate-test-update language: bash diff --git a/activestate.yaml b/activestate.yaml index 5b95a3827c..0f18c9cfdb 100644 --- a/activestate.yaml +++ b/activestate.yaml @@ -48,6 +48,7 @@ constants: scripts: - name: install-deps-dev language: bash + standalone: true if: ne .Shell "cmd" value: | if ! type "go" &> /dev/null; then @@ -55,37 +56,40 @@ scripts: exit 1 fi if ! type "golangci-lint" &> /dev/null; then - echo "golangci-lint was not found on your PATH, installing .." + echo "golangci-lint was not found on your PATH. Installing .." go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.1 fi git config core.hooksPath .githooks if ! type "swagger" &> /dev/null; then - echo "swagger was not found on your PATH, installing .." + echo "swagger was not found on your PATH. Installing .." go install github.com/go-swagger/go-swagger/cmd/swagger@v0.27.0 fi if ! type "actionlint" &> /dev/null; then - echo "actionlint was not found on your PATH, installing .." + echo "actionlint was not found on your PATH. Installing .." go install github.com/rhysd/actionlint/cmd/actionlint@v1.6.23 fi if { [[ "$GOOS" == "windows" ]] || [[ "$OS" == "Windows_NT" ]]; } && ! type "goversioninfo" &> /dev/null; then - echo "goversioninfo was not found on your PATH, installing .." + echo "goversioninfo was not found on your PATH. Installing .." GOFLAGS="" go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.0 fi - name: install-deps-os language: bash + standalone: true if: ne .OS.Name "Linux" description: Install OS specific deps value: "" - name: install-deps-ci language: bash + standalone: true if: ne .Shell "cmd" value: | if { [[ "$GOOS" == "windows" ]] || [[ "$OS" == "Windows_NT" ]]; } && ! type "goversioninfo" &> /dev/null; then - echo "goversioninfo was not found on your PATH, installing .." + echo "goversioninfo was not found on your PATH. Installing .." GOFLAGS="" go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.0 fi - name: preprocess language: bash + standalone: true description: Generates assets required by the project that aren't just specific to the build value: | set -e @@ -97,6 +101,7 @@ scripts: fi - name: build language: bash + standalone: true description: Builds the project with the host OS as the target OS. value: | set -e @@ -111,6 +116,7 @@ scripts: go build -tags "$GO_BUILD_TAGS" -o $BUILD_TARGET_DIR/$constants.BUILD_TARGET $constants.CLI_BUILDFLAGS $constants.CLI_PKGS - name: build-for language: bash + standalone: true description: Builds the project with the specified OS as the target OS. (valid values darwin, linux, windows) value: | set -e @@ -121,6 +127,7 @@ scripts: go build -tags "internal $GO_BUILD_TAGS" -o ${2} $constants.CLI_BUILDFLAGS $constants.CLI_PKGS - name: build-svc language: bash + standalone: true description: Builds the state-svc daemon value: | set -e @@ -136,6 +143,7 @@ scripts: - name: build-exec description: Builds the State Executor application language: bash + standalone: true value: | set -e $constants.SET_ENV @@ -143,8 +151,8 @@ scripts: go build -tags "$GO_BUILD_TAGS" -o $BUILD_TARGET_DIR/$constants.BUILD_EXEC_TARGET $constants.CLI_BUILDFLAGS $constants.EXECUTOR_PKGS - name: build-all description: Builds all our tools - standalone: true language: bash + standalone: true value: | set -e echo "Building State Tool" @@ -159,6 +167,7 @@ scripts: $scripts.build-exec.path() - name: build-installer language: bash + standalone: true description: Builds the state-installer value: | set -e @@ -167,13 +176,14 @@ scripts: go build -tags "$GO_BUILD_TAGS" -o $BUILD_TARGET_DIR/$constants.BUILD_INSTALLER_TARGET $constants.INSTALLER_PKGS - name: build-remote-installer language: bash + standalone: true description: Builds the state-remote-installer value: | set -e $constants.SET_ENV - TARGET=$BUILD_REMOTE_INSTALLER_TARGET + TARGET=$constants.BUILD_REMOTE_INSTALLER_TARGET if [[ "$GOOS" == "windows" || "$OS" == "Windows_NT" ]]; then - TARGET="${BUILD_REMOTE_INSTALLER_TARGET}.exe" + TARGET="${constants.BUILD_REMOTE_INSTALLER_TARGET}.exe" fi GOFLAGS="" go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.0 cd cmd/state-remote-installer @@ -181,12 +191,14 @@ scripts: go build -tags "$GO_BUILD_TAGS" -o ../../$BUILD_TARGET_DIR/$TARGET . - name: install language: bash + standalone: true description: Installs the current HEAD version into GOBIN value: | $constants.SET_ENV go install $constants.CLI_BUILDFLAGS $CLI_PKGS - name: deploy-updates language: bash + standalone: true description: Deploys update files to S3. This steps is automated by CI and should never be ran manually unless you KNOW WHAT YOU'RE DOING. value: | set -e @@ -232,17 +244,20 @@ scripts: cp installers/stop${constants.SCRIPT_EXT} $INSTALLERS_DIR/stop${constants.SCRIPT_EXT} - name: deploy-installers language: bash + standalone: true description: Deploys update files to S3. This steps is automated by CI and should never be ran manually unless you KNOW WHAT YOU'RE DOING. value: | go run scripts/ci/s3-deployer/main.go build/installers us-east-1 state-tool update/state - name: deploy-remote-installer language: bash + standalone: true value: | set -e $constants.SET_ENV go run scripts/ci/s3-deployer/main.go $BUILD_TARGET_DIR/remote-installer us-east-1 state-tool remote-installer - name: build-workflow-assets language: bash + standalone: true description: Generates our github workflows value: | $scripts.build-for.path() "windows" ./.github/deps/Windows/bin/state.exe @@ -254,6 +269,7 @@ scripts: GOOS=darwin go build -o .github/deps/macOS/bin/parallelize github.com/ActiveState/cli/scripts/ci/parallelize/ - name: update-workflow-assets language: bash + standalone: true description: Generates our github workflows value: | [ -z "${2}" ] && >&2 echo "Usage: update-workflow-assets [branch] [version]" && exit 1 @@ -286,12 +302,13 @@ scripts: rm -Rf $tmpDir - name: test language: bash + standalone: true description: Runs unit tests (not integration tests) value: | go test -v `go list ./... | grep -v integration | grep -v automation | grep -v expect | grep -v state-svc | grep -v state-offline` $@ - standalone: true - name: integration-tests language: bash + standalone: true description: Runs integration tests. value: | unset ACTIVESTATE_ACTIVATED @@ -300,6 +317,7 @@ scripts: go test `go list ./... | grep "${INTEGRATION_TEST_REGEX}"` -v "${@:1}" -timeout 20m - name: integration-tests-build-check language: bash + standalone: true description: Builds integration tests and removes the executable artifact(s). value: | out="x.test" @@ -307,28 +325,31 @@ scripts: [ -f $out ] && rm $out - name: clean language: bash + standalone: true description: Cleans out the build dir. value: | go clean rm -Rf build - name: run language: bash + standalone: true description: Builds the State Tool and runs it with `--help` value: | $scripts.build.path() build/state --help - name: debug language: bash - description: "Runs a remote debugger, that can be hooked into from your IDE, example usage: `state run debug activate` (will debug `state activate`)" standalone: true + description: "Runs a remote debugger that can be hooked into from your IDE. Example usage: `state run debug activate` (will debug `state activate`)" value: dlv debug --headless --listen=:2346 --api-version=2 github.com/ActiveState/cli/cmd/state -- $@ - name: scripted language: bash - description: "Runs a command via 'go run'" standalone: true + description: "Runs a command via 'go run'" value: go run github.com/ActiveState/cli/cmd/state $@ - name: story-cleanup language: bash + standalone: true description: "Runs Python script to move old stories from primary project to storage project" value: | export PT_API_TOKEN=$secrets.project.PT_API_TOKEN @@ -338,12 +359,14 @@ scripts: python3 ./scripts/story-cleanup/story-cleanup.py - name: lint language: bash + standalone: true description: "Runs linting for untracked and unstaged changes (if any), or staged changes" value: | golangci-lint run --new actionlint - name: lint-staged language: bash + standalone: true description: "Runs linting for staged changes (skipping untracked and unstaged-only files)" value: | golangci-lint run \ @@ -356,12 +379,14 @@ scripts: actionlint $actionfiles - name: lint-all language: bash + standalone: true description: "Runs linting for all files" value: | golangci-lint run --no-config actionlint - name: check-format language: bash + standalone: true description: "Checks if the code is formatted correctly" value: | set -e @@ -392,6 +417,7 @@ scripts: fi - name: grab-mergecommits language: bash + standalone: true value: | export JIRA_USERNAME=${secrets.user.JIRA_USERNAME} export JIRA_TOKEN=${secrets.user.JIRA_TOKEN} @@ -399,6 +425,7 @@ scripts: go run $project.path()/scripts/grab-mergecommits/main.go $1 - name: target-version-pr language: bash + standalone: true value: | export JIRA_USERNAME=${secrets.user.JIRA_USERNAME} export JIRA_TOKEN=${secrets.user.JIRA_TOKEN} @@ -406,6 +433,7 @@ scripts: go run $project.path()/scripts/ci/target-version-pr/main.go $1 - name: create-version-pr language: bash + standalone: true value: | export JIRA_USERNAME=${secrets.user.JIRA_USERNAME} export JIRA_TOKEN=${secrets.user.JIRA_TOKEN} @@ -413,6 +441,7 @@ scripts: go run $project.path()/scripts/create-version-pr/main.go $1 - name: propagate-pr language: bash + standalone: true value: | export JIRA_USERNAME=${secrets.user.JIRA_USERNAME} export JIRA_TOKEN=${secrets.user.JIRA_TOKEN} @@ -420,6 +449,7 @@ scripts: go run $project.path()/scripts/ci/propagate-pr/main.go $1 - name: verify-pr language: bash + standalone: true value: | export JIRA_USERNAME=${secrets.user.JIRA_USERNAME} export JIRA_TOKEN=${secrets.user.JIRA_TOKEN} @@ -427,6 +457,7 @@ scripts: go run $project.path()/scripts/ci/verify-pr/main.go $1 - name: start-story language: bash + standalone: true value: | export JIRA_USERNAME=${secrets.user.JIRA_USERNAME} export JIRA_TOKEN=${secrets.user.JIRA_TOKEN} @@ -434,6 +465,7 @@ scripts: go run $project.path()/scripts/start-story/main.go "$@" - name: ghapi language: bash + standalone: true value: | curl \ -H "Accept: application/vnd.github+json" \ @@ -442,6 +474,7 @@ scripts: - name: benchmark-exec if: eq .OS.Name "Linux" language: bash + standalone: true description: "Benchmarks executable leveraging highly sensitive/accurate tooling" value: | # example usage: diff --git a/changelog.md b/changelog.md index 301af6959b..2f4dc4ae66 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,58 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.46.1 + +### Fixed + +* Fixed regression in `state refresh` where it would exit with a non-zero code when there were no changes. + +## 0.46.0 + +### Added + +* Added the `state export buildplan` command, which as the name implies exports the buildplan for a project commit. +* We now show dependency and CVE information when running `state commit` and `state import`, just like we do for + `state install`. +* We now show CVE information when running `state checkout`. +* When working with complex buildscripts that use ingredient revisions or more complex build rules we will now report + on these in `state manifest`. +* We now support CycloneDX and SPDX SBOMs for `state import`. +* We now provide unstable support for powershell when running `state shell` and other commands that interact with the + shell. + +### Changed + +* Runtime installations will now use a central artifact depot, and will use symlinks on mac/linux and hardlinks on + windows to deploy them for your various runtime. Reducing disk usage, and increasing installation speeds. + * We may still copy instead of link artifacts if the artifact in question requires runtime specific modifications. +* Streamlined the UI for sourcing runtimes, it should now be consistent across commands. +* We now also show dependency information when updating requirements. +* When running `state export log` with the `-i` (index) flag we no longer consider logs for the current command. + +### Fixed + +* Running `state init` with a language version specific to the minor version would sometimes not resolve the language. +* `state manifest` would sometimes not show the resolved version. +* Missing CVE information for languages in `state manifest`. +* Uninstalling state tool would leave you in a broken state that required manual intervention if and when the uninstall + failed halfway through. +* We would sometimes redundantly show available update information. +* Uninstalling State Tool on Windows would leave behind start menu shortcuts. +* Progress indication when solving and creating a commit (eg. when running `state install`) would sometimes overlap. +* Made several improvements to dependency calculations, which should give user a more accurate picture of what + dependencies were brought in by a given change. + * This only affects UI/UX. It does not imply any build or runtime functionality. +* Many localization and error message improvements and additions to help guide users to solutions. + +## 0.45.1 + +### Fixed + +* Fixed issue where installation on Windows would fail with a message from powershell saying script running is disabled. + * Context: We use a powershell script to create start menu shortcuts for the State Tool, as there are no solutions + in Golang to do this through system APIs. + ## 0.45.0 ### Added diff --git a/cmd/state-exec/meta.go b/cmd/state-exec/meta.go index 0deca9f622..2a18175b86 100644 --- a/cmd/state-exec/meta.go +++ b/cmd/state-exec/meta.go @@ -6,7 +6,7 @@ import ( "path/filepath" "strings" - "github.com/ActiveState/cli/pkg/platform/runtime/executors/execmeta" + "github.com/ActiveState/cli/pkg/executors/execmeta" ) const ( diff --git a/cmd/state-installer/cmd.go b/cmd/state-installer/cmd.go index 66cbd453f4..dc9f1deb72 100644 --- a/cmd/state-installer/cmd.go +++ b/cmd/state-installer/cmd.go @@ -93,7 +93,7 @@ func main() { var err error cfg, err = config.New() if err != nil { - multilog.Error("Could not set up configuration handler: " + errs.JoinMessage(err)) + multilog.Critical("Could not set up configuration handler: " + errs.JoinMessage(err)) fmt.Fprintln(os.Stderr, err.Error()) exitCode = 1 } @@ -108,7 +108,7 @@ func main() { Interactive: false, }) if err != nil { - multilog.Error("Could not set up output handler: " + errs.JoinMessage(err)) + multilog.Critical("Could not set up output handler: " + errs.JoinMessage(err)) fmt.Fprintln(os.Stderr, err.Error()) exitCode = 1 return @@ -148,7 +148,7 @@ func main() { "state-installer", "", "Installs or updates the State Tool", - primer.New(nil, out, nil, nil, nil, nil, cfg, nil, nil, an), + primer.New(out, cfg, an), []*captain.Flag{ // The naming of these flags is slightly inconsistent due to backwards compatibility requirements { Name: "command", @@ -251,6 +251,8 @@ func execute(out output.Outputer, cfg *config.Instance, an analytics.Dispatcher, an.Event(anaConst.CatInstallerFunnel, "exec") + usingDefaultInstallPath := params.path == "" + if params.path == "" { var err error params.path, err = installation.InstallPathForChannel(constants.ChannelName) @@ -296,6 +298,17 @@ func execute(out output.Outputer, cfg *config.Instance, an analytics.Dispatcher, return errs.Wrap(err, "Could not check if install path is empty") } if !empty { + if usingDefaultInstallPath { + // We're having trouble pinning down why these errors are occurring, so report the list of + // existing files to Rollbar to help diagnose. + if files, err := os.ReadDir(params.path); err == nil { + fileList := []string{} + for _, file := range files { + fileList = append(fileList, filepath.Join(params.path, file.Name())) + } + rollbar.Critical("Installation path must be an empty directory: %s\nExisting files:\n%s", params.path, strings.Join(fileList, "\n")) + } + } return locale.NewInputError("err_install_nonempty_dir", "Installation path must be an empty directory: {{.V0}}", params.path) } } diff --git a/cmd/state-installer/installer.go b/cmd/state-installer/installer.go index 9b06d7b616..65ce101cb5 100644 --- a/cmd/state-installer/installer.go +++ b/cmd/state-installer/installer.go @@ -240,11 +240,13 @@ func installedOnPath(installRoot, channel string) (bool, string, error) { // Check for state.exe in channel, root and bin dir // This is to handle older state tool versions that gave incompatible input paths + // Also, fall back on checking for the install dir marker in case of a failed uninstall attempt. candidates := []string{ filepath.Join(installRoot, channel, installation.BinDirName, stateCmd), filepath.Join(installRoot, channel, stateCmd), filepath.Join(installRoot, installation.BinDirName, stateCmd), filepath.Join(installRoot, stateCmd), + filepath.Join(installRoot, installation.InstallDirMarker), } for _, candidate := range candidates { if fileutils.TargetExists(candidate) { diff --git a/cmd/state-installer/test/integration/installer_int_test.go b/cmd/state-installer/test/integration/installer_int_test.go index 8a39f63e79..89b102a305 100644 --- a/cmd/state-installer/test/integration/installer_int_test.go +++ b/cmd/state-installer/test/integration/installer_int_test.go @@ -178,7 +178,7 @@ func (suite *InstallerIntegrationTestSuite) TestInstallErrorTips() { e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), ) - cp.ExpectInput() + cp.ExpectInput(e2e.RuntimeSourcingTimeoutOpt) cp.SendLine("state command-does-not-exist") cp.ExpectInput() cp.SendLine("exit") @@ -242,7 +242,7 @@ func (suite *InstallerIntegrationTestSuite) TestInstallWhileInUse() { cp.Expect("successfully installed", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectInput() cp.SendLine("state checkout ActiveState/Perl-5.32") - cp.Expect("Checked out") + cp.Expect("Checked out", e2e.RuntimeSourcingTimeoutOpt) cp.SendLine("state shell Perl-5.32") cp.Expect("Activated") // state.exe remains active diff --git a/cmd/state-remote-installer/main.go b/cmd/state-remote-installer/main.go index 03c170f9e9..c5c08b4fb5 100644 --- a/cmd/state-remote-installer/main.go +++ b/cmd/state-remote-installer/main.go @@ -123,7 +123,7 @@ func main() { "state-installer", "", "Installs or updates the State Tool", - primer.New(nil, out, nil, nil, nil, nil, cfg, nil, nil, an), + primer.New(out, cfg, an), []*captain.Flag{ // The naming of these flags is slightly inconsistent due to backwards compatibility requirements { Name: "channel", @@ -216,6 +216,9 @@ func execute(out output.Outputer, prompt prompt.Prompter, cfg *config.Instance, if params.nonInteractive { args = append(args, "-n") // forward to installer } + if params.force { + args = append(args, "--force") // forward to installer + } env := []string{ constants.InstallerNoSubshell + "=true", } diff --git a/cmd/state-svc/gqlgen.yml b/cmd/state-svc/gqlgen.yml index 6e113118ea..0c6a28fb70 100644 --- a/cmd/state-svc/gqlgen.yml +++ b/cmd/state-svc/gqlgen.yml @@ -59,3 +59,5 @@ models: - github.com/99designs/gqlgen/graphql.Int - github.com/99designs/gqlgen/graphql.Int64 - github.com/99designs/gqlgen/graphql.Int32 + Void: + model: github.com/ActiveState/cli/cmd/state-svc/internal/graphqltypes.Void diff --git a/cmd/state-svc/internal/graphqltypes/void.go b/cmd/state-svc/internal/graphqltypes/void.go new file mode 100644 index 0000000000..3b0ee407df --- /dev/null +++ b/cmd/state-svc/internal/graphqltypes/void.go @@ -0,0 +1,13 @@ +package graphqltypes + +import "io" + +type Void struct{} + +func (Void) MarshalGQL(w io.Writer) { + _, _ = w.Write([]byte("null")) +} + +func (v *Void) UnmarshalGQL(input interface{}) error { + return nil +} diff --git a/cmd/state-svc/internal/hash/file_hasher.go b/cmd/state-svc/internal/hash/file_hasher.go new file mode 100644 index 0000000000..505b1e3637 --- /dev/null +++ b/cmd/state-svc/internal/hash/file_hasher.go @@ -0,0 +1,112 @@ +package hash + +import ( + "fmt" + "io" + "os" + "path/filepath" + "sort" + "time" + + "github.com/ActiveState/cli/internal/errs" + "github.com/bmatcuk/doublestar/v4" + "github.com/cespare/xxhash" + "github.com/patrickmn/go-cache" +) + +type fileCache interface { + Get(key string) (interface{}, bool) + Set(key string, value interface{}, expiration time.Duration) +} + +type FileHasher struct { + cache fileCache +} + +type hashedFile struct { + Pattern string + Path string + Hash string +} + +func NewFileHasher() *FileHasher { + return &FileHasher{ + cache: cache.New(24*time.Hour, 24*time.Hour), + } +} + +func (fh *FileHasher) HashFiles(wd string, globs []string) (_ string, _ []hashedFile, rerr error) { + fs := os.DirFS(wd) + hashedFiles := []hashedFile{} + hashes := []string{} + for _, glob := range globs { + files, err := doublestar.Glob(fs, glob) + if err != nil { + return "", nil, errs.Wrap(err, "Could not match glob: %s", glob) + } + sort.Strings(files) // ensure consistent ordering + for _, relativePath := range files { + absolutePath, err := filepath.Abs(filepath.Join(wd, relativePath)) + if err != nil { + return "", nil, errs.Wrap(err, "Could not get absolute path for file: %s", relativePath) + } + fileInfo, err := os.Stat(absolutePath) + if err != nil { + return "", nil, errs.Wrap(err, "Could not stat file: %s", absolutePath) + } + + if fileInfo.IsDir() { + continue + } + + var hash string + cachedHash, ok := fh.cache.Get(cacheKey(fileInfo.Name(), fileInfo.ModTime())) + if ok { + hash, ok = cachedHash.(string) + if !ok { + return "", nil, errs.New("Could not convert cache value to string") + } + } else { + fileHasher := xxhash.New() + // include filepath in hash, because moving files should affect the hash + fmt.Fprintf(fileHasher, "%016x", relativePath) + file, err := os.Open(absolutePath) + if err != nil { + return "", nil, errs.Wrap(err, "Could not open file: %s", absolutePath) + } + defer file.Close() + if _, err := io.Copy(fileHasher, file); err != nil { + return "", nil, errs.Wrap(err, "Could not hash file: %s", fileInfo.Name()) + } + + hash = fmt.Sprintf("%016x", fileHasher.Sum64()) + } + + fh.cache.Set(cacheKey(fileInfo.Name(), fileInfo.ModTime()), hash, cache.NoExpiration) + + hashes = append(hashes, hash) + hashedFiles = append(hashedFiles, hashedFile{ + Pattern: glob, + Path: relativePath, + Hash: hash, + }) + } + } + + if hashedFiles == nil { + return "", nil, nil + } + + // Ensure the overall hash is consistently calculated + sort.Slice(hashedFiles, func(i, j int) bool { return hashedFiles[i].Path < hashedFiles[j].Path }) + h := xxhash.New() + for _, f := range hashedFiles { + fmt.Fprintf(h, "%016x", f.Hash) + } + + return fmt.Sprintf("%016x", h.Sum64()), hashedFiles, nil +} + +func cacheKey(file string, modTime time.Time) string { + return fmt.Sprintf("%s-%d", file, modTime.UTC().UnixNano()) +} diff --git a/cmd/state-svc/internal/hash/file_hasher_test.go b/cmd/state-svc/internal/hash/file_hasher_test.go new file mode 100644 index 0000000000..2873e53ded --- /dev/null +++ b/cmd/state-svc/internal/hash/file_hasher_test.go @@ -0,0 +1,254 @@ +package hash + +import ( + "fmt" + "os" + "path/filepath" + "sort" + "strings" + "testing" + "time" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/osutils" + "github.com/patrickmn/go-cache" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type testCache struct { + cache *cache.Cache + hits []string + misses []string +} + +func (tc *testCache) Get(key string) (interface{}, bool) { + val, ok := tc.cache.Get(key) + if ok { + tc.hits = append(tc.hits, key) + } else { + tc.misses = append(tc.misses, key) + } + + return val, ok +} + +func (tc *testCache) Set(key string, value interface{}, expiration time.Duration) { + tc.cache.Set(key, value, cache.DefaultExpiration) +} + +func TestFileHasher_HashFiles(t *testing.T) { + dir := fileutils.TempDirUnsafe() + file1 := createTempFile(t, dir, "file1.txt") + file2 := createTempFile(t, dir, "file2.info") + subfile1 := createTempFile(t, dir, "dir1/subfile1.txt") + + hasher := NewFileHasher() + + hash1, files1, err := hasher.HashFiles(dir, []string{file1, file2, subfile1}) + require.NoError(t, err) + + hash2, files2, err := hasher.HashFiles(dir, []string{"./**/*"}) + require.NoError(t, err, errs.JoinMessage(err)) + + for _, f := range files1 { + assert.False(t, strings.HasPrefix(f.Path, dir), fmt.Sprintf("'%s' should not be prefixed with '%s'", f.Path, dir)) + } + + sort.Slice(files1, func(i, j int) bool { return files1[i].Path < files1[j].Path }) + sort.Slice(files2, func(i, j int) bool { return files2[i].Path < files2[j].Path }) + require.Len(t, files2, 3) + require.Len(t, files2, len(files1)) + + for i, f := range files1 { + assert.Equal(t, f.Path, files2[i].Path) + assert.Equal(t, f.Hash, files2[i].Hash) + } + + assert.Equal(t, hash1, hash2) +} + +func TestFileHasher_CacheHit(t *testing.T) { + file1 := createTempFile(t, "", "file1") + file2 := createTempFile(t, "", "file2") + + tc := &testCache{ + cache: cache.New(cache.NoExpiration, cache.NoExpiration), + } + + hasher := &FileHasher{ + cache: tc, + } + + hash1, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + hash2, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + assert.Equal(t, hash1, hash2) + assert.Len(t, tc.hits, 2) + assert.Len(t, tc.misses, 2) +} + +func TestFileHasher_CacheMiss(t *testing.T) { + file1 := createTempFile(t, "", "file1") + file2 := createTempFile(t, "", "file2") + + tc := &testCache{ + cache: cache.New(cache.NoExpiration, cache.NoExpiration), + } + + hasher := &FileHasher{ + cache: tc, + } + + hash1, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + if err := os.Chtimes(file1, time.Now(), time.Now()); err != nil { + t.Fatal(err) + } + + file, err := os.Open(file1) + assert.NoError(t, err) + err = file.Sync() + assert.NoError(t, err) + + hash2, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + assert.Equal(t, hash1, hash2) + assert.Len(t, tc.hits, 1) + assert.Len(t, tc.misses, 3) +} + +func TestFileHasher_ContentAgnostic(t *testing.T) { + // Files have same content but different names and modification times + file1 := createTempFile(t, "", "file1") + + // Ensure mod times are different + time.Sleep(1 * time.Millisecond) + file2 := createTempFile(t, "", "file1") + + tc := &testCache{ + cache: cache.New(cache.NoExpiration, cache.NoExpiration), + } + + hasher := &FileHasher{ + cache: tc, + } + + hash1, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + hash2, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + assert.Equal(t, hash1, hash2) + assert.Len(t, tc.hits, 2) + assert.Len(t, tc.misses, 2) +} + +func TestFileHasher_NotEqualFileAdded(t *testing.T) { + file1 := createTempFile(t, "", "file1") + file2 := createTempFile(t, "", "file2") + file3 := createTempFile(t, "", "file3") + + tc := &testCache{ + cache: cache.New(cache.NoExpiration, cache.NoExpiration), + } + + hasher := &FileHasher{ + cache: tc, + } + + hash1, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + hash2, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2, file3}) + assert.NoError(t, err) + + assert.NotEqual(t, hash1, hash2) + assert.Len(t, tc.hits, 2) + assert.Len(t, tc.misses, 3) +} + +func TestFileHasher_NotEqualFileRemoved(t *testing.T) { + file1 := createTempFile(t, "", "file1") + file2 := createTempFile(t, "", "file2") + file3 := createTempFile(t, "", "file3") + + tc := &testCache{ + cache: cache.New(cache.NoExpiration, cache.NoExpiration), + } + + hasher := &FileHasher{ + cache: tc, + } + + hash1, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2, file3}) + assert.NoError(t, err) + + hash2, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + assert.NotEqual(t, hash1, hash2) + assert.Len(t, tc.hits, 2) + assert.Len(t, tc.misses, 3) +} + +func TestFileHasher_NotEqualContentChanged(t *testing.T) { + file1 := createTempFile(t, "", "file1") + file2 := createTempFile(t, "", "file2") + + tc := &testCache{ + cache: cache.New(cache.NoExpiration, cache.NoExpiration), + } + + hasher := &FileHasher{ + cache: tc, + } + + hash1, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + hash2, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + assert.Equal(t, hash1, hash2) + + // Change content of file1 and ensure mod time is different to avoid a cache hit. + // The time these tests take as well as the accuracy of the file system's mod time + // resolution may cause the mod time to be the same. + time.Sleep(10 * time.Millisecond) + if err := os.WriteFile(file1, []byte("file1_changed"), 0644); err != nil { + t.Fatal(err) + } + + hash2Modified, _, err := hasher.HashFiles(osutils.GetwdUnsafe(), []string{file1, file2}) + assert.NoError(t, err) + + assert.NotEqual(t, hash1, hash2Modified) + assert.Len(t, tc.hits, 3) + assert.Len(t, tc.misses, 3) +} + +func createTempFile(t *testing.T, dir, path string) string { + if dir == "" { + dir = t.TempDir() + } + if path == "" { + tmpfile, err := os.CreateTemp(dir, "") + if err != nil { + t.Fatal(err) + } + path = tmpfile.Name() + tmpfile.Close() + } + err := fileutils.WriteFile(filepath.Join(dir, path), []byte(path)) // Contents aren't important so long as they're consistent + require.NoError(t, err, errs.JoinMessage(err)) + + return path +} diff --git a/cmd/state-svc/internal/resolver/resolver.go b/cmd/state-svc/internal/resolver/resolver.go index ef4fb27061..7995751f88 100644 --- a/cmd/state-svc/internal/resolver/resolver.go +++ b/cmd/state-svc/internal/resolver/resolver.go @@ -9,6 +9,8 @@ import ( "strconv" "time" + "github.com/ActiveState/cli/cmd/state-svc/internal/graphqltypes" + "github.com/ActiveState/cli/cmd/state-svc/internal/hash" "github.com/ActiveState/cli/cmd/state-svc/internal/messages" "github.com/ActiveState/cli/cmd/state-svc/internal/rtwatcher" genserver "github.com/ActiveState/cli/cmd/state-svc/internal/server/generated" @@ -28,6 +30,7 @@ import ( "github.com/ActiveState/cli/internal/updater" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/projectfile" + "github.com/patrickmn/go-cache" ) type Resolver struct { @@ -36,10 +39,12 @@ type Resolver struct { updatePoller *poller.Poller authPoller *poller.Poller projectIDCache *projectcache.ID + fileHasher *hash.FileHasher an *sync.Client anForClient *sync.Client // Use separate client for events sent through service so we don't contaminate one with the other rtwatch *rtwatcher.Watcher auth *authentication.Auth + globalCache *cache.Cache } // var _ genserver.ResolverRoot = &Resolver{} // Must implement ResolverRoot @@ -81,10 +86,12 @@ func New(cfg *config.Instance, an *sync.Client, auth *authentication.Auth) (*Res pollUpdate, pollAuth, projectcache.NewID(), + hash.NewFileHasher(), an, anForClient, rtwatcher.New(cfg, anForClient), auth, + cache.New(time.Hour, 10*time.Minute), }, nil } @@ -100,6 +107,8 @@ func (r *Resolver) Close() error { // So far no need for this, so we're pointing back at ourselves.. func (r *Resolver) Query() genserver.QueryResolver { return r } +func (r *Resolver) Mutation() genserver.MutationResolver { return r } + func (r *Resolver) Version(ctx context.Context) (*graph.Version, error) { defer func() { handlePanics(recover(), debug.Stack()) }() @@ -263,6 +272,8 @@ func (r *Resolver) GetProcessesInUse(ctx context.Context, execDir string) ([]*gr } func (r *Resolver) GetJwt(ctx context.Context) (*graph.Jwt, error) { + defer func() { handlePanics(recover(), debug.Stack()) }() + if err := r.auth.MaybeRenew(); err != nil { return nil, errs.Wrap(err, "Could not renew auth token") } @@ -296,6 +307,41 @@ func (r *Resolver) GetJwt(ctx context.Context) (*graph.Jwt, error) { return jwt, nil } +func (r *Resolver) HashGlobs(ctx context.Context, wd string, globs []string) (*graph.GlobResult, error) { + defer func() { handlePanics(recover(), debug.Stack()) }() + + hash, files, err := r.fileHasher.HashFiles(wd, globs) + if err != nil { + return nil, errs.Wrap(err, "Could not hash files") + } + + result := &graph.GlobResult{ + Hash: hash, + } + for _, f := range files { + result.Files = append(result.Files, &graph.GlobFileResult{ + Pattern: f.Pattern, + Path: f.Path, + Hash: f.Hash, + }) + } + + return result, nil +} + +func (r *Resolver) GetCache(ctx context.Context, key string) (string, error) { + v, exists := r.globalCache.Get(key) + if !exists { + return "", nil + } + return v.(string), nil +} + +func (r *Resolver) SetCache(ctx context.Context, key string, value string, expiry int) (*graphqltypes.Void, error) { + r.globalCache.Set(key, value, time.Duration(expiry)*time.Second) + return &graphqltypes.Void{}, nil +} + func handlePanics(recovered interface{}, stack []byte) { if recovered != nil { multilog.Error("Panic: %v", recovered) diff --git a/cmd/state-svc/internal/rtwatcher/watcher.go b/cmd/state-svc/internal/rtwatcher/watcher.go index 816e5c0fde..7b28d25513 100644 --- a/cmd/state-svc/internal/rtwatcher/watcher.go +++ b/cmd/state-svc/internal/rtwatcher/watcher.go @@ -2,6 +2,7 @@ package rtwatcher import ( "encoding/json" + "errors" "os" "runtime/debug" "strconv" @@ -81,7 +82,8 @@ func (w *Watcher) check() { for i := range w.watching { e := w.watching[i] // Must use index, because we are deleting indexes further down running, err := e.IsRunning() - if err != nil && !errs.Matches(err, &processError{}) { + var errProcess *processError + if err != nil && !errors.As(err, &errProcess) { multilog.Error("Could not check if runtime process is running: %s", errs.JoinMessage(err)) // Don't return yet, the conditional below still needs to clear this entry } @@ -110,7 +112,8 @@ func (w *Watcher) GetProcessesInUse(execDir string) []entry { continue } isRunning, err := proc.IsRunning() - if err != nil && !errs.Matches(err, &processError{}) { + var errProcess *processError + if err != nil && !errors.As(err, &errProcess) { multilog.Error("Could not check if runtime process is running: %s", errs.JoinMessage(err)) // Any errors should not affect fetching which processes are currently in use. We just won't // include this one in the list. diff --git a/cmd/state-svc/internal/server/generated/generated.go b/cmd/state-svc/internal/server/generated/generated.go index 9d0589b013..16617b4d7b 100644 --- a/cmd/state-svc/internal/server/generated/generated.go +++ b/cmd/state-svc/internal/server/generated/generated.go @@ -9,9 +9,11 @@ import ( "fmt" "strconv" "sync" + "sync/atomic" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/introspection" + "github.com/ActiveState/cli/cmd/state-svc/internal/graphqltypes" "github.com/ActiveState/cli/internal/graph" gqlparser "github.com/vektah/gqlparser/v2" "github.com/vektah/gqlparser/v2/ast" @@ -22,6 +24,7 @@ import ( // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { return &executableSchema{ + schema: cfg.Schema, resolvers: cfg.Resolvers, directives: cfg.Directives, complexity: cfg.Complexity, @@ -29,12 +32,14 @@ func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { } type Config struct { + Schema *ast.Schema Resolvers ResolverRoot Directives DirectiveRoot Complexity ComplexityRoot } type ResolverRoot interface { + Mutation() MutationResolver Query() QueryResolver } @@ -58,6 +63,17 @@ type ComplexityRoot struct { Received func(childComplexity int) int } + GlobFileResult struct { + Hash func(childComplexity int) int + Path func(childComplexity int) int + Pattern func(childComplexity int) int + } + + GlobResult struct { + Files func(childComplexity int) int + Hash func(childComplexity int) int + } + JWT struct { Token func(childComplexity int) int User func(childComplexity int) int @@ -72,6 +88,10 @@ type ComplexityRoot struct { Repeat func(childComplexity int) int } + Mutation struct { + SetCache func(childComplexity int, key string, value string, expiry int) int + } + Organization struct { Role func(childComplexity int) int URLname func(childComplexity int) int @@ -93,8 +113,10 @@ type ComplexityRoot struct { CheckMessages func(childComplexity int, command string, flags []string) int ConfigChanged func(childComplexity int, key string) int FetchLogTail func(childComplexity int) int + GetCache func(childComplexity int, key string) int GetJwt func(childComplexity int) int GetProcessesInUse func(childComplexity int, execDir string) int + HashGlobs func(childComplexity int, wd string, globs []string) int Projects func(childComplexity int) int ReportRuntimeUsage func(childComplexity int, pid int, exec string, source string, dimensionsJSON string) int Version func(childComplexity int) int @@ -124,6 +146,9 @@ type ComplexityRoot struct { } } +type MutationResolver interface { + SetCache(ctx context.Context, key string, value string, expiry int) (*graphqltypes.Void, error) +} type QueryResolver interface { Version(ctx context.Context) (*graph.Version, error) AvailableUpdate(ctx context.Context, desiredChannel string, desiredVersion string) (*graph.AvailableUpdate, error) @@ -135,20 +160,26 @@ type QueryResolver interface { FetchLogTail(ctx context.Context) (string, error) GetProcessesInUse(ctx context.Context, execDir string) ([]*graph.ProcessInfo, error) GetJwt(ctx context.Context) (*graph.Jwt, error) + HashGlobs(ctx context.Context, wd string, globs []string) (*graph.GlobResult, error) + GetCache(ctx context.Context, key string) (string, error) } type executableSchema struct { + schema *ast.Schema resolvers ResolverRoot directives DirectiveRoot complexity ComplexityRoot } func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } return parsedSchema } func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { - ec := executionContext{nil, e} + ec := executionContext{nil, e, 0, 0, nil} _ = ec switch typeName + "." + field { @@ -201,6 +232,41 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ConfigChangedResponse.Received(childComplexity), true + case "GlobFileResult.hash": + if e.complexity.GlobFileResult.Hash == nil { + break + } + + return e.complexity.GlobFileResult.Hash(childComplexity), true + + case "GlobFileResult.path": + if e.complexity.GlobFileResult.Path == nil { + break + } + + return e.complexity.GlobFileResult.Path(childComplexity), true + + case "GlobFileResult.pattern": + if e.complexity.GlobFileResult.Pattern == nil { + break + } + + return e.complexity.GlobFileResult.Pattern(childComplexity), true + + case "GlobResult.files": + if e.complexity.GlobResult.Files == nil { + break + } + + return e.complexity.GlobResult.Files(childComplexity), true + + case "GlobResult.hash": + if e.complexity.GlobResult.Hash == nil { + break + } + + return e.complexity.GlobResult.Hash(childComplexity), true + case "JWT.token": if e.complexity.JWT.Token == nil { break @@ -257,6 +323,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.MessageInfo.Repeat(childComplexity), true + case "Mutation.setCache": + if e.complexity.Mutation.SetCache == nil { + break + } + + args, err := ec.field_Mutation_setCache_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.SetCache(childComplexity, args["key"].(string), args["value"].(string), args["expiry"].(int)), true + case "Organization.role": if e.complexity.Organization.Role == nil { break @@ -354,6 +432,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.FetchLogTail(childComplexity), true + case "Query.getCache": + if e.complexity.Query.GetCache == nil { + break + } + + args, err := ec.field_Query_getCache_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.GetCache(childComplexity, args["key"].(string)), true + case "Query.getJWT": if e.complexity.Query.GetJwt == nil { break @@ -373,6 +463,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.GetProcessesInUse(childComplexity, args["execDir"].(string)), true + case "Query.hashGlobs": + if e.complexity.Query.HashGlobs == nil { + break + } + + args, err := ec.field_Query_hashGlobs_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.HashGlobs(childComplexity, args["wd"].(string), args["globs"].([]string)), true + case "Query.projects": if e.complexity.Query.Projects == nil { break @@ -482,19 +584,49 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { rc := graphql.GetOperationContext(ctx) - ec := executionContext{rc, e} + ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)} inputUnmarshalMap := graphql.BuildUnmarshalerMap() first := true switch rc.Operation.Operation { case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, rc.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + case ast.Mutation: return func(ctx context.Context) *graphql.Response { if !first { return nil } first = false ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) - data := ec._Query(ctx, rc.Operation.SelectionSet) + data := ec._Mutation(ctx, rc.Operation.SelectionSet) var buf bytes.Buffer data.MarshalGQL(&buf) @@ -511,20 +643,42 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { type executionContext struct { *graphql.OperationContext *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() } func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { if ec.DisableIntrospection { return nil, errors.New("introspection disabled") } - return introspection.WrapSchema(parsedSchema), nil + return introspection.WrapSchema(ec.Schema()), nil } func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { if ec.DisableIntrospection { return nil, errors.New("introspection disabled") } - return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil } var sources = []*ast.Source{ @@ -607,6 +761,17 @@ type JWT { user: User! } +type GlobFileResult { + pattern: String! + path: String! + hash: String! +} + +type GlobResult { + files: [GlobFileResult!]! + hash: String! +} + type Query { version: Version availableUpdate(desiredChannel: String!, desiredVersion: String!): AvailableUpdate @@ -618,6 +783,12 @@ type Query { fetchLogTail: String! getProcessesInUse(execDir: String!): [ProcessInfo!]! getJWT: JWT + hashGlobs(wd: String!, globs: [String!]!): GlobResult! + getCache(key: String!): String! +} + +type Mutation { + setCache(key: String!, value: String!, expiry: Int!): Void } type ConfigChangedResponse { @@ -628,6 +799,8 @@ type ProcessInfo { exe: String! pid: Int! } + +scalar Void `, BuiltIn: false}, } var parsedSchema = gqlparser.MustLoadSchema(sources...) @@ -636,6 +809,39 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...) // region ***************************** args.gotpl ***************************** +func (ec *executionContext) field_Mutation_setCache_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["key"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("key")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["key"] = arg0 + var arg1 string + if tmp, ok := rawArgs["value"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("value")) + arg1, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["value"] = arg1 + var arg2 int + if tmp, ok := rawArgs["expiry"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("expiry")) + arg2, err = ec.unmarshalNInt2int(ctx, tmp) + if err != nil { + return nil, err + } + } + args["expiry"] = arg2 + return args, nil +} + func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -765,6 +971,21 @@ func (ec *executionContext) field_Query_configChanged_args(ctx context.Context, return args, nil } +func (ec *executionContext) field_Query_getCache_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["key"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("key")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["key"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query_getProcessesInUse_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -780,6 +1001,30 @@ func (ec *executionContext) field_Query_getProcessesInUse_args(ctx context.Conte return args, nil } +func (ec *executionContext) field_Query_hashGlobs_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["wd"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("wd")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["wd"] = arg0 + var arg1 []string + if tmp, ok := rawArgs["globs"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("globs")) + arg1, err = ec.unmarshalNString2ᚕstringᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["globs"] = arg1 + return args, nil +} + func (ec *executionContext) field_Query_reportRuntimeUsage_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -891,7 +1136,7 @@ func (ec *executionContext) _AnalyticsEventResponse_sent(ctx context.Context, fi return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_AnalyticsEventResponse_sent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_AnalyticsEventResponse_sent(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "AnalyticsEventResponse", Field: field, @@ -935,7 +1180,7 @@ func (ec *executionContext) _AvailableUpdate_version(ctx context.Context, field return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_AvailableUpdate_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_AvailableUpdate_version(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "AvailableUpdate", Field: field, @@ -979,7 +1224,7 @@ func (ec *executionContext) _AvailableUpdate_channel(ctx context.Context, field return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_AvailableUpdate_channel(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_AvailableUpdate_channel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "AvailableUpdate", Field: field, @@ -1023,7 +1268,7 @@ func (ec *executionContext) _AvailableUpdate_path(ctx context.Context, field gra return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_AvailableUpdate_path(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_AvailableUpdate_path(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "AvailableUpdate", Field: field, @@ -1067,7 +1312,7 @@ func (ec *executionContext) _AvailableUpdate_platform(ctx context.Context, field return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_AvailableUpdate_platform(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_AvailableUpdate_platform(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "AvailableUpdate", Field: field, @@ -1111,7 +1356,7 @@ func (ec *executionContext) _AvailableUpdate_sha256(ctx context.Context, field g return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_AvailableUpdate_sha256(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_AvailableUpdate_sha256(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "AvailableUpdate", Field: field, @@ -1155,7 +1400,7 @@ func (ec *executionContext) _ConfigChangedResponse_received(ctx context.Context, return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ConfigChangedResponse_received(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_ConfigChangedResponse_received(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ConfigChangedResponse", Field: field, @@ -1168,8 +1413,8 @@ func (ec *executionContext) fieldContext_ConfigChangedResponse_received(ctx cont return fc, nil } -func (ec *executionContext) _JWT_token(ctx context.Context, field graphql.CollectedField, obj *graph.Jwt) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_JWT_token(ctx, field) +func (ec *executionContext) _GlobFileResult_pattern(ctx context.Context, field graphql.CollectedField, obj *graph.GlobFileResult) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_GlobFileResult_pattern(ctx, field) if err != nil { return graphql.Null } @@ -1182,7 +1427,7 @@ func (ec *executionContext) _JWT_token(ctx context.Context, field graphql.Collec }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Token, nil + return obj.Pattern, nil }) if err != nil { ec.Error(ctx, err) @@ -1199,9 +1444,9 @@ func (ec *executionContext) _JWT_token(ctx context.Context, field graphql.Collec return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_JWT_token(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GlobFileResult_pattern(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "JWT", + Object: "GlobFileResult", Field: field, IsMethod: false, IsResolver: false, @@ -1212,8 +1457,8 @@ func (ec *executionContext) fieldContext_JWT_token(ctx context.Context, field gr return fc, nil } -func (ec *executionContext) _JWT_user(ctx context.Context, field graphql.CollectedField, obj *graph.Jwt) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_JWT_user(ctx, field) +func (ec *executionContext) _GlobFileResult_path(ctx context.Context, field graphql.CollectedField, obj *graph.GlobFileResult) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_GlobFileResult_path(ctx, field) if err != nil { return graphql.Null } @@ -1226,7 +1471,7 @@ func (ec *executionContext) _JWT_user(ctx context.Context, field graphql.Collect }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.User, nil + return obj.Path, nil }) if err != nil { ec.Error(ctx, err) @@ -1238,36 +1483,26 @@ func (ec *executionContext) _JWT_user(ctx context.Context, field graphql.Collect } return graphql.Null } - res := resTmp.(*graph.User) + res := resTmp.(string) fc.Result = res - return ec.marshalNUser2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐUser(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_JWT_user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GlobFileResult_path(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "JWT", + Object: "GlobFileResult", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "userID": - return ec.fieldContext_User_userID(ctx, field) - case "username": - return ec.fieldContext_User_username(ctx, field) - case "email": - return ec.fieldContext_User_email(ctx, field) - case "organizations": - return ec.fieldContext_User_organizations(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type User", field.Name) + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _MessageInfo_id(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MessageInfo_id(ctx, field) +func (ec *executionContext) _GlobFileResult_hash(ctx context.Context, field graphql.CollectedField, obj *graph.GlobFileResult) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_GlobFileResult_hash(ctx, field) if err != nil { return graphql.Null } @@ -1280,7 +1515,7 @@ func (ec *executionContext) _MessageInfo_id(ctx context.Context, field graphql.C }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ID, nil + return obj.Hash, nil }) if err != nil { ec.Error(ctx, err) @@ -1297,9 +1532,9 @@ func (ec *executionContext) _MessageInfo_id(ctx context.Context, field graphql.C return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_MessageInfo_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GlobFileResult_hash(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "MessageInfo", + Object: "GlobFileResult", Field: field, IsMethod: false, IsResolver: false, @@ -1310,8 +1545,8 @@ func (ec *executionContext) fieldContext_MessageInfo_id(ctx context.Context, fie return fc, nil } -func (ec *executionContext) _MessageInfo_message(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MessageInfo_message(ctx, field) +func (ec *executionContext) _GlobResult_files(ctx context.Context, field graphql.CollectedField, obj *graph.GlobResult) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_GlobResult_files(ctx, field) if err != nil { return graphql.Null } @@ -1324,7 +1559,7 @@ func (ec *executionContext) _MessageInfo_message(ctx context.Context, field grap }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Message, nil + return obj.Files, nil }) if err != nil { ec.Error(ctx, err) @@ -1336,26 +1571,34 @@ func (ec *executionContext) _MessageInfo_message(ctx context.Context, field grap } return graphql.Null } - res := resTmp.(string) + res := resTmp.([]*graph.GlobFileResult) fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) + return ec.marshalNGlobFileResult2ᚕᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐGlobFileResultᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_MessageInfo_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GlobResult_files(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "MessageInfo", + Object: "GlobResult", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") + switch field.Name { + case "pattern": + return ec.fieldContext_GlobFileResult_pattern(ctx, field) + case "path": + return ec.fieldContext_GlobFileResult_path(ctx, field) + case "hash": + return ec.fieldContext_GlobFileResult_hash(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type GlobFileResult", field.Name) }, } return fc, nil } -func (ec *executionContext) _MessageInfo_condition(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MessageInfo_condition(ctx, field) +func (ec *executionContext) _GlobResult_hash(ctx context.Context, field graphql.CollectedField, obj *graph.GlobResult) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_GlobResult_hash(ctx, field) if err != nil { return graphql.Null } @@ -1368,7 +1611,7 @@ func (ec *executionContext) _MessageInfo_condition(ctx context.Context, field gr }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Condition, nil + return obj.Hash, nil }) if err != nil { ec.Error(ctx, err) @@ -1385,9 +1628,9 @@ func (ec *executionContext) _MessageInfo_condition(ctx context.Context, field gr return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_MessageInfo_condition(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GlobResult_hash(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "MessageInfo", + Object: "GlobResult", Field: field, IsMethod: false, IsResolver: false, @@ -1398,8 +1641,8 @@ func (ec *executionContext) fieldContext_MessageInfo_condition(ctx context.Conte return fc, nil } -func (ec *executionContext) _MessageInfo_repeat(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MessageInfo_repeat(ctx, field) +func (ec *executionContext) _JWT_token(ctx context.Context, field graphql.CollectedField, obj *graph.Jwt) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JWT_token(ctx, field) if err != nil { return graphql.Null } @@ -1412,7 +1655,7 @@ func (ec *executionContext) _MessageInfo_repeat(ctx context.Context, field graph }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Repeat, nil + return obj.Token, nil }) if err != nil { ec.Error(ctx, err) @@ -1424,26 +1667,26 @@ func (ec *executionContext) _MessageInfo_repeat(ctx context.Context, field graph } return graphql.Null } - res := resTmp.(graph.MessageRepeatType) + res := resTmp.(string) fc.Result = res - return ec.marshalNMessageRepeatType2githubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐMessageRepeatType(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_MessageInfo_repeat(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_JWT_token(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "MessageInfo", + Object: "JWT", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type MessageRepeatType does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _MessageInfo_interrupt(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MessageInfo_interrupt(ctx, field) +func (ec *executionContext) _JWT_user(ctx context.Context, field graphql.CollectedField, obj *graph.Jwt) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JWT_user(ctx, field) if err != nil { return graphql.Null } @@ -1456,7 +1699,7 @@ func (ec *executionContext) _MessageInfo_interrupt(ctx context.Context, field gr }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Interrupt, nil + return obj.User, nil }) if err != nil { ec.Error(ctx, err) @@ -1468,26 +1711,36 @@ func (ec *executionContext) _MessageInfo_interrupt(ctx context.Context, field gr } return graphql.Null } - res := resTmp.(graph.MessageInterruptType) + res := resTmp.(*graph.User) fc.Result = res - return ec.marshalNMessageInterruptType2githubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐMessageInterruptType(ctx, field.Selections, res) + return ec.marshalNUser2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐUser(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_MessageInfo_interrupt(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_JWT_user(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "MessageInfo", + Object: "JWT", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type MessageInterruptType does not have child fields") + switch field.Name { + case "userID": + return ec.fieldContext_User_userID(ctx, field) + case "username": + return ec.fieldContext_User_username(ctx, field) + case "email": + return ec.fieldContext_User_email(ctx, field) + case "organizations": + return ec.fieldContext_User_organizations(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type User", field.Name) }, } return fc, nil } -func (ec *executionContext) _MessageInfo_placement(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MessageInfo_placement(ctx, field) +func (ec *executionContext) _MessageInfo_id(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MessageInfo_id(ctx, field) if err != nil { return graphql.Null } @@ -1500,7 +1753,7 @@ func (ec *executionContext) _MessageInfo_placement(ctx context.Context, field gr }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Placement, nil + return obj.ID, nil }) if err != nil { ec.Error(ctx, err) @@ -1512,26 +1765,26 @@ func (ec *executionContext) _MessageInfo_placement(ctx context.Context, field gr } return graphql.Null } - res := resTmp.(graph.MessagePlacementType) + res := resTmp.(string) fc.Result = res - return ec.marshalNMessagePlacementType2githubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐMessagePlacementType(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_MessageInfo_placement(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MessageInfo_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "MessageInfo", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type MessagePlacementType does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Organization_URLname(ctx context.Context, field graphql.CollectedField, obj *graph.Organization) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Organization_URLname(ctx, field) +func (ec *executionContext) _MessageInfo_message(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MessageInfo_message(ctx, field) if err != nil { return graphql.Null } @@ -1544,7 +1797,7 @@ func (ec *executionContext) _Organization_URLname(ctx context.Context, field gra }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.URLname, nil + return obj.Message, nil }) if err != nil { ec.Error(ctx, err) @@ -1561,9 +1814,9 @@ func (ec *executionContext) _Organization_URLname(ctx context.Context, field gra return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Organization_URLname(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MessageInfo_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Organization", + Object: "MessageInfo", Field: field, IsMethod: false, IsResolver: false, @@ -1574,8 +1827,8 @@ func (ec *executionContext) fieldContext_Organization_URLname(ctx context.Contex return fc, nil } -func (ec *executionContext) _Organization_role(ctx context.Context, field graphql.CollectedField, obj *graph.Organization) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Organization_role(ctx, field) +func (ec *executionContext) _MessageInfo_condition(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MessageInfo_condition(ctx, field) if err != nil { return graphql.Null } @@ -1588,7 +1841,7 @@ func (ec *executionContext) _Organization_role(ctx context.Context, field graphq }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Role, nil + return obj.Condition, nil }) if err != nil { ec.Error(ctx, err) @@ -1605,9 +1858,9 @@ func (ec *executionContext) _Organization_role(ctx context.Context, field graphq return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Organization_role(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MessageInfo_condition(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Organization", + Object: "MessageInfo", Field: field, IsMethod: false, IsResolver: false, @@ -1618,8 +1871,8 @@ func (ec *executionContext) fieldContext_Organization_role(ctx context.Context, return fc, nil } -func (ec *executionContext) _ProcessInfo_exe(ctx context.Context, field graphql.CollectedField, obj *graph.ProcessInfo) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ProcessInfo_exe(ctx, field) +func (ec *executionContext) _MessageInfo_repeat(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MessageInfo_repeat(ctx, field) if err != nil { return graphql.Null } @@ -1632,7 +1885,7 @@ func (ec *executionContext) _ProcessInfo_exe(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Exe, nil + return obj.Repeat, nil }) if err != nil { ec.Error(ctx, err) @@ -1644,26 +1897,26 @@ func (ec *executionContext) _ProcessInfo_exe(ctx context.Context, field graphql. } return graphql.Null } - res := resTmp.(string) + res := resTmp.(graph.MessageRepeatType) fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) + return ec.marshalNMessageRepeatType2githubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐMessageRepeatType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ProcessInfo_exe(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MessageInfo_repeat(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ProcessInfo", + Object: "MessageInfo", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") + return nil, errors.New("field of type MessageRepeatType does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ProcessInfo_pid(ctx context.Context, field graphql.CollectedField, obj *graph.ProcessInfo) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ProcessInfo_pid(ctx, field) +func (ec *executionContext) _MessageInfo_interrupt(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MessageInfo_interrupt(ctx, field) if err != nil { return graphql.Null } @@ -1676,7 +1929,7 @@ func (ec *executionContext) _ProcessInfo_pid(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Pid, nil + return obj.Interrupt, nil }) if err != nil { ec.Error(ctx, err) @@ -1688,12 +1941,284 @@ func (ec *executionContext) _ProcessInfo_pid(ctx context.Context, field graphql. } return graphql.Null } - res := resTmp.(int) + res := resTmp.(graph.MessageInterruptType) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalNMessageInterruptType2githubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐMessageInterruptType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MessageInfo_interrupt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MessageInfo", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type MessageInterruptType does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MessageInfo_placement(ctx context.Context, field graphql.CollectedField, obj *graph.MessageInfo) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MessageInfo_placement(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Placement, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(graph.MessagePlacementType) + fc.Result = res + return ec.marshalNMessagePlacementType2githubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐMessagePlacementType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MessageInfo_placement(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MessageInfo", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type MessagePlacementType does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Mutation_setCache(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_setCache(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().SetCache(rctx, fc.Args["key"].(string), fc.Args["value"].(string), fc.Args["expiry"].(int)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*graphqltypes.Void) + fc.Result = res + return ec.marshalOVoid2ᚖgithubᚗcomᚋActiveStateᚋcliᚋcmdᚋstateᚑsvcᚋinternalᚋgraphqltypesᚐVoid(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ProcessInfo_pid(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Mutation_setCache(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Void does not have child fields") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_setCache_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Organization_URLname(ctx context.Context, field graphql.CollectedField, obj *graph.Organization) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Organization_URLname(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.URLname, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Organization_URLname(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Organization", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Organization_role(ctx context.Context, field graphql.CollectedField, obj *graph.Organization) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Organization_role(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Role, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Organization_role(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Organization", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ProcessInfo_exe(ctx context.Context, field graphql.CollectedField, obj *graph.ProcessInfo) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ProcessInfo_exe(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Exe, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ProcessInfo_exe(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ProcessInfo", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ProcessInfo_pid(ctx context.Context, field graphql.CollectedField, obj *graph.ProcessInfo) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ProcessInfo_pid(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Pid, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ProcessInfo_pid(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ProcessInfo", Field: field, @@ -1737,7 +2262,7 @@ func (ec *executionContext) _Project_namespace(ctx context.Context, field graphq return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Project_namespace(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Project_namespace(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Project", Field: field, @@ -1781,7 +2306,7 @@ func (ec *executionContext) _Project_locations(ctx context.Context, field graphq return ec.marshalNString2ᚕstringᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Project_locations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Project_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Project", Field: field, @@ -1812,6 +2337,7 @@ func (ec *executionContext) _Query_version(ctx context.Context, field graphql.Co }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { return graphql.Null @@ -1821,7 +2347,7 @@ func (ec *executionContext) _Query_version(ctx context.Context, field graphql.Co return ec.marshalOVersion2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐVersion(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query_version(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -1856,6 +2382,7 @@ func (ec *executionContext) _Query_availableUpdate(ctx context.Context, field gr }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { return graphql.Null @@ -1896,7 +2423,7 @@ func (ec *executionContext) fieldContext_Query_availableUpdate(ctx context.Conte ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query_availableUpdate_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -1919,6 +2446,7 @@ func (ec *executionContext) _Query_projects(ctx context.Context, field graphql.C }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { if !graphql.HasFieldError(ctx, fc) { @@ -1931,7 +2459,7 @@ func (ec *executionContext) _Query_projects(ctx context.Context, field graphql.C return ec.marshalNProject2ᚕᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐProject(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query_projects(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query_projects(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -1968,6 +2496,7 @@ func (ec *executionContext) _Query_analyticsEvent(ctx context.Context, field gra }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { return graphql.Null @@ -2000,7 +2529,7 @@ func (ec *executionContext) fieldContext_Query_analyticsEvent(ctx context.Contex ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query_analyticsEvent_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2023,6 +2552,7 @@ func (ec *executionContext) _Query_reportRuntimeUsage(ctx context.Context, field }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { return graphql.Null @@ -2055,7 +2585,7 @@ func (ec *executionContext) fieldContext_Query_reportRuntimeUsage(ctx context.Co ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query_reportRuntimeUsage_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2078,6 +2608,7 @@ func (ec *executionContext) _Query_checkMessages(ctx context.Context, field grap }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { if !graphql.HasFieldError(ctx, fc) { @@ -2123,7 +2654,7 @@ func (ec *executionContext) fieldContext_Query_checkMessages(ctx context.Context ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query_checkMessages_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2146,6 +2677,7 @@ func (ec *executionContext) _Query_configChanged(ctx context.Context, field grap }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { return graphql.Null @@ -2178,7 +2710,7 @@ func (ec *executionContext) fieldContext_Query_configChanged(ctx context.Context ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query_configChanged_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2201,6 +2733,7 @@ func (ec *executionContext) _Query_fetchLogTail(ctx context.Context, field graph }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { if !graphql.HasFieldError(ctx, fc) { @@ -2213,7 +2746,7 @@ func (ec *executionContext) _Query_fetchLogTail(ctx context.Context, field graph return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query_fetchLogTail(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query_fetchLogTail(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -2226,8 +2759,116 @@ func (ec *executionContext) fieldContext_Query_fetchLogTail(ctx context.Context, return fc, nil } -func (ec *executionContext) _Query_getProcessesInUse(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_getProcessesInUse(ctx, field) +func (ec *executionContext) _Query_getProcessesInUse(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_getProcessesInUse(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().GetProcessesInUse(rctx, fc.Args["execDir"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*graph.ProcessInfo) + fc.Result = res + return ec.marshalNProcessInfo2ᚕᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐProcessInfoᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_getProcessesInUse(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "exe": + return ec.fieldContext_ProcessInfo_exe(ctx, field) + case "pid": + return ec.fieldContext_ProcessInfo_pid(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ProcessInfo", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_getProcessesInUse_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_getJWT(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_getJWT(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().GetJwt(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*graph.Jwt) + fc.Result = res + return ec.marshalOJWT2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐJwt(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_getJWT(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "token": + return ec.fieldContext_JWT_token(ctx, field) + case "user": + return ec.fieldContext_JWT_user(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type JWT", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_hashGlobs(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_hashGlobs(ctx, field) if err != nil { return graphql.Null } @@ -2240,10 +2881,11 @@ func (ec *executionContext) _Query_getProcessesInUse(ctx context.Context, field }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().GetProcessesInUse(rctx, fc.Args["execDir"].(string)) + return ec.resolvers.Query().HashGlobs(rctx, fc.Args["wd"].(string), fc.Args["globs"].([]string)) }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { if !graphql.HasFieldError(ctx, fc) { @@ -2251,12 +2893,12 @@ func (ec *executionContext) _Query_getProcessesInUse(ctx context.Context, field } return graphql.Null } - res := resTmp.([]*graph.ProcessInfo) + res := resTmp.(*graph.GlobResult) fc.Result = res - return ec.marshalNProcessInfo2ᚕᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐProcessInfoᚄ(ctx, field.Selections, res) + return ec.marshalNGlobResult2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐGlobResult(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query_getProcessesInUse(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query_hashGlobs(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -2264,12 +2906,12 @@ func (ec *executionContext) fieldContext_Query_getProcessesInUse(ctx context.Con IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "exe": - return ec.fieldContext_ProcessInfo_exe(ctx, field) - case "pid": - return ec.fieldContext_ProcessInfo_pid(ctx, field) + case "files": + return ec.fieldContext_GlobResult_files(ctx, field) + case "hash": + return ec.fieldContext_GlobResult_hash(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type ProcessInfo", field.Name) + return nil, fmt.Errorf("no field named %q was found under type GlobResult", field.Name) }, } defer func() { @@ -2279,15 +2921,15 @@ func (ec *executionContext) fieldContext_Query_getProcessesInUse(ctx context.Con } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_getProcessesInUse_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_Query_hashGlobs_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } -func (ec *executionContext) _Query_getJWT(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_getJWT(ctx, field) +func (ec *executionContext) _Query_getCache(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_getCache(ctx, field) if err != nil { return graphql.Null } @@ -2300,35 +2942,44 @@ func (ec *executionContext) _Query_getJWT(ctx context.Context, field graphql.Col }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().GetJwt(rctx) + return ec.resolvers.Query().GetCache(rctx, fc.Args["key"].(string)) }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.(*graph.Jwt) + res := resTmp.(string) fc.Result = res - return ec.marshalOJWT2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐJwt(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query_getJWT(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query_getCache(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "token": - return ec.fieldContext_JWT_token(ctx, field) - case "user": - return ec.fieldContext_JWT_user(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type JWT", field.Name) + return nil, errors.New("field of type String does not have child fields") }, } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_getCache_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } return fc, nil } @@ -2350,6 +3001,7 @@ func (ec *executionContext) _Query___type(ctx context.Context, field graphql.Col }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { return graphql.Null @@ -2400,7 +3052,7 @@ func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2423,6 +3075,7 @@ func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.C }) if err != nil { ec.Error(ctx, err) + return graphql.Null } if resTmp == nil { return graphql.Null @@ -2432,7 +3085,7 @@ func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.C return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query___schema(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -2490,7 +3143,7 @@ func (ec *executionContext) _ReportRuntimeUsageResponse_received(ctx context.Con return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ReportRuntimeUsageResponse_received(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_ReportRuntimeUsageResponse_received(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ReportRuntimeUsageResponse", Field: field, @@ -2534,7 +3187,7 @@ func (ec *executionContext) _StateVersion_license(ctx context.Context, field gra return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_StateVersion_license(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_StateVersion_license(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "StateVersion", Field: field, @@ -2578,7 +3231,7 @@ func (ec *executionContext) _StateVersion_version(ctx context.Context, field gra return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_StateVersion_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_StateVersion_version(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "StateVersion", Field: field, @@ -2622,7 +3275,7 @@ func (ec *executionContext) _StateVersion_channel(ctx context.Context, field gra return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_StateVersion_channel(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_StateVersion_channel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "StateVersion", Field: field, @@ -2666,7 +3319,7 @@ func (ec *executionContext) _StateVersion_revision(ctx context.Context, field gr return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_StateVersion_revision(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_StateVersion_revision(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "StateVersion", Field: field, @@ -2710,7 +3363,7 @@ func (ec *executionContext) _StateVersion_date(ctx context.Context, field graphq return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_StateVersion_date(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_StateVersion_date(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "StateVersion", Field: field, @@ -2754,7 +3407,7 @@ func (ec *executionContext) _User_userID(ctx context.Context, field graphql.Coll return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_User_userID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_User_userID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "User", Field: field, @@ -2798,7 +3451,7 @@ func (ec *executionContext) _User_username(ctx context.Context, field graphql.Co return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_User_username(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_User_username(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "User", Field: field, @@ -2842,7 +3495,7 @@ func (ec *executionContext) _User_email(ctx context.Context, field graphql.Colle return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_User_email(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_User_email(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "User", Field: field, @@ -2886,7 +3539,7 @@ func (ec *executionContext) _User_organizations(ctx context.Context, field graph return ec.marshalNOrganization2ᚕᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐOrganizationᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_User_organizations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_User_organizations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "User", Field: field, @@ -2936,7 +3589,7 @@ func (ec *executionContext) _Version_state(ctx context.Context, field graphql.Co return ec.marshalNStateVersion2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐStateVersion(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Version_state(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Version_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Version", Field: field, @@ -2992,7 +3645,7 @@ func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3033,7 +3686,7 @@ func (ec *executionContext) ___Directive_description(ctx context.Context, field return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3077,7 +3730,7 @@ func (ec *executionContext) ___Directive_locations(ctx context.Context, field gr return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_locations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3121,7 +3774,7 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_args(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3175,7 +3828,7 @@ func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3219,7 +3872,7 @@ func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___EnumValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__EnumValue", Field: field, @@ -3260,7 +3913,7 @@ func (ec *executionContext) ___EnumValue_description(ctx context.Context, field return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___EnumValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__EnumValue", Field: field, @@ -3304,7 +3957,7 @@ func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__EnumValue", Field: field, @@ -3345,7 +3998,7 @@ func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__EnumValue", Field: field, @@ -3389,7 +4042,7 @@ func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.Col return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -3430,7 +4083,7 @@ func (ec *executionContext) ___Field_description(ctx context.Context, field grap return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -3474,7 +4127,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_args(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -3528,7 +4181,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -3594,7 +4247,7 @@ func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field gra return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -3635,7 +4288,7 @@ func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, fiel return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -3679,7 +4332,7 @@ func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphq return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___InputValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__InputValue", Field: field, @@ -3720,7 +4373,7 @@ func (ec *executionContext) ___InputValue_description(ctx context.Context, field return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___InputValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__InputValue", Field: field, @@ -3764,7 +4417,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___InputValue_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__InputValue", Field: field, @@ -3827,7 +4480,7 @@ func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, fiel return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__InputValue", Field: field, @@ -3868,7 +4521,7 @@ func (ec *executionContext) ___Schema_description(ctx context.Context, field gra return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -3912,7 +4565,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -3978,7 +4631,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_queryType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4041,7 +4694,7 @@ func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field gr return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_mutationType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4104,7 +4757,7 @@ func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, fiel return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4170,7 +4823,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_directives(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4226,7 +4879,7 @@ func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.Coll return ec.marshalN__TypeKind2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_kind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4267,7 +4920,7 @@ func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.Coll return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4308,7 +4961,7 @@ func (ec *executionContext) ___Type_description(ctx context.Context, field graph return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4382,7 +5035,7 @@ func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, fiel ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field___Type_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -4415,7 +5068,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4478,7 +5131,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_possibleTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4570,7 +5223,7 @@ func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field___Type_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -4603,7 +5256,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_inputFields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4654,7 +5307,7 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4717,7 +5370,7 @@ func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field gr return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4746,27 +5399,38 @@ var analyticsEventResponseImplementors = []string{"AnalyticsEventResponse"} func (ec *executionContext) _AnalyticsEventResponse(ctx context.Context, sel ast.SelectionSet, obj *graph.AnalyticsEventResponse) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, analyticsEventResponseImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("AnalyticsEventResponse") case "sent": - out.Values[i] = ec._AnalyticsEventResponse_sent(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4774,55 +5438,58 @@ var availableUpdateImplementors = []string{"AvailableUpdate"} func (ec *executionContext) _AvailableUpdate(ctx context.Context, sel ast.SelectionSet, obj *graph.AvailableUpdate) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, availableUpdateImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("AvailableUpdate") case "version": - out.Values[i] = ec._AvailableUpdate_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "channel": - out.Values[i] = ec._AvailableUpdate_channel(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "path": - out.Values[i] = ec._AvailableUpdate_path(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "platform": - out.Values[i] = ec._AvailableUpdate_platform(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "sha256": - out.Values[i] = ec._AvailableUpdate_sha256(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4830,27 +5497,131 @@ var configChangedResponseImplementors = []string{"ConfigChangedResponse"} func (ec *executionContext) _ConfigChangedResponse(ctx context.Context, sel ast.SelectionSet, obj *graph.ConfigChangedResponse) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, configChangedResponseImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("ConfigChangedResponse") case "received": - out.Values[i] = ec._ConfigChangedResponse_received(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var globFileResultImplementors = []string{"GlobFileResult"} + +func (ec *executionContext) _GlobFileResult(ctx context.Context, sel ast.SelectionSet, obj *graph.GlobFileResult) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, globFileResultImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("GlobFileResult") + case "pattern": + out.Values[i] = ec._GlobFileResult_pattern(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "path": + out.Values[i] = ec._GlobFileResult_path(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "hash": + out.Values[i] = ec._GlobFileResult_hash(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var globResultImplementors = []string{"GlobResult"} + +func (ec *executionContext) _GlobResult(ctx context.Context, sel ast.SelectionSet, obj *graph.GlobResult) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, globResultImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("GlobResult") + case "files": + out.Values[i] = ec._GlobResult_files(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ + } + case "hash": + out.Values[i] = ec._GlobResult_hash(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4858,34 +5629,43 @@ var jWTImplementors = []string{"JWT"} func (ec *executionContext) _JWT(ctx context.Context, sel ast.SelectionSet, obj *graph.Jwt) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, jWTImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("JWT") case "token": - out.Values[i] = ec._JWT_token(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "user": - out.Values[i] = ec._JWT_user(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4893,62 +5673,109 @@ var messageInfoImplementors = []string{"MessageInfo"} func (ec *executionContext) _MessageInfo(ctx context.Context, sel ast.SelectionSet, obj *graph.MessageInfo) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, messageInfoImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("MessageInfo") case "id": - out.Values[i] = ec._MessageInfo_id(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "message": - out.Values[i] = ec._MessageInfo_message(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "condition": - out.Values[i] = ec._MessageInfo_condition(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "repeat": - out.Values[i] = ec._MessageInfo_repeat(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "interrupt": - out.Values[i] = ec._MessageInfo_interrupt(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "placement": - out.Values[i] = ec._MessageInfo_placement(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var mutationImplementors = []string{"Mutation"} + +func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Mutation", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Mutation") + case "setCache": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_setCache(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4956,34 +5783,43 @@ var organizationImplementors = []string{"Organization"} func (ec *executionContext) _Organization(ctx context.Context, sel ast.SelectionSet, obj *graph.Organization) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, organizationImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Organization") case "URLname": - out.Values[i] = ec._Organization_URLname(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "role": - out.Values[i] = ec._Organization_role(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4991,34 +5827,43 @@ var processInfoImplementors = []string{"ProcessInfo"} func (ec *executionContext) _ProcessInfo(ctx context.Context, sel ast.SelectionSet, obj *graph.ProcessInfo) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, processInfoImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("ProcessInfo") case "exe": - out.Values[i] = ec._ProcessInfo_exe(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "pid": - out.Values[i] = ec._ProcessInfo_pid(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5026,34 +5871,43 @@ var projectImplementors = []string{"Project"} func (ec *executionContext) _Project(ctx context.Context, sel ast.SelectionSet, obj *graph.Project) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, projectImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Project") case "namespace": - out.Values[i] = ec._Project_namespace(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "locations": - out.Values[i] = ec._Project_locations(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5066,6 +5920,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ Object: field.Name, @@ -5078,7 +5933,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "version": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5089,16 +5944,15 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "availableUpdate": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5109,36 +5963,37 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "projects": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) } }() res = ec._Query_projects(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } return res } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "analyticsEvent": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5149,16 +6004,15 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "reportRuntimeUsage": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5169,129 +6023,187 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "checkMessages": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) } }() res = ec._Query_checkMessages(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "configChanged": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_configChanged(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "fetchLogTail": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_fetchLogTail(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } return res } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) - case "configChanged": + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "getProcessesInUse": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Query_configChanged(ctx, field) + res = ec._Query_getProcessesInUse(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } return res } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) - case "fetchLogTail": + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "getJWT": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Query_fetchLogTail(ctx, field) + res = ec._Query_getJWT(ctx, field) return res } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) - case "getProcessesInUse": + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "hashGlobs": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Query_getProcessesInUse(ctx, field) + res = ec._Query_hashGlobs(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } return res } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) - case "getJWT": + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "getCache": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Query_getJWT(ctx, field) + res = ec._Query_getCache(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } return res } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "__type": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Query___type(ctx, field) }) - case "__schema": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Query___schema(ctx, field) }) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5299,27 +6211,38 @@ var reportRuntimeUsageResponseImplementors = []string{"ReportRuntimeUsageRespons func (ec *executionContext) _ReportRuntimeUsageResponse(ctx context.Context, sel ast.SelectionSet, obj *graph.ReportRuntimeUsageResponse) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, reportRuntimeUsageResponseImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("ReportRuntimeUsageResponse") case "received": - out.Values[i] = ec._ReportRuntimeUsageResponse_received(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5327,55 +6250,58 @@ var stateVersionImplementors = []string{"StateVersion"} func (ec *executionContext) _StateVersion(ctx context.Context, sel ast.SelectionSet, obj *graph.StateVersion) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, stateVersionImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("StateVersion") case "license": - out.Values[i] = ec._StateVersion_license(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "version": - out.Values[i] = ec._StateVersion_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "channel": - out.Values[i] = ec._StateVersion_channel(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "revision": - out.Values[i] = ec._StateVersion_revision(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "date": - out.Values[i] = ec._StateVersion_date(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5383,48 +6309,53 @@ var userImplementors = []string{"User"} func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *graph.User) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, userImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("User") case "userID": - out.Values[i] = ec._User_userID(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "username": - out.Values[i] = ec._User_username(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "email": - out.Values[i] = ec._User_email(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "organizations": - out.Values[i] = ec._User_organizations(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5432,27 +6363,38 @@ var versionImplementors = []string{"Version"} func (ec *executionContext) _Version(ctx context.Context, sel ast.SelectionSet, obj *graph.Version) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, versionImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Version") case "state": - out.Values[i] = ec._Version_state(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5460,52 +6402,55 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) - case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5513,42 +6458,47 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) - case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5556,56 +6506,57 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) - case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5613,42 +6564,47 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) - case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5656,53 +6612,54 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "description": - out.Values[i] = ec.___Schema_description(ctx, field, obj) - case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) - case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) - case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5710,63 +6667,56 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) - case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) - case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) - case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) - case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) - case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) - case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) - case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) - case "specifiedByURL": - out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5789,6 +6739,74 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } +func (ec *executionContext) marshalNGlobFileResult2ᚕᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐGlobFileResultᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.GlobFileResult) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNGlobFileResult2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐGlobFileResult(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNGlobFileResult2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐGlobFileResult(ctx context.Context, sel ast.SelectionSet, v *graph.GlobFileResult) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._GlobFileResult(ctx, sel, v) +} + +func (ec *executionContext) marshalNGlobResult2githubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐGlobResult(ctx context.Context, sel ast.SelectionSet, v graph.GlobResult) graphql.Marshaler { + return ec._GlobResult(ctx, sel, &v) +} + +func (ec *executionContext) marshalNGlobResult2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐGlobResult(ctx context.Context, sel ast.SelectionSet, v *graph.GlobResult) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._GlobResult(ctx, sel, v) +} + func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v interface{}) (int, error) { res, err := graphql.UnmarshalInt(v) return res, graphql.ErrorOnPath(ctx, err) @@ -6445,6 +7463,22 @@ func (ec *executionContext) marshalOVersion2ᚖgithubᚗcomᚋActiveStateᚋcli return ec._Version(ctx, sel, v) } +func (ec *executionContext) unmarshalOVoid2ᚖgithubᚗcomᚋActiveStateᚋcliᚋcmdᚋstateᚑsvcᚋinternalᚋgraphqltypesᚐVoid(ctx context.Context, v interface{}) (*graphqltypes.Void, error) { + if v == nil { + return nil, nil + } + var res = new(graphqltypes.Void) + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOVoid2ᚖgithubᚗcomᚋActiveStateᚋcliᚋcmdᚋstateᚑsvcᚋinternalᚋgraphqltypesᚐVoid(ctx context.Context, sel ast.SelectionSet, v *graphqltypes.Void) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return v +} + func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/cmd/state-svc/internal/server/server.go b/cmd/state-svc/internal/server/server.go index 9750b77711..0a64c9d534 100644 --- a/cmd/state-svc/internal/server/server.go +++ b/cmd/state-svc/internal/server/server.go @@ -10,7 +10,6 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/handler/extension" - "github.com/99designs/gqlgen/graphql/handler/lru" "github.com/99designs/gqlgen/graphql/handler/transport" "github.com/ActiveState/cli/internal/analytics/client/sync" "github.com/ActiveState/cli/pkg/platform/authentication" @@ -111,11 +110,7 @@ func newGraphServer(r *resolver.Resolver) *handler.Server { return gqlErr }) graphServer.AddTransport(&transport.Websocket{}) - graphServer.SetQueryCache(lru.New(1000)) graphServer.Use(extension.Introspection{}) - graphServer.Use(extension.AutomaticPersistedQuery{ - Cache: lru.New(100), - }) return graphServer } diff --git a/cmd/state-svc/main.go b/cmd/state-svc/main.go index 7dbe9f7de2..0bdfb950ff 100644 --- a/cmd/state-svc/main.go +++ b/cmd/state-svc/main.go @@ -63,7 +63,7 @@ func main() { cfg, err = config.New() if err != nil { multilog.Critical("Could not initialize config: %v", errs.JoinMessage(err)) - fmt.Fprintf(os.Stderr, "Could not load config, if this problem persists please reinstall the State Tool. Error: %s\n", errs.JoinMessage(err)) + fmt.Fprintf(os.Stderr, "Could not load config. If this problem persists please reinstall the State Tool. Error: %s\n", errs.JoinMessage(err)) exitCode = 1 return } @@ -115,7 +115,7 @@ func run(cfg *config.Instance) error { return runStart(out, "svc-start:mouse") } - p := primer.New(nil, out, nil, nil, nil, nil, cfg, nil, nil, an) + p := primer.New(out, cfg, an) showVersion := false cmd := captain.NewCommand( diff --git a/cmd/state-svc/schema/schema.graphqls b/cmd/state-svc/schema/schema.graphqls index 55b8d8e8d3..2d0cb8b23d 100644 --- a/cmd/state-svc/schema/schema.graphqls +++ b/cmd/state-svc/schema/schema.graphqls @@ -77,6 +77,17 @@ type JWT { user: User! } +type GlobFileResult { + pattern: String! + path: String! + hash: String! +} + +type GlobResult { + files: [GlobFileResult!]! + hash: String! +} + type Query { version: Version availableUpdate(desiredChannel: String!, desiredVersion: String!): AvailableUpdate @@ -88,6 +99,12 @@ type Query { fetchLogTail: String! getProcessesInUse(execDir: String!): [ProcessInfo!]! getJWT: JWT + hashGlobs(wd: String!, globs: [String!]!): GlobResult! + getCache(key: String!): String! +} + +type Mutation { + setCache(key: String!, value: String!, expiry: Int!): Void } type ConfigChangedResponse { @@ -98,3 +115,5 @@ type ProcessInfo { exe: String! pid: Int! } + +scalar Void diff --git a/cmd/state-svc/test/integration/svc_int_test.go b/cmd/state-svc/test/integration/svc_int_test.go index 28d28694fc..41fcfd22e3 100644 --- a/cmd/state-svc/test/integration/svc_int_test.go +++ b/cmd/state-svc/test/integration/svc_int_test.go @@ -228,7 +228,7 @@ func (suite *SvcIntegrationTestSuite) TestAutostartConfigEnableDisable() { func (suite *SvcIntegrationTestSuite) TestLogRotation() { suite.OnlyRunForTags(tagsuite.Service) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() logDir := filepath.Join(ts.Dirs.Config, "logs") diff --git a/cmd/state/autoupdate.go b/cmd/state/autoupdate.go index 8aafd2f7bd..f6902e6427 100644 --- a/cmd/state/autoupdate.go +++ b/cmd/state/autoupdate.go @@ -2,6 +2,7 @@ package main import ( "context" + "errors" "fmt" "os" "strings" @@ -12,6 +13,7 @@ import ( "github.com/ActiveState/cli/internal/analytics" anaConst "github.com/ActiveState/cli/internal/analytics/constants" "github.com/ActiveState/cli/internal/analytics/dimensions" + "github.com/ActiveState/cli/internal/captain" "github.com/ActiveState/cli/internal/condition" "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" @@ -37,10 +39,10 @@ func init() { configMediator.RegisterOption(constants.AutoUpdateConfigKey, configMediator.Bool, !condition.IsLTS()) } -func autoUpdate(svc *model.SvcModel, args []string, cfg *config.Instance, an analytics.Dispatcher, out output.Outputer) (bool, error) { +func autoUpdate(svc *model.SvcModel, args []string, childCmd *captain.Command, cfg *config.Instance, an analytics.Dispatcher, out output.Outputer) (bool, error) { profile.Measure("autoUpdate", time.Now()) - if !shouldRunAutoUpdate(args, cfg, an) { + if !shouldRunAutoUpdate(args, childCmd, cfg, an, out) { return false, nil } @@ -72,7 +74,8 @@ func autoUpdate(svc *model.SvcModel, args []string, cfg *config.Instance, an ana err = up.InstallBlocking("") if err != nil { - if errs.Matches(err, &updater.ErrorInProgress{}) { + var errInProgress *updater.ErrorInProgress + if errors.As(err, &errInProgress) { return false, nil // ignore } if os.IsPermission(err) { @@ -86,10 +89,14 @@ func autoUpdate(svc *model.SvcModel, args []string, cfg *config.Instance, an ana code, err := relaunch(args) if err != nil { + var errStateExe *ErrStateExe + var errExecuteRelaunch *ErrExecuteRelaunch + var msg string - if errs.Matches(err, &ErrStateExe{}) { + switch { + case errors.As(err, &errStateExe): msg = anaConst.UpdateErrorExecutable - } else if errs.Matches(err, &ErrExecuteRelaunch{}) { + case errors.As(err, &errExecuteRelaunch): msg = anaConst.UpdateErrorRelaunch } an.EventWithLabel(anaConst.CatUpdates, anaConst.ActUpdateRelaunch, anaConst.UpdateLabelFailed, &dimensions.Values{ @@ -109,11 +116,23 @@ func isEnabled(cfg *config.Instance) bool { return cfg.GetBool(constants.AutoUpdateConfigKey) } -func shouldRunAutoUpdate(args []string, cfg *config.Instance, an analytics.Dispatcher) bool { +func shouldRunAutoUpdate(args []string, childCmd *captain.Command, cfg *config.Instance, an analytics.Dispatcher, out output.Outputer) bool { shouldUpdate := true label := anaConst.UpdateLabelTrue switch { + // The command explicitly skips auto update checks. + case childCmd != nil && childCmd.SkipChecks(): + logging.Debug("Not running auto update because the child command explicitly skips auto update checks") + shouldUpdate = false + label = anaConst.UpdateLabelSkipChecks + + // Running in structured-output mode. + case out.Type().IsStructured(): + logging.Debug("Not running auto update because we're running in structured output (JSON) mode") + shouldUpdate = false + label = anaConst.UpdateLabelStructuredOutput + // In a forward case os.Getenv(constants.ForwardedStateEnvVarName) == "true": logging.Debug("Not running auto updates because we're in a forward") diff --git a/cmd/state/internal/cmdtree/bundles.go b/cmd/state/internal/cmdtree/bundles.go index fcea913183..e71be1e68c 100644 --- a/cmd/state/internal/cmdtree/bundles.go +++ b/cmd/state/internal/cmdtree/bundles.go @@ -4,7 +4,9 @@ import ( "github.com/ActiveState/cli/internal/captain" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/runners/install" "github.com/ActiveState/cli/internal/runners/packages" + "github.com/ActiveState/cli/internal/runners/uninstall" "github.com/ActiveState/cli/pkg/platform/model" ) @@ -43,9 +45,8 @@ func newBundlesCommand(prime *primer.Values) *captain.Command { } func newBundleInstallCommand(prime *primer.Values) *captain.Command { - runner := packages.NewInstall(prime) - - params := packages.InstallRunParams{} + runner := install.New(prime, model.NamespaceBundle) + params := install.Params{} return captain.NewCommand( "install", @@ -61,16 +62,22 @@ func newBundleInstallCommand(prime *primer.Values) *captain.Command { Required: true, }, }, - func(_ *captain.Command, _ []string) error { - return runner.Run(params, model.NamespaceBundle) + func(_ *captain.Command, args []string) error { + for _, p := range args { + _, err := params.Packages.Add(p) + if err != nil { + return locale.WrapInputError(err, "err_install_packages_args", "Invalid install arguments") + } + } + return runner.Run(params) }, ).SetSupportsStructuredOutput() } func newBundleUninstallCommand(prime *primer.Values) *captain.Command { - runner := packages.NewUninstall(prime) + runner := uninstall.New(prime, model.NamespaceBundle) - params := packages.UninstallRunParams{} + params := uninstall.Params{} return captain.NewCommand( "uninstall", @@ -86,8 +93,13 @@ func newBundleUninstallCommand(prime *primer.Values) *captain.Command { Required: true, }, }, - func(_ *captain.Command, _ []string) error { - return runner.Run(params, model.NamespaceBundle) + func(_ *captain.Command, args []string) error { + for _, p := range args { + if _, err := params.Packages.Add(p); err != nil { + return locale.WrapInputError(err, "err_uninstall_packages_args", "Invalid package uninstall arguments") + } + } + return runner.Run(params) }, ).SetSupportsStructuredOutput() } diff --git a/cmd/state/internal/cmdtree/checkout.go b/cmd/state/internal/cmdtree/checkout.go index 39c863cc6d..e83fc6ee1c 100644 --- a/cmd/state/internal/cmdtree/checkout.go +++ b/cmd/state/internal/cmdtree/checkout.go @@ -5,13 +5,10 @@ import ( "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/runners/checkout" - "github.com/ActiveState/cli/pkg/project" ) func newCheckoutCommand(prime *primer.Values) *captain.Command { - params := &checkout.Params{ - Namespace: &project.Namespaced{AllowOmitOwner: true}, - } + params := &checkout.Params{} cmd := captain.NewCommand( "checkout", @@ -43,10 +40,10 @@ func newCheckoutCommand(prime *primer.Values) *captain.Command { }, []*captain.Argument{ { - Name: locale.Tl("arg_state_checkout_namespace", "org/project"), - Description: locale.Tl("arg_state_checkout_namespace_description", "The namespace of the project that you wish to checkout"), + Name: locale.T("arg_state_checkout_namespace"), + Description: locale.T("arg_state_checkout_namespace_description"), + Value: ¶ms.Namespace, Required: true, - Value: params.Namespace, }, { Name: locale.Tl("arg_state_checkout_path", "path"), diff --git a/cmd/state/internal/cmdtree/cmdtree.go b/cmd/state/internal/cmdtree/cmdtree.go index 955d451fc1..db47ba83c7 100644 --- a/cmd/state/internal/cmdtree/cmdtree.go +++ b/cmd/state/internal/cmdtree/cmdtree.go @@ -37,6 +37,12 @@ func New(prime *primer.Values, args ...string) *CmdTree { newOpenCommand(prime), ) + deptree := newExportDepTreeCommand(prime) + deptree.AddChildren( + newExportDepTreeArtifactsCommand(prime), + newExportDepTreeIngredientsCommand(prime), + ) + exportCmd := newExportCommand(prime) exportCmd.AddChildren( newJWTCommand(prime), @@ -48,6 +54,8 @@ func New(prime *primer.Values, args ...string) *CmdTree { newExportEnvCommand(prime), newExportLogCommand(prime), newExportRuntimeCommand(prime), + newExportBuildPlanCommand(prime), + deptree, ) platformsCmd := newPlatformsCommand(prime) @@ -213,6 +221,7 @@ func New(prime *primer.Values, args ...string) *CmdTree { newEvalCommand(prime), newManifestCommmand(prime), artifactsCmd, + newUpgradeCommand(prime), ) return &CmdTree{ diff --git a/cmd/state/internal/cmdtree/config.go b/cmd/state/internal/cmdtree/config.go index e213eca340..d09608e4e4 100644 --- a/cmd/state/internal/cmdtree/config.go +++ b/cmd/state/internal/cmdtree/config.go @@ -10,17 +10,17 @@ import ( func newConfigCommand(prime *primer.Values) *captain.Command { return captain.NewCommand( "config", - locale.Tl("config_title", "Config"), + locale.Tl("config_title", "Listing Configuration Keys and Values"), locale.Tl("config_description", "Manage the State Tool configuration"), prime, []*captain.Flag{}, []*captain.Argument{}, func(ccmd *captain.Command, _ []string) error { - runner, err := config.NewConfig(prime) + runner, err := config.NewList(prime) if err != nil { return err } - return runner.Run(ccmd.Usage) + return runner.Run() }).SetGroup(UtilsGroup).SetSupportsStructuredOutput() } diff --git a/cmd/state/internal/cmdtree/events.go b/cmd/state/internal/cmdtree/events.go index 7ffae42333..4aa8361a81 100644 --- a/cmd/state/internal/cmdtree/events.go +++ b/cmd/state/internal/cmdtree/events.go @@ -35,7 +35,7 @@ func newEventsLogCommand(prime *primer.Values) *captain.Command { { Name: "follow", Shorthand: "f", - Description: locale.Tl("tail_f_description", "Don't stop when end of file is reached, wait for additional data."), + Description: locale.Tl("tail_f_description", "Don't stop when end of file is reached. Wait for additional data."), Value: ¶ms.Follow, }, }, diff --git a/cmd/state/internal/cmdtree/exec.go b/cmd/state/internal/cmdtree/exec.go index 60a59b08c8..1b94068c39 100644 --- a/cmd/state/internal/cmdtree/exec.go +++ b/cmd/state/internal/cmdtree/exec.go @@ -27,7 +27,7 @@ func newExecCommand(prime *primer.Values, args ...string) *captain.Command { []*captain.Argument{}, func(ccmd *captain.Command, args []string) error { if len(args) > 0 && (args[0] == "-h" || args[0] == "--help") { - prime.Output().Print(ccmd.UsageText()) + prime.Output().Print(ccmd.Help()) return nil } else if len(args) > 0 && (args[0] == "-v" || args[0] == "--verbose" || args[0] == "--") { if len(args) > 1 { diff --git a/cmd/state/internal/cmdtree/export.go b/cmd/state/internal/cmdtree/export.go index d46ca3ce69..3838ad1b9c 100644 --- a/cmd/state/internal/cmdtree/export.go +++ b/cmd/state/internal/cmdtree/export.go @@ -8,8 +8,10 @@ import ( "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/runners/export" "github.com/ActiveState/cli/internal/runners/export/config" + "github.com/ActiveState/cli/internal/runners/export/deptree" "github.com/ActiveState/cli/internal/runners/export/docs" "github.com/ActiveState/cli/internal/runners/export/ghactions" + "github.com/ActiveState/cli/pkg/project" ) func newExportCommand(prime *primer.Values) *captain.Command { @@ -196,7 +198,6 @@ func newExportLogCommand(prime *primer.Values) *captain.Command { }) cmd.SetSupportsStructuredOutput() - cmd.SetUnstable(true) return cmd } @@ -228,3 +229,144 @@ func newExportRuntimeCommand(prime *primer.Values) *captain.Command { return cmd } + +func newExportBuildPlanCommand(prime *primer.Values) *captain.Command { + runner := export.NewBuildPlan(prime) + params := &export.BuildPlanParams{Namespace: &project.Namespaced{}} + + cmd := captain.NewCommand( + "buildplan", + locale.Tl("export_buildplan_title", "Exporting Build Plan"), + locale.Tl("export_buildplan_description", "Export the build plan for your project"), + prime, + []*captain.Flag{ + { + Name: "namespace", + Description: locale.Tl("export_buildplan_flags_namespace_description", "The namespace of the project to export the build plan for"), + Value: params.Namespace, + }, + { + Name: "commit", + Description: locale.Tl("export_buildplan_flags_commit_description", "The commit ID to export the build plan for"), + Value: ¶ms.CommitID, + }, + { + Name: "target", + Description: locale.Tl("export_buildplan_flags_target_description", "The target to export the build plan for"), + Value: ¶ms.Target, + }, + }, + []*captain.Argument{}, + func(_ *captain.Command, _ []string) error { + return runner.Run(params) + }, + ) + + cmd.SetSupportsStructuredOutput() + cmd.SetUnstable(true) + + return cmd +} + +func newExportDepTreeCommand(prime *primer.Values) *captain.Command { + cmd := captain.NewCommand( + "deptree", + locale.Tl("export_dep_tree_title", "Export Dependency Tree"), + locale.Tl("export_dep_tree_description", "Export the dependency tree for your project"), + prime, + []*captain.Flag{}, + []*captain.Argument{}, + func(ccmd *captain.Command, _ []string) error { + prime.Output().Print(ccmd.Help()) + return nil + }, + ) + cmd.SetHidden(true) // For development purposes only at the moment + cmd.SetUnstable(true) + return cmd +} + +func newExportDepTreeArtifactsCommand(prime *primer.Values) *captain.Command { + params := deptree.ArtifactParams{Namespace: &project.Namespaced{}} + runner := deptree.NewByArtifacts(prime) + cmd := captain.NewCommand( + "artifacts", + locale.Tl("export_dep_tree_title", "Export Dependency Tree"), + locale.Tl("export_dep_tree_description", "Export the dependency tree for your project"), + prime, + []*captain.Flag{ + { + Name: "namespace", + Description: locale.Tl("export_dep_tree_flags_namespace_description", "The namespace of the project to inspect dependencies for"), + Value: params.Namespace, + }, + { + Name: "commit", + Description: locale.Tl("export_dep_tree_flags_commit_description", "The commit ID to inspect dependencies for"), + Value: ¶ms.CommitID, + }, + { + Name: "req", + Description: locale.Tl("export_dep_tree_flag_req_description", "Requirement name to filter for"), + Value: ¶ms.Req, + }, + { + Name: "platform", + Description: locale.Tl("export_dep_tree_flag_platform_description", "Platform ID to filter for (defaults to host platform)"), + Value: ¶ms.PlatformID, + }, + { + Name: "limit", + Description: locale.Tl("export_dep_tree_flag_limit_description", "Limit the recursion level"), + Value: ¶ms.LevelLimit, + }, + }, + []*captain.Argument{}, + func(ccmd *captain.Command, _ []string) error { + return runner.Run(params) + }, + ) + cmd.SetHidden(true) // For development purposes only at the moment + cmd.SetUnstable(true) + return cmd +} + +func newExportDepTreeIngredientsCommand(prime *primer.Values) *captain.Command { + params := deptree.IngredientParams{Namespace: &project.Namespaced{}} + runner := deptree.NewByIngredients(prime) + cmd := captain.NewCommand( + "ingredients", + locale.Tl("export_dep_tree_title", "Export Dependency Tree"), + locale.Tl("export_dep_tree_description", "Export the dependency tree for your project"), + prime, + []*captain.Flag{ + { + Name: "namespace", + Description: locale.Tl("export_dep_tree_flags_namespace_description", "The namespace of the project to inspect dependencies for"), + Value: params.Namespace, + }, + { + Name: "commit", + Description: locale.Tl("export_dep_tree_flags_commit_description", "The commit ID to inspect dependencies for"), + Value: ¶ms.CommitID, + }, + { + Name: "req", + Description: locale.Tl("export_dep_tree_flag_req_description", "Requirement name to filter for"), + Value: ¶ms.Req, + }, + { + Name: "limit", + Description: locale.Tl("export_dep_tree_flag_limit_description", "Limit the recursion level"), + Value: ¶ms.LevelLimit, + }, + }, + []*captain.Argument{}, + func(ccmd *captain.Command, _ []string) error { + return runner.Run(params) + }, + ) + cmd.SetHidden(true) // For development purposes only at the moment + cmd.SetUnstable(true) + return cmd +} diff --git a/cmd/state/internal/cmdtree/languages.go b/cmd/state/internal/cmdtree/languages.go index 5adafc39b5..1c6ad1229e 100644 --- a/cmd/state/internal/cmdtree/languages.go +++ b/cmd/state/internal/cmdtree/languages.go @@ -4,7 +4,9 @@ import ( "github.com/ActiveState/cli/internal/captain" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/runners/install" "github.com/ActiveState/cli/internal/runners/languages" + "github.com/ActiveState/cli/pkg/platform/model" ) func newLanguagesCommand(prime *primer.Values) *captain.Command { @@ -24,9 +26,8 @@ func newLanguagesCommand(prime *primer.Values) *captain.Command { } func newLanguageInstallCommand(prime *primer.Values) *captain.Command { - runner := languages.NewUpdate(prime) - - params := languages.UpdateParams{} + runner := install.New(prime, model.NamespaceLanguage) + params := install.Params{} return captain.NewCommand( "install", @@ -39,11 +40,18 @@ func newLanguageInstallCommand(prime *primer.Values) *captain.Command { Name: "language", Description: locale.T("arg_languages_install_description"), Required: true, - Value: ¶ms.Language, + Value: ¶ms.Packages, }, }, - func(ccmd *captain.Command, _ []string) error { - return runner.Run(¶ms) + func(ccmd *captain.Command, args []string) error { + for _, p := range args { + pkg, err := params.Packages.Add(p) + if err != nil { + return locale.WrapInputError(err, "err_install_packages_args", "Invalid install arguments") + } + pkg.Namespace = model.NamespaceLanguage.String() + } + return runner.Run(params) }, ).SetSupportsStructuredOutput() } diff --git a/cmd/state/internal/cmdtree/manifest.go b/cmd/state/internal/cmdtree/manifest.go index 4f61330343..367dfba44c 100644 --- a/cmd/state/internal/cmdtree/manifest.go +++ b/cmd/state/internal/cmdtree/manifest.go @@ -10,15 +10,23 @@ import ( func newManifestCommmand(prime *primer.Values) *captain.Command { runner := manifest.NewManifest(prime) + params := manifest.Params{} + cmd := captain.NewCommand( "manifest", locale.Tl("manifest_title", "Listing Requirements For Your Project"), locale.Tl("manifest_cmd_description", "List the requirements of the current project"), prime, - []*captain.Flag{}, + []*captain.Flag{ + { + Name: "expand", + Description: locale.Tl("manifest_flag_expand", "Expand requirement names to include their namespace"), + Value: ¶ms.Expand, + }, + }, []*captain.Argument{}, func(_ *captain.Command, _ []string) error { - return runner.Run() + return runner.Run(params) }, ) diff --git a/cmd/state/internal/cmdtree/packages.go b/cmd/state/internal/cmdtree/packages.go index 39b66a1cb0..636dc02dc3 100644 --- a/cmd/state/internal/cmdtree/packages.go +++ b/cmd/state/internal/cmdtree/packages.go @@ -4,7 +4,9 @@ import ( "github.com/ActiveState/cli/internal/captain" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/runners/install" "github.com/ActiveState/cli/internal/runners/packages" + "github.com/ActiveState/cli/internal/runners/uninstall" "github.com/ActiveState/cli/pkg/platform/model" ) @@ -49,9 +51,9 @@ func newPackagesCommand(prime *primer.Values) *captain.Command { } func newInstallCommand(prime *primer.Values) *captain.Command { - runner := packages.NewInstall(prime) + runner := install.New(prime, model.NamespacePackage) - params := packages.InstallRunParams{} + params := install.Params{} var packagesRaw string cmd := captain.NewCommand( @@ -65,12 +67,6 @@ func newInstallCommand(prime *primer.Values) *captain.Command { Description: locale.T("package_flag_ts_description"), Value: ¶ms.Timestamp, }, - { - Name: "revision", - Shorthand: "r", - Description: locale.T("package_flag_rev_description"), - Value: ¶ms.Revision, - }, }, []*captain.Argument{ { @@ -82,11 +78,11 @@ func newInstallCommand(prime *primer.Values) *captain.Command { }, func(_ *captain.Command, args []string) error { for _, p := range args { - if err := params.Packages.Set(p); err != nil { - return locale.WrapInputError(err, "err_install_packages_args", "Invalid package install arguments") + if _, err := params.Packages.Add(p); err != nil { + return locale.WrapInputError(err, "err_install_packages_args", "Invalid install arguments") } } - return runner.Run(params, model.NamespacePackage) + return runner.Run(params) }, ) @@ -98,9 +94,9 @@ func newInstallCommand(prime *primer.Values) *captain.Command { } func newUninstallCommand(prime *primer.Values) *captain.Command { - runner := packages.NewUninstall(prime) + runner := uninstall.New(prime, model.NamespacePackage) - params := packages.UninstallRunParams{} + params := uninstall.Params{} var packagesRaw string cmd := captain.NewCommand( @@ -119,11 +115,11 @@ func newUninstallCommand(prime *primer.Values) *captain.Command { }, func(_ *captain.Command, args []string) error { for _, p := range args { - if err := params.Packages.Set(p); err != nil { + if _, err := params.Packages.Add(p); err != nil { return locale.WrapInputError(err, "err_uninstall_packages_args", "Invalid package uninstall arguments") } } - return runner.Run(params, model.NamespacePackage) + return runner.Run(params) }, ) diff --git a/cmd/state/internal/cmdtree/publish.go b/cmd/state/internal/cmdtree/publish.go index b64d683468..553ae085f8 100644 --- a/cmd/state/internal/cmdtree/publish.go +++ b/cmd/state/internal/cmdtree/publish.go @@ -70,7 +70,7 @@ func newPublish(prime *primer.Values) *captain.Command { Name: "depend", Description: locale.Tl( "author_upload_depend_description", - "Ingredient that this ingredient depends on, format as /[@]. Can be set multiple times.", + "Ingredient that this ingredient depends on. Format as /[@]. Can be set multiple times.", ), Value: ¶ms.Depends, }, @@ -78,7 +78,7 @@ func newPublish(prime *primer.Values) *captain.Command { Name: "depend-runtime", Description: locale.Tl( "author_upload_dependruntime_description", - "Ingredient that this ingredient depends on during runtime, format as /[@]. Can be set multiple times.", + "Ingredient that this ingredient depends on during runtime. Format as /[@]. Can be set multiple times.", ), Value: ¶ms.DependsRuntime, }, @@ -86,7 +86,7 @@ func newPublish(prime *primer.Values) *captain.Command { Name: "depend-build", Description: locale.Tl( "author_upload_dependbuild_description", - "Ingredient that this ingredient depends on during build, format as /[@]. Can be set multiple times.", + "Ingredient that this ingredient depends on during build. Format as /[@]. Can be set multiple times.", ), Value: ¶ms.DependsBuild, }, @@ -94,7 +94,7 @@ func newPublish(prime *primer.Values) *captain.Command { Name: "depend-test", Description: locale.Tl( "author_upload_dependtest_description", - "Ingredient that this ingredient depends on during tests, format as /[@]. Can be set multiple times.", + "Ingredient that this ingredient depends on during tests. Format as /[@]. Can be set multiple times.", ), Value: ¶ms.DependsTest, }, @@ -102,7 +102,7 @@ func newPublish(prime *primer.Values) *captain.Command { Name: "feature", Description: locale.Tl( "author_upload_feature_description", - "Feature that this ingredient provides, format as /[@]. Can be set multiple times.", + "Feature that this ingredient provides. Format as /[@]. Can be set multiple times.", ), Value: ¶ms.Features, }, diff --git a/cmd/state/internal/cmdtree/run.go b/cmd/state/internal/cmdtree/run.go index 8557296058..b1a0986b2b 100644 --- a/cmd/state/internal/cmdtree/run.go +++ b/cmd/state/internal/cmdtree/run.go @@ -28,7 +28,7 @@ func newRunCommand(prime *primer.Values) *captain.Command { }, func(ccmd *captain.Command, args []string) error { if name == "-h" || name == "--help" { - prime.Output().Print(ccmd.UsageText()) + prime.Output().Print(ccmd.Help()) return nil } else if name == "-v" || name == "--verbose" { if len(args) > 1 { diff --git a/cmd/state/internal/cmdtree/test.go b/cmd/state/internal/cmdtree/test.go index 46b2595ba6..b1a02006b0 100644 --- a/cmd/state/internal/cmdtree/test.go +++ b/cmd/state/internal/cmdtree/test.go @@ -20,22 +20,40 @@ func newTestCommand(prime *primer.Values) *captain.Command { return nil }, ) - cmd.AddChildren(captain.NewCommand( - "multierror", - "", - "For testing purposes only", - prime, - nil, - nil, - func(ccmd *captain.Command, _ []string) error { - return errs.Pack( - locale.NewInputError("error1"), - errs.Wrap(locale.NewInputError("error2"), "false error1"), - locale.WrapInputError(errs.New("false error2"), "error3"), - locale.NewInputError("error4"), - ) - }, - )) + cmd.AddChildren( + captain.NewCommand( + "multierror-input", + "", + "For testing purposes only", + prime, + nil, + nil, + func(ccmd *captain.Command, _ []string) error { + return errs.Pack( + locale.NewInputError("error1"), + errs.Wrap(locale.NewInputError("error2"), "false error1"), + locale.WrapInputError(errs.New("false error2"), "error3"), + locale.NewInputError("error4"), + ) + }, + ), + captain.NewCommand( + "multierror-noinput", + "", + "For testing purposes only", + prime, + nil, + nil, + func(ccmd *captain.Command, _ []string) error { + return errs.Pack( + locale.NewError("error1"), + errs.Wrap(locale.NewError("error2"), "false error1"), + locale.WrapError(errs.New("false error2"), "error3"), + locale.NewError("error4"), + ) + }, + ), + ) cmd.SetHidden(true) return cmd } diff --git a/cmd/state/internal/cmdtree/update.go b/cmd/state/internal/cmdtree/update.go index 1e82a8b7cd..a027d6dbe6 100644 --- a/cmd/state/internal/cmdtree/update.go +++ b/cmd/state/internal/cmdtree/update.go @@ -41,7 +41,7 @@ func newUpdateLockCommand(prime *primer.Values, globals *globalOptions) *captain cmd := captain.NewCommand( "lock", locale.Tl("lock_title", "Lock the State Tool version"), - locale.Tl("lock_description", "Lock the State Tool at the current version, this disables automatic updates."), + locale.Tl("lock_description", "Lock the State Tool at the current version. This disables automatic updates."), prime, []*captain.Flag{ { diff --git a/cmd/state/internal/cmdtree/upgrade.go b/cmd/state/internal/cmdtree/upgrade.go new file mode 100644 index 0000000000..18019f5f3b --- /dev/null +++ b/cmd/state/internal/cmdtree/upgrade.go @@ -0,0 +1,43 @@ +package cmdtree + +import ( + "github.com/ActiveState/cli/internal/captain" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/runners/upgrade" +) + +func newUpgradeCommand(prime *primer.Values) *captain.Command { + runner := upgrade.New(prime) + + params := upgrade.NewParams() + + cmd := captain.NewCommand( + "upgrade", + locale.Tl("upgrade_cmd_title", "Upgrading Project"), + locale.Tl("upgrade_cmd_description", "Upgrade dependencies of a project"), + prime, + []*captain.Flag{ + { + Name: "ts", + Description: locale.T("flag_state_upgrade_ts_description"), + Value: ¶ms.Timestamp, + }, + { + Name: "expand", + Description: locale.T("flag_state_upgrade_expand_description"), + Value: ¶ms.Expand, + }, + }, + []*captain.Argument{}, + func(_ *captain.Command, _ []string) error { + return runner.Run(params) + }, + ) + + cmd.SetGroup(PackagesGroup) + cmd.SetSupportsStructuredOutput() + cmd.SetUnstable(true) + + return cmd +} diff --git a/cmd/state/main.go b/cmd/state/main.go index fa86cf98f3..84ae4a16fb 100644 --- a/cmd/state/main.go +++ b/cmd/state/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "errors" "fmt" "os" "runtime/debug" @@ -32,7 +33,7 @@ import ( _ "github.com/ActiveState/cli/internal/prompt" // Sets up survey defaults "github.com/ActiveState/cli/internal/rollbar" "github.com/ActiveState/cli/internal/rtutils" - "github.com/ActiveState/cli/internal/runbits/errors" + runbits_errors "github.com/ActiveState/cli/internal/runbits/errors" "github.com/ActiveState/cli/internal/runbits/panics" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/svcctl" @@ -78,8 +79,14 @@ func main() { var err error cfg, err = config.New() if err != nil { - multilog.Critical("Could not initialize config: %v", errs.JoinMessage(err)) - fmt.Fprintf(os.Stderr, "Could not load config, if this problem persists please reinstall the State Tool. Error: %s\n", errs.JoinMessage(err)) + if !locale.IsInputError(err) { + multilog.Critical("Could not initialize config: %v", errs.JoinMessage(err)) + fmt.Fprintf(os.Stderr, "Could not load config, if this problem persists please reinstall the State Tool. Error: %s\n", errs.JoinMessage(err)) + } else { + for _, err2 := range locale.UnpackError(err) { + fmt.Fprintf(os.Stderr, err2.Error()) + } + } exitCode = 1 return } @@ -107,7 +114,7 @@ func main() { // Run our main command logic, which is logic that defers to the error handling logic below err = run(os.Args, isInteractive, cfg, out) if err != nil { - exitCode, err = errors.ParseUserFacing(err) + exitCode, err = runbits_errors.ParseUserFacing(err) if err != nil { out.Error(err) } @@ -178,14 +185,15 @@ func run(args []string, isInteractive bool, cfg *config.Instance, out output.Out } } - projectfile.RegisterMigrator(migrator.NewMigrator(auth, cfg)) + projectfile.RegisterMigrator(migrator.NewMigrator(auth, cfg, svcmodel)) // Retrieve project file if os.Getenv("ACTIVESTATE_PROJECT") != "" { out.Notice(locale.T("warning_activestate_project_env_var")) } pjPath, err := projectfile.GetProjectFilePath() - if err != nil && errs.Matches(err, &projectfile.ErrorNoProjectFromEnv{}) { + var errNoProjectFromEnv *projectfile.ErrorNoProjectFromEnv + if err != nil && errors.As(err, &errNoProjectFromEnv) { // Fail if we are meant to inherit the projectfile from the environment, but the file doesn't exist return err } @@ -234,7 +242,7 @@ func run(args []string, isInteractive bool, cfg *config.Instance, out output.Out // Run the actual command cmds := cmdtree.New(primer.New(pj, out, auth, prompter, sshell, conditional, cfg, ipcClient, svcmodel, an), args...) - childCmd, err := cmds.Command().Find(args[1:]) + childCmd, err := cmds.Command().FindChild(args[1:]) if err != nil { logging.Debug("Could not find child command, error: %v", err) } @@ -243,23 +251,22 @@ func run(args []string, isInteractive bool, cfg *config.Instance, out output.Out cmds.OnExecStart(msger.OnExecStart) cmds.OnExecStop(msger.OnExecStop) - if childCmd != nil && !childCmd.SkipChecks() && !out.Type().IsStructured() { - // Auto update to latest state tool version - if updated, err := autoUpdate(svcmodel, args, cfg, an, out); err == nil && updated { - return nil // command will be run by updated exe - } else if err != nil { - multilog.Error("Failed to autoupdate: %v", err) - } + // Auto update to latest state tool version if possible. + if updated, err := autoUpdate(svcmodel, args, childCmd, cfg, an, out); err == nil && updated { + return nil // command will be run by updated exe + } else if err != nil { + multilog.Error("Failed to autoupdate: %v", err) + } - if childCmd.Name() != "update" && pj != nil && pj.IsLocked() { - if (pj.Version() != "" && pj.Version() != constants.Version) || - (pj.Channel() != "" && pj.Channel() != constants.ChannelName) { - return errs.AddTips( - locale.NewInputError("lock_version_mismatch", "", pj.Source().Lock, constants.ChannelName, constants.Version), - locale.Tr("lock_update_legacy_version", constants.DocumentationURLLocking), - locale.T("lock_update_lock"), - ) - } + // Check to see if this state tool version is different from the lock version. + if (childCmd == nil || !childCmd.SkipChecks()) && pj != nil && pj.IsLocked() { + if (pj.Version() != "" && pj.Version() != constants.Version) || + (pj.Channel() != "" && pj.Channel() != constants.ChannelName) { + return errs.AddTips( + locale.NewInputError("lock_version_mismatch", "", pj.Source().Lock, constants.ChannelName, constants.Version), + locale.Tr("lock_update_legacy_version", constants.DocumentationURLLocking), + locale.T("lock_update_lock"), + ) } } @@ -272,7 +279,7 @@ func run(args []string, isInteractive bool, cfg *config.Instance, out output.Out if !out.Type().IsStructured() { err = errs.AddTips(err, locale.Tl("err_tip_run_help", "Run → '[ACTIONABLE]state {{.V0}}--help[/RESET]' for general help", cmdName)) } - errors.ReportError(err, cmds.Command(), an) + runbits_errors.ReportError(err, cmds.Command(), an) } return err diff --git a/go.mod b/go.mod index 1ec1e68490..fbe81cfbf2 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/ActiveState/cli -go 1.22 +go 1.22.5 -replace cloud.google.com/go => cloud.google.com/go v0.110.0 +toolchain go1.23.1 require ( - github.com/99designs/gqlgen v0.17.19 + github.com/99designs/gqlgen v0.17.54 github.com/ActiveState/go-ogle-analytics v0.0.0-20170510030904-9b3f14901527 - github.com/ActiveState/termtest v0.7.3-0.20240522153407-fcd066736664 + github.com/ActiveState/termtest v0.7.3-0.20240703202616-34f7899287a4 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 github.com/alecthomas/participle/v2 v2.0.0 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 @@ -16,8 +16,7 @@ require ( github.com/blang/semver v3.5.1+incompatible github.com/creack/pty v1.1.11 github.com/dave/jennifer v0.18.0 - github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 - github.com/fatih/color v1.10.0 + github.com/fatih/color v1.16.0 github.com/felixge/fgprof v0.9.0 github.com/fsnotify/fsnotify v1.4.7 github.com/gammazero/workerpool v1.1.1 @@ -29,10 +28,10 @@ require ( github.com/go-openapi/validate v0.20.2 github.com/gofrs/flock v0.8.1 github.com/google/go-github/v45 v45.0.0 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.0 - github.com/hashicorp/go-cleanhttp v0.5.1 - github.com/hashicorp/go-retryablehttp v0.6.7 + github.com/hashicorp/go-cleanhttp v0.5.2 + github.com/hashicorp/go-retryablehttp v0.7.7 github.com/hashicorp/go-version v1.1.0 github.com/hpcloud/tail v1.0.0 github.com/imdario/mergo v0.3.11 @@ -57,13 +56,12 @@ require ( github.com/stretchr/testify v1.9.0 github.com/thoas/go-funk v0.8.0 github.com/vbauerster/mpb/v7 v7.1.5 - github.com/vektah/gqlparser/v2 v2.5.1 - go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/net v0.25.0 - golang.org/x/sys v0.20.0 - golang.org/x/term v0.20.0 - golang.org/x/text v0.15.0 + github.com/vektah/gqlparser/v2 v2.5.16 + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/net v0.29.0 + golang.org/x/sys v0.25.0 + golang.org/x/term v0.24.0 + golang.org/x/text v0.18.0 gopkg.in/AlecAivazis/survey.v1 v1.8.8 gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 gopkg.in/yaml.v2 v2.4.0 @@ -72,11 +70,14 @@ require ( require ( github.com/ActiveState/graphql v0.0.0-20230719154233-6949037a6e48 + github.com/bmatcuk/doublestar/v4 v4.7.1 + github.com/brunoga/deep v1.2.4 + github.com/cespare/xxhash v1.1.0 github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.25.0 github.com/charmbracelet/lipgloss v0.9.1 github.com/go-git/go-git/v5 v5.12.0 - github.com/imacks/bitflags-go v1.0.0 + github.com/gowebpki/jcs v1.0.1 github.com/klauspost/compress v1.11.4 github.com/mholt/archiver/v3 v3.5.1 github.com/zijiren233/yaml-comment v0.2.1 @@ -95,6 +96,7 @@ require ( 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/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 // indirect github.com/klauspost/pgzip v1.2.5 // indirect github.com/kr/pty v1.1.8 // indirect @@ -109,11 +111,12 @@ require ( github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/skeema/knownhosts v1.2.2 // indirect - golang.org/x/sync v0.3.0 // indirect + github.com/sosodev/duration v1.3.1 // indirect + golang.org/x/sync v0.8.0 // indirect ) require ( - github.com/BurntSushi/toml v1.2.1 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect github.com/Netflix/go-expect v0.0.0-20201125194554-85d881c3777e // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect @@ -137,18 +140,17 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/labstack/gommon v0.3.1 // indirect + github.com/labstack/gommon v0.3.1 github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matryer/is v1.2.0 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.7 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -174,9 +176,9 @@ require ( github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.mongodb.org/mongo-driver v1.5.3 // indirect - golang.org/x/mod v0.12.0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/time v0.1.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.25.0 // indirect gopkg.in/fsnotify.v1 v1.4.7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index d3d50b2ec3..b53eb36707 100644 --- a/go.sum +++ b/go.sum @@ -1,361 +1,34 @@ -cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= -cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= -cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= -cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= -cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= -cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= -cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= -cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= -cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= -cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= -cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= -cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= -cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= -cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= -cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= -cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= -cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= -cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= -cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= -cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= -cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= -cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= -cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= -cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= -cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= -cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= -cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= -cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= -cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= -cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= -cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= -cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= -cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= -cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= -cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= -cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= -cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= -cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= -cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= -cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= -cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= -cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= -cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= -cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= -cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= -cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= -cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= -cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= -cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= -cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= -cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= -cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= -cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= -cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= -cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= -cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= -cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= -cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= -cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= -cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= -cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= -cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= -cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= -cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= -cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= -cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= -cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= -cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= -cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= -cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= -cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= -cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= -cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= -cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= -cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= -cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= -cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= -cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= -cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= -cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= -cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= -cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= -cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= -cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= -cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= -cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= -cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= -cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= -cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= -cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= -cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= -cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= -cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= -cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= -cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= -cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= -cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= -cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= -cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= -cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= -cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= -cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= -cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= -cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= -cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= -cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= -cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= -cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= -cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= -cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= -cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= -cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= -cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= -cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= -cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= -cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= -cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= -cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= -cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= -cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= -cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= -cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= -cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= -cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= -cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= -cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= -cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= -cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= -cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= -cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= -cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= -cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= -cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= -cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= -cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= -cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= -cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= -cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= -cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= -cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= -cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= -cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= -cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= -cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= -cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= -cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= -cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= -cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= -cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= -cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= -cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= -cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= -cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= -cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= -cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= -cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= -cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= -cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= -cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= -cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= -cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= -cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= -cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= -cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= -cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= -cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= -cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= -cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= -cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= -cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= -cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= -cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= -cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= -cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= -cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= -cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= -cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= -cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= -cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= -cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= -cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= -cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= -cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= -cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= -cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= -cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= -cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= -cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= -cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= -cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= -cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= -cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= -cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= -cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= -cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= -cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= -cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= -cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= -cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= -cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= -cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= -cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= -cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= -cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= -cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= -cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= -cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= -cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= -cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= -cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= -cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= -cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= -cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= -cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= -cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= -cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= -cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= -cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= -cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= -cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= -cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= -cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= -cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= -cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= -cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= -cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= -cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= -cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= -cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= -cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= -cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= -cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= -cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= -cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= -cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= -cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= -cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= -cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= -cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= -cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= -cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= -cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/99designs/gqlgen v0.17.19 h1:lO3PBSOv5Mw8RPt0Nwg7ovJ9tNfjGDEnU48AYqLzBVA= -github.com/99designs/gqlgen v0.17.19/go.mod h1:tXjo2/o1L/9A8S/4nLK7Arx/677H8hxlD/iSTRx0BtE= +github.com/99designs/gqlgen v0.17.54 h1:AsF49k/7RJlwA00RQYsYN0T8cQuaosnV/7G1dHC3Uh8= +github.com/99designs/gqlgen v0.17.54/go.mod h1:77/+pVe6zlTsz++oUg2m8VLgzdUPHxjoAG3BxI5y8Rc= github.com/ActiveState/go-ogle-analytics v0.0.0-20170510030904-9b3f14901527 h1:lW+qgVXf/iAnSs8SgagWxh8d6nsbpmwyhmeg9/fp0Os= github.com/ActiveState/go-ogle-analytics v0.0.0-20170510030904-9b3f14901527/go.mod h1:/9SyzKLlJSuIa7WAsLUUhHqTK9+PtZD8cKF8G4SLpa0= github.com/ActiveState/graphql v0.0.0-20230719154233-6949037a6e48 h1:UCx/ObpVRgC4fp2OlJM2iNdMMu+K87/aPxKrQ1WRLj4= github.com/ActiveState/graphql v0.0.0-20230719154233-6949037a6e48/go.mod h1:NhUbNQ8UpfnC6nZvZ8oThqYSCE/G8FQp9JUrK9jXJs0= github.com/ActiveState/pty v0.0.0-20230628221854-6fb90eb08a14 h1:RdhhSiwmgyUaaF2GBNrbqTwE5SM+MaVjwf91Ua+CK8c= github.com/ActiveState/pty v0.0.0-20230628221854-6fb90eb08a14/go.mod h1:5mM6vNRQwshCjlkOnVpwC//4ZpkiC6nmZr8lPOxJdXs= -github.com/ActiveState/termtest v0.7.3-0.20240522153407-fcd066736664 h1:0W+6cvjhkhF7AtCQJDGooMpOhDF4wqZpZyO2loIqtgY= -github.com/ActiveState/termtest v0.7.3-0.20240522153407-fcd066736664/go.mod h1:RyWp2NaaTrVAa+XjMHpKAqwBFWbL6wE12HQxiZNGAqU= +github.com/ActiveState/termtest v0.7.3-0.20240703202616-34f7899287a4 h1:aYm+l6fT6sg+xEfO2+uSt0UJqw7WECwwqvSR7zaL/yI= +github.com/ActiveState/termtest v0.7.3-0.20240703202616-34f7899287a4/go.mod h1:RyWp2NaaTrVAa+XjMHpKAqwBFWbL6wE12HQxiZNGAqU= github.com/AlecAivazis/survey/v2 v2.0.5/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -363,9 +36,12 @@ github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5 github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= github.com/Netflix/go-expect v0.0.0-20201125194554-85d881c3777e h1:YYUPbL3iB9+Y/JYEXjCi9AolqiKIIJX/2aRR9TuKD6w= github.com/Netflix/go-expect v0.0.0-20201125194554-85d881c3777e/go.mod h1:68ORG0HSEWDuH5Eh73AFbYWZ1zT4Y+b0vhOa+vZRUdI= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/PuerkitoBio/goquery v1.9.3 h1:mpJr/ikUA9/GNJB/DBZcGeFDXUtosHRyRrwh7KGdTG0= +github.com/PuerkitoBio/goquery v1.9.3/go.mod h1:1ndLHPdTz+DyQPICCWYlYQMPl0oXZj0G6D4LCYA6u4U= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -392,11 +68,12 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= +github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= github.com/andygrunwald/go-jira v1.15.1 h1:6J9aYKb9sW8bxv3pBLYBrs0wdsFrmGI5IeTgWSKWKc8= github.com/andygrunwald/go-jira v1.15.1/go.mod h1:GIYN1sHOIsENWUZ7B4pDeT/nxEtrZpE8l0987O67ZR8= 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/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -422,13 +99,13 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q= +github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/brunoga/deep v1.2.4 h1:Aj9E9oUbE+ccbyh35VC/NHlzzjfIVU69BXu2mt2LmL8= +github.com/brunoga/deep v1.2.4/go.mod h1:GDV6dnXqn80ezsLSZ5Wlv1PdKAWAO4L5PnKYtv2dgaI= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= @@ -442,18 +119,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -462,7 +127,6 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= @@ -490,24 +154,9 @@ github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcej 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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= -github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= -github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3/go.mod h1:VEPNJUlxl5KdWjDvz6Q1l+rJlxF2i6xqDeGuGAxa87M= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/fgprof v0.9.0 h1:1Unx04fyC3gn3RMH/GuwUF1UdlulLMpJV13jr9SOHvs= @@ -667,102 +316,69 @@ github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzq github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v45 v45.0.0 h1:LU0WBjYidxIVyx7PZeWb+FP4JZJ3Wh3FQgdumnGqiLs= github.com/google/go-github/v45 v45.0.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200615235658-03e1cf38a040/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gowebpki/jcs v1.0.1 h1:Qjzg8EOkrOTuWP7DqQ1FbYtcpEbeTzUoTN9bptp8FOU= +github.com/gowebpki/jcs v1.0.1/go.mod h1:CID1cNZ+sHp1CCpAR8mPf6QRtagFBgPJE0FCUQ6+BrI= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.6.7 h1:8/CAEZt/+F7kR7GevNHulKkUjLht3CPmn7egmhieNKo= -github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= @@ -773,8 +389,8 @@ github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= @@ -787,10 +403,7 @@ github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 h1:AgcIVYPa6XJnU3phs github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imacks/bitflags-go v1.0.0 h1:RdMiuY/FcAvuKNfGOO1BmlFcGybrUkxnywPHcjcNg+Y= -github.com/imacks/bitflags-go v1.0.0/go.mod h1:/YBJXL0V6B9tSsHJb1mkqBBervbLfyKPgsfKxaCSz1E= github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -810,6 +423,7 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d h1:cVtBfNW5XTHiKQe7jDaDBSh/EVM4XLPutLAGboIXuM0= @@ -820,7 +434,6 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= 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/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -833,7 +446,6 @@ github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -850,13 +462,10 @@ github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITV github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= -github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -874,19 +483,18 @@ github.com/mash/go-tempfile-suffix v0.0.0-20150731093933-48f0f8a3a5ab h1:2lWb5W+ github.com/mash/go-tempfile-suffix v0.0.0-20150731093933-48f0f8a3a5ab/go.mod h1:oBJAJTenVXse2frk3J4anZ7funxla2ZdJHFQShkD43k= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= -github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +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.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= @@ -911,7 +519,6 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -962,8 +569,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -975,8 +580,6 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -989,7 +592,6 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg= github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -998,17 +600,13 @@ github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUz github.com/rollbar/rollbar-go v1.1.0 h1:3ysiHp3ep8W50ykgBMCKXJGaK2Jdivru7SW9EYfAo+M= github.com/rollbar/rollbar-go v1.1.0/go.mod h1:AcFs5f0I+c71bpHlXNNDbOWJiKwjFDtISeXco0L5PKQ= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= -github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= -github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -1028,11 +626,11 @@ github.com/skratchdot/open-golang v0.0.0-20190104022628-a2dfa6d0dab6/go.mod h1:s github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= +github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -1046,21 +644,14 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= @@ -1079,7 +670,6 @@ github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oW github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= @@ -1087,8 +677,8 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+ github.com/vbauerster/mpb/v7 v7.1.5 h1:vtUEUfQHmNeJETyF4AcRCOV6RC4wqFwNORy52UMXPbQ= github.com/vbauerster/mpb/v7 v7.1.5/go.mod h1:4M8+qAoQqV60WDNktBM5k05i1iTrXE7rjKOHEVkVlec= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= -github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUOHcr4= -github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= +github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= +github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= 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/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= @@ -1099,14 +689,9 @@ github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHM github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zijiren233/yaml-comment v0.2.1 h1:/ymMfauuR6zPme+c59FvGNmvxmjOS+BRZSU9YEM82g4= @@ -1122,14 +707,8 @@ go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4S go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.5.3 h1:wWbFB6zaGHpzguF3f7tW94sVE8sFl3lHx8OZx/4OuFI= go.mongodb.org/mongo-driver v1.5.3/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= -go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak= -go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= @@ -1145,43 +724,38 @@ golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/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.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1194,67 +768,33 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= 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.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1263,14 +803,10 @@ golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/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.0.0-20220929204114-8fcdb60fdcc0/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/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1296,84 +832,57 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/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-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/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-20220721230656-c6bc011c0c49/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-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/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.4.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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= 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.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.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.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1383,187 +892,55 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= 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/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= -google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= -google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= -google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= -google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= -google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= -google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/AlecAivazis/survey.v1 v1.8.8 h1:5UtTowJZTz1j7NxVzDGKTz6Lm9IWm8DDF6b7a2wq9VY= gopkg.in/AlecAivazis/survey.v1 v1.8.8/go.mod h1:CaHjv79TCgAvXMSFJSVgonHXYWxnhzI3eoHtnX5UgUo= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1588,7 +965,6 @@ gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1601,8 +977,9 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU= @@ -1635,3 +1012,4 @@ modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.0.1 h1:WyIDpEpAIx4Hel6q/Pcgj/VhaQV5XPJ2I6ryIYbjnpc= modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/installers/install.ps1 b/installers/install.ps1 index ae30d9a78a..3c8dceda26 100644 --- a/installers/install.ps1 +++ b/installers/install.ps1 @@ -147,6 +147,26 @@ function error([string] $msg) Write-Host $msg -ForegroundColor Red } +function setShellOverride +{ + # Walk up the process tree to find cmd.exe + # If we encounter it we set the shell override + $currentPid = $PID + while ($currentPid -ne 0) + { + $process = Get-WmiObject Win32_Process | Where-Object { $_.ProcessId -eq $currentPid } + if (!$process) { break } + + if ($process.Name -eq "cmd" -or $process.Name -eq "cmd.exe") + { + [System.Environment]::SetEnvironmentVariable("ACTIVESTATE_CLI_SHELL_OVERRIDE", $process.Name, "Process") + break + } + + $currentPid = $process.ParentProcessId + } +} + $version = $script:VERSION if (!$version) { # If the user did not specify a version, formulate a query to fetch the JSON info of the latest @@ -248,6 +268,7 @@ $PSDefaultParameterValues['*:Encoding'] = 'utf8' # Run the installer. $env:ACTIVESTATE_SESSION_TOKEN = $script:SESSION_TOKEN_VALUE +setShellOverride & $exePath $args --source-installer="install.ps1" $success = $? if (Test-Path env:ACTIVESTATE_SESSION_TOKEN) diff --git a/internal/analytics/constants/constants.go b/internal/analytics/constants/constants.go index e3f53ac4d2..3c28b4e8f3 100644 --- a/internal/analytics/constants/constants.go +++ b/internal/analytics/constants/constants.go @@ -70,6 +70,18 @@ const ActRuntimeBuild = "build" // ActRuntimeDownload is the event action sent before starting the download of artifacts for a runtime const ActRuntimeDownload = "download" +// ActRuntimeUnpack is the event action sent before starting the unpack of artifacts for a runtime +const ActRuntimeUnpack = "unpack" + +// ActRuntimeInstall is the event action sent before starting the install of artifacts for a runtime +const ActRuntimeInstall = "install" + +// ActRuntimeUninstall is the event action sent before starting the uninstall of artifacts for a runtime +const ActRuntimeUninstall = "uninstall" + +// ActRuntimePostprocess is the event action sent before starting the postprocess of artifacts for a runtime +const ActRuntimePostprocess = "postprocess" + // ActRuntimeSuccess is the event action sent when a runtime's environment has been successfully computed (for the first time) const ActRuntimeSuccess = "success" @@ -148,39 +160,47 @@ const ActCommandInputError = "command-input-error" // ActExecutorExit is the event action used for executor exit codes const ActExecutorExit = "executor-exit" -// UpdateLabelSuccess is the sent if an auto-update was successful +// UpdateLabelSuccess is sent if an auto-update was successful const UpdateLabelSuccess = "success" -// UpdateLabelFailed is the sent if an auto-update failed +// UpdateLabelFailed is sent if an auto-update failed const UpdateLabelFailed = "failure" -// UpdateLabelTrue is the sent if we should auto-update +// UpdateLabelTrue is sent if we should auto-update const UpdateLabelTrue = "true" -// UpdateLabelForward is the sent if we should not auto-update as we are forwarding a command +// UpdateLabelForward is sent if we should not auto-update as we are forwarding a command const UpdateLabelForward = "forward" -// UpdateLabelUnitTest is the sent if we should not auto-update as we are running unit tests +// UpdateLabelUnitTest is sent if we should not auto-update as we are running unit tests const UpdateLabelUnitTest = "unittest" -// UpdateLabelConflict is the sent if we should not auto-update as the current command might conflict +// UpdateLabelConflict is sent if we should not auto-update as the current command might conflict const UpdateLabelConflict = "conflict" -// UpdateLabelDisabledEnv is the sent if we should not auto-update as the user has disabled auto-updates via the environment +// UpdateLabelDisabledEnv is sent if we should not auto-update as the user has disabled auto-updates via the environment const UpdateLabelDisabledEnv = "disabled-env" -// UpdateLabelDisabledConfig is the sent if we should not auto-update as the user has disabled auto-updates via the config +// UpdateLabelDisabledConfig is sent if we should not auto-update as the user has disabled auto-updates via the config const UpdateLabelDisabledConfig = "disabled-config" -// AutoUpdateLabelDisabledCI is the sent if we should not auto-update as we are on CI +// AutoUpdateLabelDisabledCI is sent if we should not auto-update as we are on CI const UpdateLabelCI = "ci" -// UpdateLabelFreshInstall is the sent if we should not auto-update as we are on a fresh install +// UpdateLabelFreshInstall is sent if we should not auto-update as we are on a fresh install const UpdateLabelFreshInstall = "fresh-install" -// UpdateLabelLocked is the sent if we should not auto-update as the state tool is locked +// UpdateLabelLocked is sent if we should not auto-update as the state tool is locked const UpdateLabelLocked = "locked" +// UpdateLabelSkipChecks is sent if we should not auto-update because the command explicitly skips +// auto update checks. +const UpdateLabelSkipChecks = "skip-checks" + +// UpdateLabelStructuredOutput is sent if we should not auto-update because we're running in +// structured output (JSON) mode. +const UpdateLabelStructuredOutput = "structured-output" + // UpdateLabelTooFreq is the sent if we should not auto-update as the last check was too recent const UpdateLabelTooFreq = "too-frequent" diff --git a/internal/archiver/archiver.go b/internal/archiver/archiver.go new file mode 100644 index 0000000000..e8ece29276 --- /dev/null +++ b/internal/archiver/archiver.go @@ -0,0 +1,75 @@ +package archiver + +import ( + "os" + "path/filepath" + "strings" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/mholt/archiver/v3" +) + +type FileMap struct { + Source string + Target string // Note: Target paths should always be relative to the archive root, do not use absolute paths +} + +func CreateTgz(archivePath string, workDir string, fileMaps []FileMap) error { + f, err := os.OpenFile(archivePath, os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return errs.Wrap(err, "Could not create temp file") + } + defer f.Close() + tgz := archiver.NewTarGz() + if err := tgz.Create(f); err != nil { + return errs.Wrap(err, "Could not create tar.gz") + } + defer tgz.Close() + + for _, fileMap := range fileMaps { + source := fileMap.Source + if !filepath.IsAbs(source) { + // Ensure the source path is absolute, because otherwise it will use the global working directory which + // we're not interested in. + source = filepath.Join(workDir, source) + } + file, err := os.Open(source) + if err != nil { + return errs.Wrap(err, "Could not open file") + } + + fileInfo, err := file.Stat() + if err != nil { + return errs.Wrap(err, "Could not stat file") + } + + // write it to the archive + err = tgz.Write(archiver.File{ + FileInfo: archiver.FileInfo{ + FileInfo: fileInfo, + CustomName: fileMap.Target, + }, + ReadCloser: file, + }) + file.Close() + if err != nil { + return errs.Wrap(err, "Could not write file to tar.gz") + } + } + + return nil +} + +func FilesWithCommonParent(filepaths ...string) []FileMap { + var fileMaps []FileMap + common := fileutils.CommonParentPath(filepaths) + for _, path := range filepaths { + path = filepath.ToSlash(path) + fileMaps = append(fileMaps, FileMap{ + Source: path, + Target: strings.TrimPrefix(strings.TrimPrefix(path, common), "/"), + }) + } + return fileMaps +} diff --git a/internal/assets/contents/activestate.yaml.perl.tpl b/internal/assets/contents/activestate.yaml.perl.tpl index fa4514299e..0fa716f4d2 100644 --- a/internal/assets/contents/activestate.yaml.perl.tpl +++ b/internal/assets/contents/activestate.yaml.perl.tpl @@ -34,7 +34,7 @@ scripts: my (%entries) = @_; while ((my $from, my $to) = each(%entries)) { if ($ARGV[0] eq $from) { - printf("Shimming command to 'state %s', to configure this shim edit the following file:\n${project.path()}/activestate.yaml\n\n", $to); + printf("Shimming command to 'state %s'. To configure this shim, edit the following file:\n${project.path()}/activestate.yaml\n\n", $to); system("state", $to, @ARGV[1 .. $#ARGV]); exit($?); } diff --git a/internal/assets/contents/scripts/removePaths.bat b/internal/assets/contents/scripts/removePaths.bat index f3d4683ef3..99889b4c2b 100644 --- a/internal/assets/contents/scripts/removePaths.bat +++ b/internal/assets/contents/scripts/removePaths.bat @@ -32,17 +32,19 @@ echo "Waiting for process %exe% with PID %pid% to end..." >> %logfile% echo "Process %exe% has ended" >> %logfile% set success=true for %%i in (%paths%) do ( - echo "Attempting to remove path %%i" >> %logfile% - if exist "%%i\" ( - rmdir /s /q %%i 2>>&1 >> %logfile% - ) else if exist "%%i" ( - del /f /q %%i 2>>&1 >> %logfile% - ) - if exist "%%i" ( - echo "Could not remove path: %%i" >> %logfile% - set success=false - ) else ( - echo "Successfully removed path %%i" >> %logfile% + if "%success%"=="true" ( + echo "Attempting to remove path %%i" >> %logfile% + if exist "%%i\" ( + rmdir /s /q %%i 2>>&1 >> %logfile% + ) else if exist "%%i" ( + del /f /q %%i 2>>&1 >> %logfile% + ) + if exist "%%i" ( + echo "Could not remove path: %%i" >> %logfile% + set success=false + ) else ( + echo "Successfully removed path %%i" >> %logfile% + ) ) ) diff --git a/internal/assets/contents/shells/bashrc.sh b/internal/assets/contents/shells/bashrc.sh index 0f3094cbba..c632d14b1d 100644 --- a/internal/assets/contents/shells/bashrc.sh +++ b/internal/assets/contents/shells/bashrc.sh @@ -1,9 +1,5 @@ if [ -f ~/.bashrc ]; then source ~/.bashrc; fi -{{if and (ne .Owner "") (not .PreservePs1) }} -export PS1="[{{.Owner}}/{{.Name}}] $PS1" -{{end}} - cd "{{.WD}}" {{- range $K, $V := .Env}} diff --git a/internal/assets/contents/shells/bashrc_global.sh b/internal/assets/contents/shells/bashrc_global.sh index 61daa66d21..1ab77e375f 100644 --- a/internal/assets/contents/shells/bashrc_global.sh +++ b/internal/assets/contents/shells/bashrc_global.sh @@ -1,7 +1,3 @@ -{{if and (ne .Project "") (not .PreservePs1)}} -export PS1="[{{.Project}}] $PS1" -{{end}} - {{- range $K, $V := .Env}} {{- if eq $K "PATH"}} export {{$K}}="{{$V}}:$PATH" diff --git a/internal/assets/contents/shells/pwsh.ps1 b/internal/assets/contents/shells/pwsh.ps1 new file mode 100644 index 0000000000..fbbe14f2ff --- /dev/null +++ b/internal/assets/contents/shells/pwsh.ps1 @@ -0,0 +1,27 @@ +cd "{{.WD}}" + +{{- range $K, $V := .Env}} +{{- if eq $K "PATH"}} +$env:PATH = "{{ escapePwsh $V}};$env:PATH" +{{- else}} +$env:{{$K}} = "{{ escapePwsh $V }}" +{{- end}} +{{- end}} + +{{ if .ExecAlias }} +New-Alias {{.ExecAlias}} {{.ExecName}} +{{ end }} + +{{range $K, $CMD := .Scripts}} +function {{$K}} { + & {{$.ExecName}} run {{$CMD}} $args +} +{{end}} + +# Reset execution policy, since we had to set it to bypass to run this script +Set-ExecutionPolicy -Scope Process -ExecutionPolicy (Get-ExecutionPolicy -Scope User) + +echo "{{ escapePwsh .ActivatedMessage}}" +echo "Warning: PowerShell is not yet officially supported." + +{{.UserScripts}} diff --git a/internal/assets/contents/shells/pwsh_global.ps1 b/internal/assets/contents/shells/pwsh_global.ps1 new file mode 100644 index 0000000000..6ea4b04943 --- /dev/null +++ b/internal/assets/contents/shells/pwsh_global.ps1 @@ -0,0 +1,7 @@ +{{- range $K, $V := .Env}} +{{- if eq $K "PATH"}} +$env:{{$K}} = "{{ escapePwsh $V }};$env:PATH" +{{- else}} +$env:{{$K}} = "{{ escapePwsh $V }}" +{{- end}} +{{- end}} diff --git a/internal/assets/contents/shells/zshrc.sh b/internal/assets/contents/shells/zshrc.sh index 7adb9a133c..9de475b8dd 100644 --- a/internal/assets/contents/shells/zshrc.sh +++ b/internal/assets/contents/shells/zshrc.sh @@ -2,10 +2,6 @@ if [ -f $ZDOTDIR/.zshrc ]; then source $ZDOTDIR/.zshrc; fi cd "{{.WD}}" -{{if and (ne .Owner "") (not .PreservePs1)}} -export PS1="[{{.Owner}}/{{.Name}}] $PS1" -{{end}} - {{- range $K, $V := .Env}} {{- if eq $K "PATH"}} export {{$K}}="{{$V}}:$PATH" diff --git a/internal/assets/contents/shells/zshrc_global.sh b/internal/assets/contents/shells/zshrc_global.sh index 9f19cbfbe8..1ab77e375f 100644 --- a/internal/assets/contents/shells/zshrc_global.sh +++ b/internal/assets/contents/shells/zshrc_global.sh @@ -1,11 +1,7 @@ -{{if and (ne .Project "") (not .PreservePs1)}} -export PS1="[{{.Project}}] $PS1" -{{- end}} - {{- range $K, $V := .Env}} {{- if eq $K "PATH"}} export {{$K}}="{{$V}}:$PATH" {{- else}} export {{$K}}="{{$V}}" {{- end}} -{{- end}} \ No newline at end of file +{{- end}} diff --git a/internal/assets/contents/usage.tpl b/internal/assets/contents/usage.tpl index 8110478bbb..9efc639d0d 100644 --- a/internal/assets/contents/usage.tpl +++ b/internal/assets/contents/usage.tpl @@ -66,4 +66,4 @@ To access the list of full commands, including unstable features still in beta, WARNING: You have access to all State Tool commands, including unstable features still in beta, in order to hide these features run: "state config set optin.unstable false" -{{- end}} \ No newline at end of file +{{- end}} diff --git a/internal/captain/command.go b/internal/captain/command.go index 2932a36f28..aa5fd383f3 100644 --- a/internal/captain/command.go +++ b/internal/captain/command.go @@ -20,6 +20,7 @@ import ( "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/logging" configMediator "github.com/ActiveState/cli/internal/mediators/config" "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/osutils" @@ -33,6 +34,8 @@ import ( "github.com/spf13/pflag" ) +type ErrNoChildren struct{ *locale.LocalizedError } + func init() { configMediator.RegisterOption(constants.UnstableConfig, configMediator.Bool, false) } @@ -206,7 +209,7 @@ func (c *Command) UsageText() string { } func (c *Command) Help() string { - return fmt.Sprintf("%s\n\n%s", c.cobra.Short, c.UsageText()) + return strings.TrimRightFunc(fmt.Sprintf("%s\n\n%s", c.cobra.Short, c.UsageText()), unicode.IsSpace) } func (c *Command) ShortDescription() string { @@ -215,6 +218,7 @@ func (c *Command) ShortDescription() string { func (c *Command) Execute(args []string) error { defer profile.Measure("cobra:Execute", time.Now()) + c.logArgs(args) c.cobra.SetArgs(args) err := c.cobra.Execute() c.cobra.SetArgs(nil) @@ -464,15 +468,19 @@ func (c *Command) AvailableChildren() []*Command { return commands } -func (c *Command) Find(args []string) (*Command, error) { +func (c *Command) FindChild(args []string) (*Command, error) { foundCobra, _, err := c.cobra.Find(args) if err != nil { return nil, errs.Wrap(err, "Could not find child command with args: %s", strings.Join(args, " ")) } if cmd, ok := cobraMapping[foundCobra]; ok { + if cmd.parent == nil { + // Cobra returns the parent command if no child was found, but we don't want that. + return nil, nil + } return cmd, nil } - return nil, locale.NewError("err_captain_cmd_find", "Could not find child Command with args: {{.V0}}", strings.Join(args, " ")) + return nil, &ErrNoChildren{locale.NewError("err_captain_cmd_find", "Could not find child Command with args: {{.V0}}", strings.Join(args, " "))} } func (c *Command) GenBashCompletions() (string, error) { @@ -838,7 +846,14 @@ func (cmd *Command) Usage() error { return errs.Wrap(err, "Could not execute template") } - cmd.out.Print(out.String()) + if writer := cmd.cobra.OutOrStdout(); writer != os.Stdout { + _, err := writer.Write(out.Bytes()) + if err != nil { + return errs.Wrap(err, "Unable to write to cobra outWriter") + } + } else { + cmd.out.Print(strings.TrimRightFunc(out.String(), unicode.IsSpace)) + } return nil @@ -869,3 +884,27 @@ func childCommands(cmd *Command) string { return fmt.Sprintf("\n\nAvailable Commands:\n%s", table.Render()) } + +func (c *Command) logArgs(args []string) { + child, err := c.FindChild(args) + if err != nil { + logging.Debug("Could not find child command, error: %v", err) + } + + var logArgs []string + if child != nil { + logArgs = append(logArgs, child.commandNames(false)...) + } + + logging.Debug("Args: %s, Flags: %s", logArgs, flags(args)) +} + +func flags(args []string) []string { + flags := []string{} + for _, arg := range args { + if strings.HasPrefix(arg, "-") || condition.InActiveStateCI() || condition.BuiltOnDevMachine() { + flags = append(flags, arg) + } + } + return flags +} diff --git a/internal/captain/rationalize.go b/internal/captain/rationalize.go index 4abbc6fd94..c44d7dbfdf 100644 --- a/internal/captain/rationalize.go +++ b/internal/captain/rationalize.go @@ -6,6 +6,7 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/pkg/buildscript" "github.com/ActiveState/cli/pkg/localcommit" ) @@ -31,5 +32,11 @@ func rationalizeError(err *error) { *err = errs.WrapUserFacing(*err, locale.Tr("err_commit_id_invalid", errInvalidCommitID.CommitID), errs.SetInput()) + + // Outdated build script. + case errors.Is(*err, buildscript.ErrOutdatedAtTime): + *err = errs.WrapUserFacing(*err, + locale.T("err_outdated_buildscript"), + errs.SetInput()) } } diff --git a/internal/captain/values.go b/internal/captain/values.go index 32b87bd901..5f772b13ee 100644 --- a/internal/captain/values.go +++ b/internal/captain/values.go @@ -124,9 +124,9 @@ func (u *UsersValue) Type() string { // - / // - /@ type PackageValue struct { - Namespace string - Name string - Version string + Namespace string `json:"namespace"` + Name string `json:"name"` + Version string `json:"version,omitempty"` } var _ FlagMarshaler = &PackageValue{} @@ -175,7 +175,7 @@ func (p *PackageValueNoVersion) Set(s string) error { return errs.Wrap(err, "PackageValue.Set failed") } if p.Version != "" { - return locale.NewInputError("err_package_value_no_version", "Specifying a version is not supported, package format should be '[/]'") + return locale.NewInputError("err_package_value_no_version", "Specifying a version is not supported. Package format should be '[/]'") } return nil } @@ -203,7 +203,7 @@ func (p *PackageValueNSRequired) Type() string { } // PackagesValue is used to represent multiple PackageValue, this is used when a flag can be passed multiple times. -type PackagesValue []PackageValue +type PackagesValue []*PackageValue var _ FlagMarshaler = &PackagesValue{} @@ -216,12 +216,16 @@ func (p *PackagesValue) String() string { } func (p *PackagesValue) Set(s string) error { + return nil // This is currently not natively supported by captain as it takes a full list of arguments +} + +func (p *PackagesValue) Add(s string) (*PackageValue, error) { pf := &PackageValue{} if err := pf.Set(s); err != nil { - return err + return nil, err } - *p = append(*p, *pf) - return nil + *p = append(*p, pf) + return pf, nil } func (p *PackagesValue) Type() string { diff --git a/internal/chanutils/workerpool/workerpool.go b/internal/chanutils/workerpool/workerpool.go new file mode 100644 index 0000000000..48d24dbc1b --- /dev/null +++ b/internal/chanutils/workerpool/workerpool.go @@ -0,0 +1,86 @@ +package workerpool + +import ( + "time" + + "github.com/ActiveState/cli/internal/errs" + "github.com/gammazero/workerpool" +) + +// WorkerPool is a wrapper around workerpool.WorkerPool to provide it with some much needed improvements. These are: +// 1. allow for workers to return errors so we don't need to introduce channels to all code using workerpools. +// 2. catch panics inside workers and return them as errors. +type WorkerPool struct { + size int + inner *workerpool.WorkerPool + queue []func() error + errors chan error + errorsOccurred bool +} + +func New(maxWorkers int) *WorkerPool { + return &WorkerPool{ + size: maxWorkers, + inner: workerpool.New(maxWorkers), + errors: make(chan error), + } +} + +func (wp *WorkerPool) Submit(fn func() error) { + wp.queue = append(wp.queue, fn) +} + +// runQueue will submit the queue of functions to the underlying workerpool library. The reason we do it this way is so +// we have control over what jobs are running, which is in turn important for us to be able to error out as soon as +// possible when an error occurs. +func (wp *WorkerPool) runQueue() { + n := 0 + for _, fn := range wp.queue { + if wp.errorsOccurred { + // No point to keep going if errors have occurred, we want to raise these errors asap. + break + } + + wp.inner.Submit(func() { + defer func() { + if p := recover(); p != nil { + wp.errorsOccurred = true + wp.errors <- errs.New("panic inside workerpool: %v", p) + } + }() + err := fn() + if err != nil { + wp.errorsOccurred = true + wp.errors <- err + } + }) + + // Give some breathing room for errors to bubble up so we're not running a bunch of jobs we know will + // result in a failure anyway. + // The sleep would only cause a slowdown if the previous batch of jobs finished in under the time of the sleep, + // which is unlikely unless they threw an error. + if n == wp.size { + n = 0 + time.Sleep(time.Millisecond * 100) + } + } +} + +func (wp *WorkerPool) Wait() error { + wp.runQueue() + + go func() { + wp.inner.StopWait() + close(wp.errors) + }() + + var rerr error + for err := range wp.errors { + if rerr == nil { + rerr = errs.New("workerpool error") + } + rerr = errs.Pack(rerr, err) + } + + return rerr +} diff --git a/internal/chanutils/workerpool/workerpool_test.go b/internal/chanutils/workerpool/workerpool_test.go new file mode 100644 index 0000000000..9051027680 --- /dev/null +++ b/internal/chanutils/workerpool/workerpool_test.go @@ -0,0 +1,22 @@ +package workerpool + +import ( + "errors" + "fmt" + "testing" +) + +func TestError(t *testing.T) { + errToThrow := fmt.Errorf("error") + wp := New(1) + wp.Submit(func() error { + return nil + }) + wp.Submit(func() error { + return errToThrow + }) + err := wp.Wait() + if !errors.Is(err, errToThrow) { + t.Errorf("expected error to be %v, got %v", errToThrow, err) + } +} diff --git a/internal/colorize/colorize.go b/internal/colorize/colorize.go index 024d39ffca..c351727f6c 100644 --- a/internal/colorize/colorize.go +++ b/internal/colorize/colorize.go @@ -18,7 +18,7 @@ func init() { defer profile.Measure("colorize:init", time.Now()) var err error colorRx, err = regexp.Compile( - `\[(HEADING|NOTICE|SUCCESS|ERROR|WARNING|DISABLED|ACTIONABLE|CYAN|GREEN|RED|ORANGE|YELLOW|MAGENTA|/RESET)!?\]`, + `\[(HEADING|BOLD|NOTICE|SUCCESS|ERROR|WARNING|DISABLED|ACTIONABLE|CYAN|GREEN|RED|ORANGE|YELLOW|MAGENTA|/RESET)!?\]`, ) if err != nil { panic(fmt.Sprintf("Could not compile regex: %v", err)) @@ -27,6 +27,7 @@ func init() { type ColorTheme interface { Heading(writer io.Writer) + Bold(writer io.Writer) Notice(writer io.Writer) Success(writer io.Writer) Error(writer io.Writer) @@ -51,6 +52,11 @@ func (dct defaultColorTheme) Heading(writer io.Writer) { c.SetStyle(colorstyle.Bold, false) } +func (dct defaultColorTheme) Bold(writer io.Writer) { + c := colorstyle.New(writer) + c.SetStyle(colorstyle.Bold, false) +} + // Notice switches to bright foreground func (dct defaultColorTheme) Notice(writer io.Writer) { colorstyle.New(writer).SetStyle(colorstyle.Default, true) @@ -174,6 +180,8 @@ func colorize(ct ColorTheme, writer io.Writer, arg string) { ct.Warning(writer) case `ERROR`: ct.Error(writer) + case `BOLD`: + ct.Bold(writer) case `DISABLED`: ct.Disabled(writer) case `ACTIONABLE`: diff --git a/internal/condition/condition.go b/internal/condition/condition.go index fb77305cfa..372fe86fa8 100644 --- a/internal/condition/condition.go +++ b/internal/condition/condition.go @@ -55,7 +55,7 @@ func OptInUnstable(cfg Configurable) bool { if v := os.Getenv(constants.OptinUnstableEnvVarName); v != "" { return v == "true" } - return cfg.GetBool(constants.UnstableConfig) + return BuiltOnDevMachine() || cfg.GetBool(constants.UnstableConfig) } func IsNetworkingError(err error) bool { diff --git a/internal/config/instance.go b/internal/config/instance.go index 00a2cb3ea0..fd6d68fe48 100644 --- a/internal/config/instance.go +++ b/internal/config/instance.go @@ -185,7 +185,7 @@ func (i *Instance) Get(key string) interface{} { return result } if opt := mediator.GetOption(key); mediator.KnownOption(opt) { - return opt.Default + return mediator.GetDefault(opt) } return nil } diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 2980b3c6a1..b8f054e96e 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -49,6 +49,9 @@ const LogBuildVerboseEnvVarName = "ACTIVESTATE_CLI_BUILD_VERBOSE" // DisableRuntime is the env var used to disable downloading of runtimes, useful for CI or testing const DisableRuntime = "ACTIVESTATE_CLI_DISABLE_RUNTIME" +// DisableBuildscriptDirtyCheck is the env var used to disable the check for dirty buildscripts +const DisableBuildscriptDirtyCheck = "ACTIVESTATE_CLI_DISABLE_BS_DIRTY_CHECK" + // DisableUpdates is the env var used to disable automatic updates const DisableUpdates = "ACTIVESTATE_CLI_DISABLE_UPDATES" @@ -58,8 +61,8 @@ const DisableLanguageTemplates = "ACTIVESTATE_CLI_DISABLE_LANGUAGE_TEMPLATES" // UpdateChannelEnvVarName is the env var that is used to override which channel to pull the update from const UpdateChannelEnvVarName = "ACTIVESTATE_CLI_UPDATE_CHANNEL" -// InstallBuildDependencies is the env var that is used to override whether to install build dependencies -const InstallBuildDependencies = "ACTIVESTATE_CLI_INSTALL_BUILD_DEPENDENCIES" +// InstallBuildDependenciesEnvVarName is the env var that is used to override whether to install build dependencies +const InstallBuildDependenciesEnvVarName = "ACTIVESTATE_CLI_INSTALL_BUILD_DEPENDENCIES" // InternalConfigFileNameLegacy is effectively the same as InternalConfigName, but includes our preferred extension const InternalConfigFileNameLegacy = "config.yaml" @@ -185,27 +188,11 @@ const DisableActivateEventsEnvVarName = "ACTIVESTATE_CLI_DISABLE_ACTIVATE_EVENTS const APIUpdateInfoURL = "https://platform.activestate.com/sv/state-update/api/v1" // APIUpdateURL is the URL for our update files -const APIUpdateURL = "https://state-tool.s3.amazonaws.com/update/state" +const APIUpdateURL = "https://state-tool.activestate.com/update/state" // APIArtifactURL is the URL for downloading artifacts const APIArtifactURL = "https://s3.ca-central-1.amazonaws.com/cli-artifacts/" -// ArtifactFile is the name of the artifact json file contained within artifacts -const ArtifactFile = "artifact.json" - -// ArtifactArchiveName is the standardized name of an artifact archive -const ArtifactArchiveName = "artifact.tar.gz" - -// ArtifactCacheFileName is the standardized name of an artifact cache file -const ArtifactCacheFileName = "artifact_cache.json" - -// ArtifactMetaDir is the directory in which we store meta information about artifacts -const ArtifactMetaDir = "artifacts" - -// ArtifactCacheSizeEnvVarName is the maximum size in MB of the artifact cache. -// The default is 500MB. -const ArtifactCacheSizeEnvVarName = "ACTIVESTATE_ARTIFACT_CACHE_SIZE_MB" - // DefaultNamespaceDomain is the domain used when no namespace is given and one has to be constructed const DefaultNamespaceDomain = "github.com" @@ -347,40 +334,6 @@ const ( ValidZeroUUID = "00000000-0000-0000-0000-000000000000" ) -// ActivePythonDistsDir represents the base name of a directory where ActivePython dists will be installed under. -const ActivePythonDistsDir = "python" - -// RuntimeInstallDirs represents the directory within a distribution archive where the distribution exists. -const RuntimeInstallDirs = "INSTALLDIR,perl" - -// RuntimeMetaFile is the json file that holds meta information about our runtime -const RuntimeMetaFile = "metadata.json" - -// RuntimeDefinitionFilename is the filename for runtime meta data bundled with artifacts, if they are built by the alternative builder -const RuntimeDefinitionFilename = "runtime.json" - -// LocalRuntimeEnvironmentDirectory is the directory (relative to the installation of a runtime build) where runtime definition files are stored -const LocalRuntimeEnvironmentDirectory = "_runtime_store" - -// LocalRuntimeTempDirectory is the directory (relative to the installation of a runtime build) where temp files are stored -const LocalRuntimeTempDirectory = "_runtime_temp" - -// RuntimeInstallationCompleteMarker is created after all artifacts have been installed -// Check for existence of this file to ensure that the installation has not been interrupted prematurely. -const RuntimeInstallationCompleteMarker = "completed" - -// RuntimeBuildEngineStore contains the name of the build engine that was used to create this runtime -const RuntimeBuildEngineStore = "build_engine" - -// RuntimeRecipeStore contains a serialization of the recipe used to create this build -const RuntimeRecipeStore = "recipe" - -// RuntimeBuildPlanStore containts a serialization of the build plan used to create this build -const RuntimeBuildPlanStore = "build_plan" - -// BuildScriptStore holds the cached buildscript for the current project. -const BuildScriptStore = "build_script" - // StateToolMarketingPage links to the marketing page for the state tool const StateToolMarketingPage = "https://www.activestate.com/products/platform/state-tool/" @@ -517,9 +470,6 @@ const PipShim = "pip" // AutoUpdateConfigKey is the config key for storing whether or not autoupdates can be performed const AutoUpdateConfigKey = "autoupdate" -// PreservePs1ConfigKey is the config key that specifies whether to modify the shell PS1/prompt to show [org/project] info. -const PreservePs1ConfigKey = "shell.preserve.prompt" - // DefaultAnalyticsPixel is the default url for the analytics pixel const DefaultAnalyticsPixel = "https://state-tool.s3.amazonaws.com/pixel" @@ -529,16 +479,17 @@ const AnalyticsPixelOverrideEnv = "ACTIVESTATE_CLI_ANALYTICS_PIXEL" // TerminalAnimationInterval is the interval we use for terminal animations const TerminalAnimationInterval = 150 * time.Millisecond -// RuntimeSetupWaitEnvVarName is only used for an integration test to pause installation and wait -// for Ctrl+C. -const RuntimeSetupWaitEnvVarName = "ACTIVESTATE_CLI_RUNTIME_SETUP_WAIT" - -// PlatformApiRequestRequestsEnvVarName is only used for an integration test to print some Platform -// API request info. -const PlatformApiPrintRequestsEnvVarName = "ACTIVESTATE_CLI_PLATFORM_API_PRINT_REQUESTS" - // ActiveStateCIEnvVarName is the environment variable set when running in an ActiveState CI environment. const ActiveStateCIEnvVarName = "ACTIVESTATE_CI" // OverrideSandbox is the environment variable to set when overriding the sandbox for integration tests. const OverrideSandbox = "ACTIVESTATE_TEST_OVERRIDE_SANDBOX" + +// PlatformPrivateNamespace is the namespace for private packages. +const PlatformPrivateNamespace = "private" + +// OverrideShellEnvVarName is the environment variable to set when overriding the shell for shell detection. +const OverrideShellEnvVarName = "ACTIVESTATE_CLI_SHELL_OVERRIDE" + +// IgnoreEnvEnvVarName is the environment variable to set for skipping specific environment variables during runtime setup. +const IgnoreEnvEnvVarName = "ACTIVESTATE_CLI_IGNORE_ENV" diff --git a/internal/constraints/constraints.go b/internal/constraints/constraints.go index 503f8331f5..618845f810 100644 --- a/internal/constraints/constraints.go +++ b/internal/constraints/constraints.go @@ -125,12 +125,12 @@ func (c *Conditional) RegisterParam(name string, value interface{}) { func (c *Conditional) Eval(conditional string) (bool, error) { tpl, err := template.New("").Funcs(c.funcs).Parse(fmt.Sprintf(`{{if %s}}1{{end}}`, conditional)) if err != nil { - return false, locale.WrapInputError(err, "err_conditional", "Invalid 'if' condition: '{{.V0}}', error: '{{.V1}}'.", conditional, err.Error()) + return false, locale.WrapInputError(err, "err_conditional", "Invalid 'if' condition: '{{.V0}}'. Error: '{{.V1}}'.", conditional, err.Error()) } result := bytes.Buffer{} if err := tpl.Execute(&result, c.params); err != nil { - return false, locale.WrapInputError(err, "err_conditional", "Invalid 'if' condition: '{{.V0}}', error: '{{.V1}}'.", conditional, err.Error()) + return false, locale.WrapInputError(err, "err_conditional", "Invalid 'if' condition: '{{.V0}}'. Error: '{{.V1}}'.", conditional, err.Error()) } return result.String() == "1", nil diff --git a/internal/errs/errs.go b/internal/errs/errs.go index 5a0d4f69f3..6ac1a9f6fa 100644 --- a/internal/errs/errs.go +++ b/internal/errs/errs.go @@ -6,7 +6,6 @@ import ( "reflect" "strings" - "github.com/ActiveState/cli/internal/condition" "github.com/ActiveState/cli/internal/osutils/stacktrace" "github.com/ActiveState/cli/internal/rtutils" "gopkg.in/yaml.v3" @@ -106,8 +105,21 @@ func Wrap(wrapTarget error, message string, args ...interface{}) *WrapperError { } // Pack creates a new error that packs the given errors together, allowing for multiple errors to be returned -func Pack(err error, errs ...error) error { - return &PackedErrors{append([]error{err}, errs...)} +// This accepts nil errors, and will return nil if all errors passed in are also nil. +func Pack(errs ...error) error { + var errsNonNil []error + for _, err := range errs { + if err != nil { + errsNonNil = append(errsNonNil, err) + } + } + if len(errsNonNil) == 0 { + return nil + } + if len(errsNonNil) == 1 { + return errsNonNil[0] + } + return &PackedErrors{errsNonNil} } // encodeErrorForJoin will recursively encode an error into a format that can be marshalled in a way that is easily @@ -181,39 +193,6 @@ func AddTips(err error, tips ...string) error { var errorType = reflect.TypeOf((*error)(nil)).Elem() -// Matches is an analog for errors.As that just checks whether err matches the given type, so you can do: -// errs.Matches(err, &ErrStruct{}) -// Without having to first assign it to a variable -// This is useful if you ONLY care about the bool return value and not about setting the variable -func Matches(err error, target interface{}) bool { - if target == nil { - panic("errors: target cannot be nil") - } - - // Guard against miss-use of this function - if _, ok := target.(*WrapperError); ok { - if condition.BuiltOnDevMachine() || condition.InActiveStateCI() { - panic("target cannot be a WrapperError, you probably want errors.Is") - } - } - - val := reflect.ValueOf(target) - targetType := val.Type() - if targetType.Kind() != reflect.Interface && !targetType.Implements(errorType) { - panic("errors: *target must be interface or implement error") - } - errs := Unpack(err) - for _, err := range errs { - if reflect.TypeOf(err).AssignableTo(targetType) { - return true - } - if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(&target) { - return true - } - } - return false -} - func IsAny(err error, errs ...error) bool { for _, e := range errs { if errors.Is(err, e) { diff --git a/internal/errs/errs_test.go b/internal/errs/errs_test.go index 0359be33ed..b540a22f30 100644 --- a/internal/errs/errs_test.go +++ b/internal/errs/errs_test.go @@ -2,8 +2,6 @@ package errs_test import ( "errors" - "os" - "os/exec" "path/filepath" "reflect" "strings" @@ -63,82 +61,6 @@ func TestErrs(t *testing.T) { type standardError struct{ error } -func TestMatches(t *testing.T) { - type args struct { - err error - target interface{} - } - tests := []struct { - name string - args args - want bool - }{ - { - "Simple match", - args{ - &standardError{errors.New("error")}, - &standardError{}, - }, - true, - }, - { - "Simple miss-match", - args{ - errors.New("error"), - &standardError{}, - }, - false, - }, - { - "Wrapped match", - args{ - errs.Wrap(&standardError{errors.New("error")}, "Wrapped"), - &standardError{}, - }, - true, - }, - { - "exec.ExitError", // this one has proved troublesome - args{ - &exec.ExitError{&os.ProcessState{}, []byte("")}, - &exec.ExitError{}, - }, - true, - }, - { - "wrapped exec.ExitError", - args{ - errs.Wrap(&exec.ExitError{&os.ProcessState{}, []byte("")}, "wrapped"), - &exec.ExitError{}, - }, - true, - }, - { - "combined errors 1", - args{ - errs.Pack(&exec.ExitError{&os.ProcessState{}, []byte("")}, errs.New("Random")), - &exec.ExitError{}, - }, - true, - }, - { - "combined errors 2 - inverted", - args{ - errs.Pack(errs.New("Random"), &exec.ExitError{&os.ProcessState{}, []byte("")}), - &exec.ExitError{}, - }, - true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := errs.Matches(tt.args.err, tt.args.target); got != tt.want { - t.Errorf("Matches() = %v, want %v", got, tt.want) - } - }) - } -} - func TestAddTips(t *testing.T) { type args struct { err error diff --git a/internal/errs/example_test.go b/internal/errs/example_test.go index fdb3394767..64541d25f7 100644 --- a/internal/errs/example_test.go +++ b/internal/errs/example_test.go @@ -19,7 +19,6 @@ func TestExample(t *testing.T) { errt := &MyError{} var errx error = &MyError{errs.New("test1")} errors.As(errx, &errt) - errs.Matches(errx, &MyError{}) // Regular error var err error = errs.New("Regular error message on %s", runtime.GOOS) @@ -38,8 +37,6 @@ func TestExample(t *testing.T) { err = errs.Wrap(myError, "My WrappedErr!") assert.Error(t, err) assert.True(t, errors.As(err, &myErrorCopy), "Error can be accessed as myErrorCopy") - assert.True(t, errs.Matches(err, &MyError{}), "Error Matches") - assert.False(t, errs.Matches(errs.New("foo"), &MyError{}), "Error doesn't match") assert.True(t, errors.Is(err, myError), "err is equivalent to myError") // ptrs same addr, non-ptrs struct equality // Create user input error diff --git a/internal/events/cmdcall/cmdcall.go b/internal/events/cmdcall/cmdcall.go index bea194ac0d..7e8d068016 100644 --- a/internal/events/cmdcall/cmdcall.go +++ b/internal/events/cmdcall/cmdcall.go @@ -42,7 +42,7 @@ func New(p primeable, cmdList string) *CmdCall { subshell: p.Subshell(), cmdList: cmdList, p: p, - scriptrun: scriptrun.New(p.Auth(), p.Output(), p.Subshell(), p.Project(), p.Config(), p.Analytics(), p.SvcModel()), + scriptrun: scriptrun.New(p), } } diff --git a/internal/fileevents/fileevents.go b/internal/fileevents/fileevents.go index 80affbcec4..906941506c 100644 --- a/internal/fileevents/fileevents.go +++ b/internal/fileevents/fileevents.go @@ -109,7 +109,7 @@ func (fe *FileEvents) onEvent(affectedFilepath string, log logging.Logger) error } err = runScript(value, logger) if err != nil { - return locale.NewError("err_fileevent_cmd", "Could not run the script `{{.V0}}`, please ensure its name is valid and you can run `state run {{.V0}}`.", value) + return locale.NewError("err_fileevent_cmd", "Could not run the script `{{.V0}}`. Please ensure its name is valid and you can run `state run {{.V0}}`.", value) } } return nil @@ -142,10 +142,10 @@ func runScript(name string, log logging.Logger) error { go captureStd(stdout, log) if err := cmd.Start(); err != nil { - return locale.WrapError(err, "err_fileevent_cmd_start", "Could not run script `{{.V0}}`, error: {{.V1}}.", name, err.Error()) + return locale.WrapError(err, "err_fileevent_cmd_start", "Could not run script `{{.V0}}`. Error: {{.V1}}.", name, err.Error()) } if err := cmd.Wait(); err != nil { - return locale.WrapError(err, "err_fileevent_cmd_start", "Error happened while running script `{{.V0}}`, error: {{.V1}}.", name, err.Error()) + return locale.WrapError(err, "err_fileevent_cmd_start", "Error happened while running script `{{.V0}}`. Error: {{.V1}}.", name, err.Error()) } log(locale.Tl("script_finished", "Script Finished")) diff --git a/internal/fileutils/fileutils.go b/internal/fileutils/fileutils.go index 38d8a2c15f..114b35652e 100644 --- a/internal/fileutils/fileutils.go +++ b/internal/fileutils/fileutils.go @@ -17,6 +17,7 @@ import ( "unicode" "github.com/gofrs/flock" + "github.com/labstack/gommon/random" "github.com/thoas/go-funk" "github.com/ActiveState/cli/internal/assets" @@ -25,6 +26,7 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/rollbar" + "github.com/ActiveState/cli/internal/rtutils/ptr" ) // nullByte represents the null-terminator byte @@ -765,6 +767,14 @@ func CopyFiles(src, dst string) error { return copyFiles(src, dst, false) } +type ErrAlreadyExist struct { + Path string +} + +func (e *ErrAlreadyExist) Error() string { + return fmt.Sprintf("file already exists: %s", e.Path) +} + func copyFiles(src, dest string, remove bool) error { if !DirExists(src) { return locale.NewError("err_os_not_a_directory", "", src) @@ -778,6 +788,7 @@ func copyFiles(src, dest string, remove bool) error { return errs.Wrap(err, "os.ReadDir %s failed", src) } + var errAlreadyExist error for _, entry := range entries { srcPath := filepath.Join(src, entry.Name()) destPath := filepath.Join(dest, entry.Name()) @@ -787,15 +798,24 @@ func copyFiles(src, dest string, remove bool) error { return errs.Wrap(err, "os.Lstat %s failed", srcPath) } + if !fileInfo.IsDir() && TargetExists(destPath) { + errAlreadyExist = errs.Pack(errAlreadyExist, &ErrAlreadyExist{destPath}) + continue + } + switch fileInfo.Mode() & os.ModeType { case os.ModeDir: err := MkdirUnlessExists(destPath) if err != nil { return errs.Wrap(err, "MkdirUnlessExists %s failed", destPath) } - err = CopyFiles(srcPath, destPath) + err = copyFiles(srcPath, destPath, remove) if err != nil { - return errs.Wrap(err, "CopyFiles %s:%s failed", srcPath, destPath) + if errors.As(err, ptr.To(&ErrAlreadyExist{})) { + errAlreadyExist = errs.Pack(errAlreadyExist, err) + } else { + return errs.Wrap(err, "CopyFiles %s:%s failed", srcPath, destPath) + } } case os.ModeSymlink: err := CopySymlink(srcPath, destPath) @@ -816,6 +836,12 @@ func copyFiles(src, dest string, remove bool) error { } } + // If some files already exist we want to error on this, but only after all other remaining files have been copied. + // If ANY other type of error occurs then we don't bubble this up as this is the only error we handle that's non-critical. + if errAlreadyExist != nil { + return errAlreadyExist + } + return nil } @@ -845,10 +871,15 @@ func TempFileUnsafe(dir, pattern string) *os.File { return f } -func TempFilePathUnsafe(dir, pattern string) string { - f := TempFileUnsafe(dir, pattern) - defer f.Close() - return f.Name() +func TempFilePath(dir, pattern string) string { + if dir == "" { + dir = os.TempDir() + } + fname := random.String(8, random.Alphanumeric) + if pattern != "" { + fname = fmt.Sprintf("%s-%s", fname, pattern) + } + return filepath.Join(dir, fname) } // TempDirUnsafe returns a temp path or panics if it cannot be created @@ -959,6 +990,13 @@ func ResolvePath(path string) (string, error) { return evalPath, nil } +func ResolvePathIfPossible(path string) string { + if resolvedPath, err := ResolveUniquePath(path); err == nil { + return resolvedPath + } + return path +} + // PathsEqual checks whether the paths given all resolve to the same path func PathsEqual(paths ...string) (bool, error) { if len(paths) < 2 { @@ -1075,7 +1113,7 @@ type DirEntry struct { rootPath string } -func (d DirEntry) Path() string { +func (d DirEntry) AbsolutePath() string { return d.absolutePath } @@ -1084,9 +1122,19 @@ func (d DirEntry) RelativePath() string { return strings.TrimPrefix(d.absolutePath, d.rootPath) } +type DirEntries []DirEntry + +func (d DirEntries) RelativePaths() []string { + result := []string{} + for _, de := range d { + result = append(result, de.RelativePath()) + } + return result +} + // ListDir recursively lists filepaths under the given sourcePath // This does not follow symlinks -func ListDir(sourcePath string, includeDirs bool) ([]DirEntry, error) { +func ListDir(sourcePath string, includeDirs bool) (DirEntries, error) { result := []DirEntry{} sourcePath = filepath.Clean(sourcePath) if err := filepath.WalkDir(sourcePath, func(path string, f fs.DirEntry, err error) error { @@ -1200,3 +1248,54 @@ func globPath(path string) string { } return result } + +// CommonParentPath will return the common parent path of the given paths, provided they share a common path. +// If they do not all share a single common path the result will be empty. +func CommonParentPath(paths []string) string { + if len(paths) == 0 { + return "" + } + + common := paths[0] + for _, p := range paths[1:] { + common = commonParentPath(common, p) + if common == "" { + return "" + } + } + + return common +} + +func commonParentPath(a, b string) (result string) { + isWindowsPath := false + defer func() { + if isWindowsPath { + result = posixPathToWindowsPath(result) + } + }() + common := "" + ab := windowsPathToPosixPath(a) + bb := windowsPathToPosixPath(b) + isWindowsPath = a != ab + as := strings.Split(ab, "/") + bs := strings.Split(bb, "/") + max := min(len(as), len(bs)) + for x := 1; x <= max; x++ { + ac := strings.Join(as[:x], "/") + bc := strings.Join(bs[:x], "/") + if ac != bc { + return common + } + common = ac + } + return common +} + +func windowsPathToPosixPath(path string) string { + return strings.ReplaceAll(path, "\\", "/") +} + +func posixPathToWindowsPath(path string) string { + return strings.ReplaceAll(path, "/", "\\") +} diff --git a/internal/fileutils/fileutils_test.go b/internal/fileutils/fileutils_test.go index e444678dd1..5aec01ccf6 100644 --- a/internal/fileutils/fileutils_test.go +++ b/internal/fileutils/fileutils_test.go @@ -573,55 +573,6 @@ func TestResolveUniquePath(t *testing.T) { }) } -func TestCaseSensitivePath(t *testing.T) { - tests := []struct { - dirName string - variant string - }{ - { - "lowercase", - "LOWERCASE", - }, - { - "UPPERCASE", - "uppercase", - }, - { - "MiXeDcAse", - "mixedCase", - }, - { - "{other~symbols!}", - "{OTHER~symbols!}", - }, - { - "spéçïàl", - "spÉÇÏÀl", - }, - } - for _, tt := range tests { - t.Run(tt.dirName, func(t *testing.T) { - testCaseSensitivePath(t, tt.dirName, tt.variant) - }) - } -} - -func testCaseSensitivePath(t *testing.T, dirName, variant string) { - dir, err := os.MkdirTemp("", dirName) - assert.NoError(t, err) - - dir, err = GetLongPathName(dir) - assert.NoError(t, err) - - searchPath := strings.Replace(dir, dirName, variant, -1) - found, err := CaseSensitivePath(searchPath) - assert.NoError(t, err) - - if found != dir { - t.Fatalf("Found should match dir \nwant: %s \ngot: %s", dir, found) - } -} - func TestPathsMatch(t *testing.T) { if runtime.GOOS != "darwin" { t.Skip("PathsMatch is only tested on macOS") @@ -683,3 +634,116 @@ func TestIsWritableDir(t *testing.T) { t.Fatalf("Path should not be writable: %s", pathWithNoPermission) } } + +func TestCommonParentPath(t *testing.T) { + tests := []struct { + paths []string + expected string + }{ + { + paths: []string{"./folder1/file.txt", "./folder1/subfolder/file.txt"}, + expected: "./folder1", + }, + { + paths: []string{"./folder1/file.txt", "./folder2/file.txt"}, + expected: ".", + }, + { + paths: []string{"./folder1/subfolder1/file.txt", "./folder1/subfolder2/file.txt"}, + expected: "./folder1", + }, + { + paths: []string{"./folder1/", "./folder1/subfolder/"}, + expected: "./folder1", + }, + { + paths: []string{"./folder1/file.txt", "./folder1/file.txt"}, + expected: "./folder1/file.txt", + }, + { + paths: []string{"./folder1/file.txt", "./folder1/"}, + expected: "./folder1", + }, + { + paths: []string{"./folder1/file.txt", "./folder2/"}, + expected: ".", + }, + { + paths: []string{"./folder1/file.txt", "./folder1/subfolder/file.txt", "./folder1/subfolder2/file.txt"}, + expected: "./folder1", + }, + { + paths: []string{"./folder1/file.txt", "./folder1/subfolder/file.txt", "./folder2/file.txt"}, + expected: ".", + }, + { + paths: []string{"./folder1/file.txt", "./folder1/subfolder/file.txt", "./folder1/subfolder2/file.txt", "./folder1/subfolder3/file.txt"}, + expected: "./folder1", + }, + { + paths: []string{"./folder1/file.txt", "./folder1/file.txt", "./folder1/file.txt"}, + expected: "./folder1/file.txt", + }, + { + paths: []string{"/home/user/folder1/file.txt", "/home/user/folder1/subfolder/file.txt"}, + expected: "/home/user/folder1", + }, + { + paths: []string{"/home/user/folder1/file.txt", "/home/user/folder2/file.txt"}, + expected: "/home/user", + }, + { + paths: []string{"/home/user/folder1/subfolder1/file.txt", "/home/user/folder1/subfolder2/file.txt"}, + expected: "/home/user/folder1", + }, + { + paths: []string{"C:\\Users\\User\\folder1\\file.txt", "C:\\Users\\User\\folder1\\subfolder\\file.txt"}, + expected: "C:\\Users\\User\\folder1", + }, + { + paths: []string{"C:\\Users\\User\\folder1\\file.txt", "C:\\Users\\User\\folder2\\file.txt"}, + expected: "C:\\Users\\User", + }, + { + paths: []string{"C:\\Users\\User\\folder1\\subfolder1\\file.txt", "C:\\Users\\User\\folder1\\subfolder2\\file.txt"}, + expected: "C:\\Users\\User\\folder1", + }, + { + paths: []string{"folder1/file.txt", "folder1/subfolder/file.txt"}, + expected: "folder1", + }, + { + paths: []string{"folder1/file.txt", "folder2/file.txt"}, + expected: "", + }, + { + paths: []string{"folder1/file.txt", "folder1/subfolder/file.txt", "folder1/subfolder2/file.txt"}, + expected: "folder1", + }, + { + paths: []string{"folder1/file.txt", "folder1/file.txt", "folder1/file.txt"}, + expected: "folder1/file.txt", + }, + { + paths: []string{"C:\\Users\\User\\folder1\\file.txt", "C:\\Users\\User\\folder1\\subfolder\\file.txt", "C:\\Users\\User\\folder2\\file.txt"}, + expected: "C:\\Users\\User", + }, + { + paths: []string{"/var/log/syslog", "/var/log/auth.log"}, + expected: "/var/log", + }, + { + paths: []string{}, + expected: "", + }, + } + + for _, test := range tests { + t.Run(filepath.Join(test.paths...), func(t *testing.T) { + result := CommonParentPath(test.paths) + if result != test.expected { + t.Errorf("CommonParentPath(%v) = %q; expected %q", test.paths, result, test.expected) + } + }) + } +} diff --git a/internal/globaldefault/default.go b/internal/globaldefault/default.go index 5e412dfc01..7636130260 100644 --- a/internal/globaldefault/default.go +++ b/internal/globaldefault/default.go @@ -4,6 +4,7 @@ import ( "path/filepath" "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/installation/storage" "github.com/ActiveState/cli/internal/locale" @@ -13,10 +14,9 @@ import ( "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/subshell/sscommon" "github.com/ActiveState/cli/internal/svcctl" - "github.com/ActiveState/cli/pkg/platform/runtime" - "github.com/ActiveState/cli/pkg/platform/runtime/executors" - "github.com/ActiveState/cli/pkg/platform/runtime/target" + "github.com/ActiveState/cli/pkg/executors" "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/cli/pkg/runtime" ) type DefaultConfigurer interface { @@ -69,19 +69,16 @@ func SetupDefaultActivation(subshell subshell.SubShell, cfg DefaultConfigurer, r return locale.WrapError(err, "err_globaldefault_prepare", "Could not prepare environment.") } - exes, err := runtime.ExecutablePaths() + env := runtime.Env(false) + exes, err := osutils.ExecutablePaths(env.Variables) if err != nil { - return locale.WrapError(err, "err_globaldefault_rtexes", "Could not retrieve runtime executables") + return errs.Wrap(err, "Could not get executable paths") } - env, err := runtime.Env(false, false) - if err != nil { - return locale.WrapError(err, "err_globaldefault_rtenv", "Could not construct runtime environment variables") - } - - target := target.NewProjectTargetCache(proj, storage.GlobalBinDir(), nil, target.TriggerActivate) execInit := executors.New(BinDir()) - if err := execInit.Apply(svcctl.NewIPCSockPathFromGlobals().String(), target, env, exes); err != nil { + if err := execInit.Apply(svcctl.NewIPCSockPathFromGlobals().String(), + executors.NewTarget("", proj.Owner(), proj.Name(), storage.GlobalBinDir()), + env.Variables, exes); err != nil { return locale.WrapError(err, "err_globaldefault_fw", "Could not set up forwarders") } diff --git a/internal/graph/generated.go b/internal/graph/generated.go index 8514664e0a..a9c307c88d 100644 --- a/internal/graph/generated.go +++ b/internal/graph/generated.go @@ -24,6 +24,17 @@ type ConfigChangedResponse struct { Received bool `json:"received"` } +type GlobFileResult struct { + Pattern string `json:"pattern"` + Path string `json:"path"` + Hash string `json:"hash"` +} + +type GlobResult struct { + Files []*GlobFileResult `json:"files"` + Hash string `json:"hash"` +} + type Jwt struct { Token string `json:"token"` User *User `json:"user"` @@ -38,6 +49,9 @@ type MessageInfo struct { Placement MessagePlacementType `json:"placement"` } +type Mutation struct { +} + type Organization struct { URLname string `json:"URLname"` Role string `json:"role"` @@ -53,6 +67,9 @@ type Project struct { Locations []string `json:"locations"` } +type Query struct { +} + type ReportRuntimeUsageResponse struct { Received bool `json:"received"` } diff --git a/internal/graph/response.go b/internal/graph/response.go index ed1ee4fb2c..52add42637 100644 --- a/internal/graph/response.go +++ b/internal/graph/response.go @@ -1,6 +1,8 @@ package graph -import "encoding/json" +import ( + "encoding/json" +) type VersionResponse struct { Version Version `json:"version"` @@ -25,3 +27,7 @@ type GetProcessesInUseResponse struct { type GetJWTResponse struct { Payload json.RawMessage `json:"getJWT"` } + +type HashGlobsResponse struct { + Response GlobResult `json:"hashGlobs"` +} diff --git a/internal/httputil/get.go b/internal/httputil/get.go index 9982132336..46f9e572a6 100644 --- a/internal/httputil/get.go +++ b/internal/httputil/get.go @@ -17,7 +17,7 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/proxyreader" "github.com/ActiveState/cli/internal/retryhttp" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/events/progress" + "github.com/ActiveState/cli/pkg/runtime/events/progress" ) // Get takes a URL and returns the contents as bytes @@ -81,7 +81,7 @@ func httpGetWithProgressRetry(url string, prg progress.Reporter, attempt int, re var src io.Reader = resp.Body defer resp.Body.Close() - if prg != nil { + if prg != nil && attempt == 1 { if err := prg.ReportSize(total); err != nil { return nil, errs.Wrap(err, "Could not report size") } diff --git a/internal/installation/paths.go b/internal/installation/paths.go index 5c84acd58f..424bfd94f6 100644 --- a/internal/installation/paths.go +++ b/internal/installation/paths.go @@ -1,6 +1,7 @@ package installation import ( + "errors" "os" "path/filepath" "strings" @@ -22,14 +23,15 @@ const ( ) type InstallMarkerMeta struct { - Channel string `json:"channel"` + Channel string `json:"channel"` Version string `json:"version"` } type StateExeDoesNotExistError struct{ *errs.WrapperError } func IsStateExeDoesNotExistError(err error) bool { - return errs.Matches(err, &StateExeDoesNotExistError{}) + var errStateExeDoesNotExist *StateExeDoesNotExistError + return errors.As(err, &errStateExeDoesNotExist) } func DefaultInstallPath() (string, error) { diff --git a/internal/installation/storage/storage.go b/internal/installation/storage/storage.go index ba40cef0b1..a8659cbed1 100644 --- a/internal/installation/storage/storage.go +++ b/internal/installation/storage/storage.go @@ -125,12 +125,6 @@ func GlobalBinDir() string { return filepath.Join(CachePath(), "bin") } -// ArtifactCacheDir is where cached artifacts are stored. -// This is a shared cache for downloaded artifacts, not installed artifacts. -func ArtifactCacheDir() string { - return filepath.Join(CachePath(), constants.ArtifactMetaDir) -} - // InstallSource returns the installation source of the State Tool func InstallSource() (string, error) { path, err := AppDataPath() diff --git a/internal/locale/locale.go b/internal/locale/locale.go index b6f4565741..17db70f89f 100644 --- a/internal/locale/locale.go +++ b/internal/locale/locale.go @@ -138,6 +138,15 @@ func T(translationID string, args ...interface{}) string { return translateFunction(translationID, args...) } +// Ts aliases to T, but accepts a list of translationIDs to be translated +func Ts(translationIDs ...string) []string { + result := []string{} + for _, id := range translationIDs { + result = append(result, T(id)) + } + return result +} + // Tr is like T but it accepts string params that will be used as numbered params, eg. V0, V1, V2 etc func Tr(translationID string, values ...string) string { return T(translationID, parseInput(values...)) diff --git a/internal/locale/locales/en-us.yaml b/internal/locale/locales/en-us.yaml index da4e7c0b8f..9a4deb3a3a 100644 --- a/internal/locale/locales/en-us.yaml +++ b/internal/locale/locales/en-us.yaml @@ -20,7 +20,7 @@ flag_state_verbose_description: flag_state_monochrome_output_description: other: Force monochrome text output flag_state_output_description: - other: "Set the output method, possible values: plain, simple, json, editor" + other: "Set the output method. Possible values: plain, simple, json, editor" flag_state_non_interactive_description: other: Run the State Tool without any prompts flag_state_version_description: @@ -87,7 +87,7 @@ secret_prompt_user: secret_prompt_project: other: Organization members can access the value secret_no_description: - other: "- (This secret has no description, you can set one via the web dashboard)" + other: "- (This secret has no description. You can set one via the web dashboard.)" totp_prompt: other: "Enter your two-factor authentication code:" survey_error_template: @@ -106,15 +106,15 @@ tos_disclaimer_prompt: err_auth_failed: other: Authentication failed err_auth_failed_unknown_cause: - other: "Authentication failed due to an unknown cause, error received: {{.V0}}" + other: "Authentication failed due to an unknown cause. Error received: {{.V0}}" err_auth_token: - other: "Failed to create authentication token, please try again or run '[ACTIONABLE]state clean config[/RESET]' if the issue persists." + other: "Failed to create authentication token. Please try again or run '[ACTIONABLE]state clean config[/RESET]' if the issue persists." auth_err_password_prompt: other: The provided password is invalid signup_description: other: Signup a new account login_success_welcome_back: - other: You have successfully authenticated, hello [NOTICE]{{.Name}}[/RESET]! + other: You have successfully authenticated. Hello [NOTICE]{{.Name}}[/RESET]! logged_in_as: other: You are logged in as [NOTICE]{{.Name}}[/RESET] logout_description: @@ -145,14 +145,14 @@ err_unsupported_platform: other: "Unsupported platform: [NOTICE]{{.V0}}[/RESET]" err_detect_language: other: Could not detect which language to use -err_language_not_found: - other: "Could not find language: [NOTICE]{{.V0}}@{{.V1}}[/RESET]" project_checkout_empty: other: You have not activated any projects yet building: other: Building downloading: other: Downloading +unpacking: + other: Unpacking installing: other: Installing unknown_value: @@ -162,7 +162,7 @@ total: projects_description: other: List your projects err_api_not_authenticated: - other: You are not authenticated, authenticate with '[ACTIONABLE]state auth[/RESET]'. + other: You are not authenticated. Authenticate with '[ACTIONABLE]state auth[/RESET]'. err_api_forbidden: other: You are not allowed to access or modify the requested resource err_api_org_not_found: @@ -204,7 +204,7 @@ edit_script_cmd_expand_flag: edit_scripts_no_name: other: Could not find script with the given name [NOTICE]{{.V0}}[/RESET] edit_scripts_project_file_saved: - other: "\nScript changes detected, updating activestate.yaml" + other: "\nScript changes detected. Updating activestate.yaml" error_open_not_installed_lin: other: Please install '[ACTIONABLE]{{.V0}}[/RESET]' to edit scripts error_edit_script: @@ -253,6 +253,8 @@ field_localcheckouts: other: Local Checkouts field_platforms: other: Platforms +field_value: + other: Value err_conflicting_branch_while_checkedout: other: | Cannot activate branch [NOTICE]{{.V0}}[/RESET]. Branch [NOTICE]{{.V1}}[/RESET] is already checked out. @@ -300,7 +302,7 @@ secrets_expand_err_not_found: secrets_expand_err_no_access: other: You are not a member of organization '[NOTICE]{{.V0}}[/RESET]' and therefore cannot access secrets belonging to its projects secrets_err_invalid_namespace: - other: "Invalid namespace given for secret: [NOTICE]{{.V0}}[/RESET], namespace must be in format of 'scope.secretName', eg. 'user.mySecret' or 'project.ourSecret'." + other: "Invalid namespace given for secret: [NOTICE]{{.V0}}[/RESET]. Namespace must be in format of 'scope.secretName', eg. 'user.mySecret' or 'project.ourSecret'." secrets_warn_deprecated_var: other: "DEPRECATION WARNING: 'state variables' (or 'state vars') has been retired in favour of secrets and constants. Please use 'state secrets' instead." secrets_err_user_not_defined: @@ -308,7 +310,7 @@ secrets_err_user_not_defined: secrets_err_project_not_defined: other: "Secret has not been defined: [NOTICE]{{.V0}}[/RESET]. Either define it by running 'state secrets set [NOTICE]{{.V0}}[/RESET]' or have someone in your organization sync with you by having them run 'state secrets sync'." secrets_err_not_authenticated: - other: You are running a command that requires access to secrets, please authenticate by running 'state auth'. + other: You are running a command that requires access to secrets. Please authenticate by running 'state auth'. secrets_row_value_set: other: "[SUCCESS]✔ Defined[/RESET]" secrets_row_value_unset: @@ -334,7 +336,7 @@ keypairs_err_invalid_rsa_publickey: keypairs_err_load_not_found: other: 'Authorized keypair not found. Please refer to the docs for more info: https://docs.activestate.com/platform/state/advanced-topics/secrets/#setting-up-a-key-pair' keypairs_err_load_requires_mode: - other: 'Keypair [NOTICE]"{{.V0}}"[/RESET] file is too permissive, expects no more than [NOTICE]"{{.V1}}"[/RESET] permissions' + other: 'Keypair [NOTICE]"{{.V0}}"[/RESET] file is too permissive. It expects no more than [NOTICE]"{{.V1}}"[/RESET] permissions' keypairs_err_base64_decoding: other: Message is not base-64 encoded keypairs_err_override_with_save: @@ -352,7 +354,7 @@ err_file_not_found_in_path: secrets_err_expand_noproject: other: Expanding of variable failed because a project was not passed along. This indicates a problem in the underlying code, and is unlikely to be something an end-user can address. err_invalid_lock: - other: "Invalid lock specified in your activestate.yaml: '{{.V0}}', should be in the format of: [NOTICE]channel@{number}.{number}.{number}-{hash}[/RESET]" + other: "Invalid lock specified in your activestate.yaml: '{{.V0}}'. It should be in the format of: [NOTICE]channel@{number}.{number}.{number}-{hash}[/RESET]" update_available_header: other: "[ACTIONABLE]Update Available[/RESET]" update_available: @@ -390,14 +392,10 @@ installer_err_runtime_no_executable: other: Expected runtime installer '[NOTICE]{{.V0}}[/RESET]' to include '[ACTIONABLE]{{.V1}}[/RESET]' or '[ACTIONABLE]{{.V2}}[/RESET]' installer_err_runtime_no_file: other: Expected runtime installer '[NOTICE]{{.V0}}[/RESET]' to include '[ACTIONABLE]{{.V1}}[/RESET]' -installer_err_runtime_executable_not_exec: - other: Executable '[NOTICE]{{.V1}}[/RESET]' does not have execute permissions for runtime '[NOTICE]{{.V0}}[/RESET]' -installer_err_fail_obtain_prefixes: - other: Unable to obtain relocation prefixes for runtime '[NOTICE]{{.V0}}[/RESET]' build_status_in_progress: other: "Your changes are currently being built remotely on the ActiveState Platform. Please visit [NOTICE]{{.V0}}[/RESET] to see the progress." err_no_default_branch: - other: This project has no default branch. This indicates malformed data, please contact support! + other: This project has no default branch. This indicates malformed data. Please contact support! err_no_commit: other: Project branch has no commits err_order_marshal: @@ -423,9 +421,9 @@ err_no_platform_data_remains: err_runtime_setup: other: Error setting up runtime err_signs3_invalid_url: - other: API Responded with an invalid S3 URL, please contact support + other: API Responded with an invalid S3 URL. Please contact support err_invalid_namespace: - other: "Invalid namespace: [NOTICE]{{.V0}}[/RESET]. Should be in the format of [NOTICE]org/project[/RESET], and can optionally contain a [NOTICE]#COMMIT_ID[/RESET] suffix. Names should be alphanumeric and may contain dashes and periods." + other: "Invalid namespace: [NOTICE]{{.V0}}[/RESET]. It should be in the format of [NOTICE]org/project[/RESET], and can optionally contain a [NOTICE]#COMMIT_ID[/RESET] suffix. Names should be alphanumeric and may contain dashes and periods." err_invalid_commit_id: other: "Invalid commit ID: [NOTICE]{{.V0}}[/RESET]. It should be a valid UUID." err_invalid_project_name: @@ -433,9 +431,9 @@ err_invalid_project_name: err_could_not_get_commit_behind_count: other: Could not obtain commit history properly err_auth_required: - other: Authentication is required, please authenticate by running 'state auth' + other: Authentication is required. Please authenticate by running 'state auth' err_auth_needinput: - other: You are logged out, in order to log in either run this command in interactive mode or provide your credentials via flags (see '[ACTIONABLE]state auth --help[/RESET]'). + other: You are logged out. In order to log in either run this command in interactive mode or provide your credentials via flags (see '[ACTIONABLE]state auth --help[/RESET]'). prompt_login_or_signup: other: Would you like to login to an existing ActiveState Platform account, or create a new account? prompt_login_browser_action: @@ -445,7 +443,7 @@ prompt_login_action: prompt_signup_browser_action: other: Signup for a new account using the ActiveState Platform website err_browser_open: - other: "Could not open your browser, please manually open the following URL above." + other: "Could not open your browser. Please manually open the following URL above." err_os_not_a_directory: other: Expected '{{.V0}}' to be a valid directory export_cmd_description: @@ -486,18 +484,6 @@ field_version: other: Version field_bitwidth: other: Bit Width -commit_message_added_platform: - other: "Added platform: {{.V0}} {{.V1}}bit {{.V2}}" -commit_message_updated_platform: - other: "Updated platform: {{.V0}} to {{.V1}}" -commit_message_removed_platform: - other: "Removed platform: {{.V0}} {{.V1}}bit {{.V2}}" -commit_message_added_language: - other: "Added language: {{.V0}} {{.V1}}" -commit_message_updated_language: - other: "Updated language: {{.V0}} to {{.V1}}" -commit_message_removed_language: - other: "Removed language: {{.V0}} {{.V1}}" fileutils_err_amend_file: other: "Could not edit file: [NOTICE]{{.V0}}[/RESET]" err_auth_empty_token: @@ -527,17 +513,17 @@ auth_device_timeout: auth_device_success: other: Successfully authorized this device err_prompt_bad_flag: - other: Could not validate input due to an unexpected flag, please contact support if this problem persists + other: Could not validate input due to an unexpected flag. Please contact support if this problem persists err_invalid_project: other: Your activestate.yaml is missing the 'project' field. err_bad_project_url: - other: "Invalid value for 'project' field in your activestate.yaml, please ensure it is in the format of: 'https://platform.activestate.com/org/project'." + other: "Invalid value for 'project' field in your activestate.yaml. Please ensure it is in the format of: 'https://platform.activestate.com/org/project'." err_set_commit_id: other: "Could not update your activestate.yaml with the latest commit ID. Please ensure you have your project defined in the format of '[ACTIONABLE]project: https://platform.activestate.com/org/project[/RESET]'" err_set_project: other: "Could not update the project field in your activestate.yaml. Please ensure you have your project defined in the format of '[ACTIONABLE]project: https://platform.activestate.com/org/project[/RESET]'" err_unauthorized: - other: You are not authorized, did you provide valid login credentials? + other: You are not authorized. Did you provide valid login credentials? err_projectfile_exists: other: A project already exists in the specified directory err_projectfile_invalid_url: @@ -599,19 +585,17 @@ package_search_flag_ns_description: package_flag_ts_description: other: The timestamp at which you want to query. Can be either 'now' or RFC3339 formatted timestamp. package_flag_rev_description: - other: The revision you want to use, this ensures you get this exact revision and nothing else. + other: The revision you want to use. This ensures you get this exact revision and nothing else. package_search_flag_language_description: other: The language used to constrain search results package_search_flag_exact-term_description: other: Ensures that search results match search term exactly package_import_flag_filename_description: other: The file to import -commit_message_added_package: - other: "Added package: {{.V0}}@{{.V1}}" -commit_message_removed_package: - other: "Removed package: {{.V0}}" -commit_message_updated_package: - other: "Updated package: {{.V0}} to {{.V1}}" +commit_message_added: + other: "Added: {{.V0}}" +commit_message_removed: + other: "Removed: {{.V0}}" commit_message_add_initial: other: Initialize project via the State Tool commit_reqstext_message: @@ -622,8 +606,6 @@ err_bundle_added: other: Failed to add bundle err_language_updated: other: Failed to update language -package_err_cannot_fetch_checkpoint: - other: Cannot fetch checkpoint for package listing bundle_err_cannot_fetch_checkpoint: other: Cannot fetch checkpoint for bundle listing package_err_cannot_obtain_commit: @@ -646,54 +628,12 @@ package_name: other: Name package_version: other: Version -package_added: - other: "Package added: [NOTICE]{{.V0}}[/RESET]" -package_version_added: - other: "Package added: [NOTICE]{{.V0}}@{{.V1}}[/RESET]" -bundle_added: - other: "[SUCCESS]✔ {{.V0}} Bundle successfully installed![/RESET]" -bundle_version_added: - other: "[SUCCESS]✔ {{.V0}} Bundle @ version {{.V1}} successfully installed![/RESET]" -language_updated: - other: "Language updated: [NOTICE]{{.V0}}[/RESET]" -language_version_updated: - other: "Language updated: [NOTICE]{{.V0}}@{{.V1}}[/RESET]" -err_package_updated: - other: Failed to update package -err_bundle_updated: - other: Failed to update bundle -package_updated: - other: "Package updated: [NOTICE]{{.V0}}[/RESET]" -package_version_updated: - other: "Package updated: [NOTICE]{{.V0}}@{{.V1}}[/RESET]" -bundle_updated: - other: "Bundle updated: [NOTICE]{{.V0}}[/RESET]" -bundle_version_updated: - other: "Bundle updated: [NOTICE]{{.V0}}@{{.V1}}[/RESET]" -err_package_removed: - other: Failed to remove package err_remove_requirement_not_found: other: Could not remove requirement '[ACTIONABLE]{{.V0}}[/RESET]', because it does not exist. -err_bundle_removed: - other: Failed to remove bundle -err_packages_removed: - other: Failed to remove packages -package_removed: - other: "Package uninstalled: [NOTICE]{{.V0}}[/RESET]" -bundle_removed: - other: "Bundle uninstalled: [NOTICE]{{.V0}}[/RESET]" +err_remove_platform_not_found: + other: Could not remove platform '[ACTIONABLE]{{.V0}}[/RESET]', because it does not exist. err_update_build_script: other: Could not update runtime build script -raw_version_added: - other: "Package added: [NOTICE]{{.V0}}@{{.V1}}[/RESET]" -raw_added: - other: "Package added: [NOTICE]{{.V0}}[/RESET]" -raw_version_updated: - other: "Package updated: [NOTICE]{{.V0}}@{{.V1}}[/RESET]" -raw_updated: - other: "Package updated: [NOTICE]{{.V0}}[/RESET]" -raw_removed: - other: "Package removed: [NOTICE]{{.V0}}[/RESET]" notice_commit_build_script: other: | Your local build script has changes that should be committed. Please run '[ACTIONABLE]state commit[/RESET]' to do so. @@ -702,14 +642,10 @@ command_flag_invalid_value: other: "Invalid value for {{.V0}} flag: [NOTICE]{{.V1}}[/RESET]" command_cmd_no_such_cmd: other: "No such command: [NOTICE]{{.V0}}[/RESET]" -err_fetch_languages: - other: "Could not retrieve languages for your project. Does your project exist on the Platform?" err_incompatible_move_file_dir: other: | Could not move [NOTICE]{{.V0}}[/RESET] to [NOTICE]{{.V1}}[/RESET]. One is a file, the other a directory. This indicates that the requested build may be corrupted. -err_init_lang: - other: "Invalid language: {{.V0}}@{{.V1}}" initializing_project: other: | Initializing Project @@ -756,7 +692,7 @@ push_prompt_not_authorized: Either get the project owner to invite you, or create a new project with these changes. Would you like to create a new project with your changes now? export_privkey_cmd_description: - other: Exports the private key, useful if you want to set it via environment variable (ACTIVESTATE_PRIVATE_KEY) + other: Exports the private key. This is useful if you want to set it via environment variable (ACTIVESTATE_PRIVATE_KEY) err_unknown_format: other: "Unknown format: [NOTICE]{{.V0}}[/RESET]" err_sprint: @@ -764,13 +700,13 @@ err_sprint: field_localized_field: other: "Localized Field" err_could_not_marshal_print: - other: "Could not marshal the value being printed, please check the error log for more information." + other: "Could not marshal the value being printed. Please check the error log for more information." err_no_structured_output: other: "This command does not support the '{{.V0}}' output format. Please try again without that output flag." err_unsupported_structured_output: other: "Failed to structure output in the requested format. Please consider reporting this on our forums: {{.V0}}." err_main_outputer: - other: "Could not create output writer, please contact developers if this problem persists. Error: {{.V0}}" + other: "Could not create output writer. Please contact developers if this problem persists. Error: {{.V0}}" field_name: other: Name field_description: @@ -864,10 +800,6 @@ languages_install_cmd_description: other: Update the language of a project arg_languages_install_description: other: The language to update in the form of @ -err_language_format: - other: The language and version provided is not formatting correctly, must be in the form of @ -err_language_mismatch: - other: Cannot change languages, only changes to the current project's language is allowed err_no_recipes: other: No build recipes could be generated for the current project err_order_unknown: @@ -888,7 +820,7 @@ arg_state_deploy_namespace: arg_state_deploy_namespace_description: other: The namespace of the project that you wish to deploy err_deploy_no_commits: - other: "The project '[NOTICE]{{.V0}}[/RESET]' does not have any packages configured, please add add some packages first." + other: "The project '[NOTICE]{{.V0}}[/RESET]' does not have any packages configured. Please add add some packages first." err_windows_registry: other: Error while interacting with Windows registry err_deploy_run_install: @@ -919,7 +851,7 @@ deploy_configure_cmd_description: deploy_symlink_cmd_description: other: Symlink the executables to your PATH and to the target directory (must have run install first or this will error) deploy_report_cmd_description: - other: Reports information about the deployed runtime environment, useful for further manual setup (must have run install first or this will error) + other: Reports information about the deployed runtime environment. This is useful for further manual setup (you must have run install first or this will error) deploy_restart_shell: other: | Please restart your terminal or start a new terminal session in order to start using the newly configured Runtime Environment. @@ -938,24 +870,12 @@ deploy_uninstall_success: Successfully removed deployment. Please restart your terminal or start a new terminal session in order to clear any residual Runtime Environment variables and settings. -envdef_file_not_found: - other: | - Your installation seems to be corrupted. - - Cannot find runtime definition file at [NOTICE]{{.V0}}[/RESET]. - You can try to manually delete the cache directory and re-activating the project. -envdef_unmarshal_error: - other: | - Your installation seems to be corrupted. - - Cannot not parse runtime definition file at [NOTICE]{{.V0}}[/RESET] - This indicates a problem with the build. You can try updating your project err_arg_required: other: "The following argument is required:\n Name: [NOTICE]{{.V0}}[/RESET]\n Description: [NOTICE]{{.V1}}[/RESET]" err_init_no_language: other: "A project has not been set using 'state use'. You must include the [NOTICE]language[/RESET] argument. For more help, run '[ACTIONABLE]state init --help[/RESET]'." platform_added: - other: "[NOTICE]{{.V0}}@{{.V1}}[/RESET] has been added." + other: "[NOTICE]{{.V0}}[/RESET] has been added." platform_removed: other: "[NOTICE]{{.V0}}@{{.V1}}[/RESET] has been removed." deploy_usable_path: @@ -1025,7 +945,7 @@ err_non_interactive_mode: other: You are running the State Tool in non-interactive mode, but interactive input was needed. Please re-run the State Tool in interactive mode. If you are using a non-interactive terminal like Git Bash on Windows, prefix your command with '[ACTIONABLE]winpty[/RESET]'. (See https://github.com/git-for-windows/git/wiki/FAQ#some-native-console-programs-dont-work-when-run-from-git-bash-how-to-fix-it for more information.) err_alternate_branches: other: | - Your current platform ([ACTIONABLE]{{.V0}}/{{.V1}}[/RESET]) does not appear to be configured in your branch: '[ACTIONABLE]{{.V2}}[/RESET]', perhaps you could try one of the alternate branches on your project: + Your current platform ([ACTIONABLE]{{.V0}}/{{.V1}}[/RESET]) does not appear to be configured in your branch: '[ACTIONABLE]{{.V2}}[/RESET]'. Perhaps you could try one of the alternate branches on your project: - {{.V3}} @@ -1033,13 +953,13 @@ err_alternate_branches: err_fetch_project: other: "Could not fetch details for project: {{.V0}}" err_set_default_branch: - other: Could not update project field with branch, please manually set the `branch={{.V0}}` query parameter on the project field in your activestate.yaml. + other: Could not update project field with branch. Please manually set the `branch={{.V0}}` query parameter on the project field in your activestate.yaml. artifact_download_failed: other: Failed to download artifact '{{.V0}}' ({{.V1}}) artifact_setup_failed: other: Failed to install artifact '{{.V0}}' ({{.V1}}) err_stored_artifacts: - other: Could not unmarshal stored artifacts, your install may be corrupted. + other: Could not unmarshal stored artifacts. Your install may be corrupted. err_fetch_branch: other: "Could not get branch [NOTICE]{{.V0}}[/RESET] for project" err_refresh_runtime: @@ -1053,7 +973,7 @@ err_user_network_solution: err_user_network_timeout: other: "Request failed due to timeout. {{.V0}}" err_user_libc_solution: - other: If you specified a glibc version, please check it is configured → [ACTIONABLE]{{.V0}}[/RESET]. + other: If you specified a glibc version. Please check it is configured → [ACTIONABLE]{{.V0}}[/RESET]. warn_revert_head: other: | [NOTICE]DEPRECATION WARNING[/RESET]: 'state revert HEAD' has been deprecated in favor of '[ACTIONABLE]state revert REMOTE[/RESET]'. Please use '[ACTIONABLE]state revert REMOTE[/RESET]' instead. @@ -1075,9 +995,9 @@ err_push_outdated: err_tip_push_outdated: other: Run '[ACTIONABLE]state pull[/RESET]'. err_push_not_authenticated: - other: In order to update your project you need to be authenticated, please run '[ACTIONABLE]state auth[/RESET]' to authenticate. + other: In order to update your project you need to be authenticated. Please run '[ACTIONABLE]state auth[/RESET]' to authenticate. err_push_no_project: - other: No project found, you may need to create one first. + other: No project found. You may need to create one first. err_push_headless: other: Cannot push a headless project. To convert your project please visit {{.V0}} push_push_tip_headless_init: @@ -1085,7 +1005,7 @@ push_push_tip_headless_init: push_push_tip_headless_cwd: other: Navigate to a directory with an activestate.yaml. err_push_nocommit: - other: You have nothing to push, make some changes first with '[ACTIONABLE]state install[/RESET]'. + other: You have nothing to push. Make some changes first with '[ACTIONABLE]state install[/RESET]'. push_no_changes: other: You have no local changes to push. To pull in remote changes run '[ACTIONABLE]state pull[/RESET]'. err_push_create_nonunique: @@ -1104,11 +1024,11 @@ operation_success_local: Your local project has been updated. Run [ACTIONABLE]state push[/RESET] to save changes to the platform. buildplan_err: - other: "Could not plan build, platform responded with:\n{{.V0}}" + other: "Could not plan build. Platform responded with:\n{{.V0}}" buildplan_err_cropped: - other: "Could not plan build, platform responded with:\n{{.V0}}\n{{.V1}}" + other: "Could not plan build. Platform responded with:\n{{.V0}}\n{{.V1}}" err_buildplanner_head_on_branch_moved: - other: The branch you're trying to update has changed remotely, please run '[ACTIONABLE]state pull[/RESET]'. + other: The branch you're trying to update has changed remotely. Please run '[ACTIONABLE]state pull[/RESET]'. transient_solver_tip: other: You may want to retry this command if the failure was related to a resourcing or networking issue. warning_git_project_mismatch: @@ -1161,29 +1081,31 @@ err_exec_recursion: To allow recursion, set [ACTIONABLE]{{.V1}}=true[/RESET] package_ingredient_alternatives: other: | - No results found for search term "[NOTICE]{{.V0}}[/RESET]", did you mean: + No results found for search term {{.V0}}. Did you mean: {{.V1}} - Run "[ACTIONABLE]state search {{.V0}}[/RESET]" to see more suggestions. + Use "[ACTIONABLE]state search[/RESET]" to find more suggestions. package_ingredient_alternatives_nosuggest: other: | - No results found for search term "[NOTICE]{{.V0}}[/RESET]". + No results found for search term {{.V0}}. - Run "[ACTIONABLE]state search {{.V0}}[/RESET]" to find alternatives. -package_ingredient_alternatives_nolang: + Use "[ACTIONABLE]state search[/RESET]" to find alternatives. +package_requirements_no_match: other: | - No results found for search term "[NOTICE]{{.V0}}[/RESET]". + No results found for following packages: {{.V0}}. - This may be because you have not installed a language for your project. Install a language by running "[ACTIONABLE]state languages install [/RESET]". + Run "[ACTIONABLE]state search {{.V0}}[/RESET]" to find alternatives. progress_search: - other: " • Searching for [ACTIONABLE]{{.V0}}[/RESET] in the ActiveState Catalog" + other: "• Searching for packages in the ActiveState Catalog" +progress_platform_search: + other: "• Searching for platform in the ActiveState Catalog" progress_cve_search: - other: " • Searching for new vulnerabilities (CVEs) on [ACTIONABLE]{{.V0}}[/RESET] and any dependencies" + other: "• Checking for vulnerabilities (CVEs) on [ACTIONABLE]{{.V0}}[/RESET] and its dependencies" setup_runtime: other: "Setting Up Runtime" progress_solve: - other: "Resolving Dependencies" + other: "• Resolving Dependencies" additional_dependencies: other: Installing {{.V0}} includes [ACTIONABLE]{{.V1}}[/RESET] direct dependencies. additional_total_dependencies: @@ -1199,11 +1121,11 @@ progress_safe: progress_unsafe: other: " [ERROR]x Unsafe[/RESET]" progress_commit: - other: " • Creating commit" + other: "• Creating commit" progress_solve_preruntime: - other: " • Resolving Dependencies" + other: "• Resolving Dependencies" progress_pkg_nolang: - other: " • Searching for [ACTIONABLE]{{.V0}}[/RESET] across all languages in the ActiveState Catalog" + other: "• Searching for [ACTIONABLE]{{.V0}}[/RESET] across all languages in the ActiveState Catalog" progress_build_log: other: "Build Log [ACTIONABLE]{{.V0}}[/RESET]" progress_completed: @@ -1223,10 +1145,21 @@ warning_vulnerable_indirectonly: warning_vulnerable_directonly: other: | [ERROR]Warning: Dependency has {{.V0}} known vulnerabilities (CVEs)[/RESET] +cve_critical: + other: Critical +cve_high: + other: High +cve_medium: + other: Medium +cve_low: + other: Low more_info_vulnerabilities: other: For more information on these vulnerabilities run '[ACTIONABLE]state security open [/RESET]'. disable_prompting_vulnerabilities: - other: To disable prompting for vulnerabilities run '[ACTIONABLE]state config set security.prompt.enable false[/RESET]'. + other: To disable prompting for vulnerabilities run '[ACTIONABLE]state config set security.prompt.enabled false[/RESET]'. +warning_vulnerable_short: + other: | + [ERROR]Warning:[/RESET] Dependency has [ERROR]{{.V0}} known vulnerabilities (CVEs)[/RESET]. Severity: {{.V1}}. Run '[ACTIONABLE]state security[/RESET]' for more info. prompt_continue_pkg_operation: other: | Do you want to continue installing this dependency despite its vulnerabilities? @@ -1275,15 +1208,13 @@ err_project_frompath_notexist: err_project_namespace_missmatch: other: Project at [ACTIONABLE]{{.V0}}[/RESET] does not match namespace [ACTIONABLE]{{.V1}}[/RESET] err_project_fromenv: - other: Could not detect an appropriate project to use, please provide a valid path or namespace. + other: Could not detect an appropriate project to use. Please provide a valid path or namespace. err_local_project_not_checked_out: other: "Cannot find the [ACTIONABLE]{{.V0}}[/RESET] project. Please either check it out using '[ACTIONABLE]state checkout[/RESET]' or run this command again from the project directory." err_findproject_notfound: other: "Could not load project [ACTIONABLE]{{.V0}}[/RESET] from path: [ACTIONABLE]{{.V1}}[/RESET]" arg_state_shell_namespace_description: other: The namespace of the project you wish to start a virtual environment shell/prompt for, or just the project name if previously used -err_language_by_commit: - other: Could not get language from commit ID {{.V0}} err_parse_project: other: Could not parse project file at {{.V0}} err_uninstall_privilege_mismatch: @@ -1377,11 +1308,13 @@ shell_project_statement: Opening shell for project [ACTIONABLE]{{.V0}}[/RESET], located at [ACTIONABLE]{{.V1}}[/RESET]. This shell is operating inside a virtual environment. For editors and other tooling use the executables at: [ACTIONABLE]{{.V2}}[/RESET]. +arg_state_checkout_namespace: + other: org/project +arg_state_checkout_namespace_description: + other: The namespace of the project that you wish to checkout, or the path to a project archive (.tar.gz) to checkout checking_out: other: | Checking out project: [NOTICE]{{.V0}}[/RESET] -installing_runtime_title: - other: Installing Runtime checkout_project_statement: other: | Checked out project [ACTIONABLE]{{.V0}}[/RESET], located at [ACTIONABLE]{{.V1}}[/RESET]. @@ -1410,7 +1343,7 @@ err_rtprogress_outofsync: Please report this issue on [ACTIONABLE]{{.V0}}[/RESET] and include your log file at [ACTIONABLE]{{.V1}}[/RESET]. warning_macos_bash: other: | - You are running bash on macOS, which is no longer supported by Apple. To update your account to use zsh, please run 'chsh -s /bin/zsh'. If you continue to use bash you may run into issues finding binaries on your PATH, in order to work around these issues please read: https://scriptingosx.com/2017/04/about-bash_profile-and-bashrc-on-macos/ + You are running bash on macOS, which is no longer supported by Apple. To update your account to use zsh, please run 'chsh -s /bin/zsh'. If you continue to use bash you may run into issues finding binaries on your PATH. In order to work around these issues please read: https://scriptingosx.com/2017/04/about-bash_profile-and-bashrc-on-macos/ operating_message: other: | Operating on project [ACTIONABLE]{{.V0}}[/RESET], located at [ACTIONABLE]{{.V1}}[/RESET]. @@ -1432,6 +1365,10 @@ err_commit_id_invalid: other: "Your activestate.yaml contains an invalid commit ID: '{{.V0}}'. Please run '[ACTIONABLE]state reset[/RESET]' to fix it." err_commit_id_invalid_given: other: "Invalid commit ID: '{{.V0}}'." +err_commit_id_not_in_history: + other: "The project '[ACTIONABLE]{{.V0}}[/RESET]' does not contain the provided commit: '[ACTIONABLE]{{.V1}}[/RESET]'." +err_outdated_buildscript: + other: "[WARNING]Warning:[/RESET] You are using an outdated version of the buildscript. Please run '[ACTIONABLE]state reset LOCAL[/RESET]' in order to reinitialize your buildscript file." err_shortcutdir_writable: other: Could not continue as we don't have permission to create [ACTIONABLE]{{.V0}}[/RESET]. move_prompt: @@ -1446,10 +1383,8 @@ err_edit_local_checkouts: other: Could not update local checkouts err_edit_project_mapping: other: Could not update project mapping -notice_runtime_disabled: - other: Skipping runtime setup because it was disabled by an environment variable err_searchingredient_toomany: - other: Too many ingredients match the query '[ACTIONABLE]{{.V0}}[/RESET]', please try to be more specific. + other: Too many ingredients match the query '[ACTIONABLE]{{.V0}}[/RESET]'. Please try to be more specific. alternative_unknown_pkg_name: other: unknown err_uploadingredient_publish: @@ -1471,7 +1406,7 @@ uploadingredient_success: You can install this package by running `[ACTIONABLE]state install {{.V1}}/{{.V0}} --ts now`[/RESET]. err_runtime_cache_invalid: - other: Your runtime needs to be updated, please run '[ACTIONABLE]state refresh[/RESET]'. + other: Your runtime needs to be updated. Please run '[ACTIONABLE]state refresh[/RESET]'. err_buildscript_not_exist: other: Your project does not have a buildscript.as file. Please refer to the documentation on how to create one. commit_success: @@ -1497,7 +1432,7 @@ warn_build_not_complete: other: "[WARNING]Some artifacts are still being built. Try running this command again in a few minutes.[/RESET]" err_build_artifacts_failed: other: | - The following artifacts failed to build, please refer to their logs for more information: + The following artifacts failed to build. Please refer to their logs for more information: {{.V0}} err_build_artifact_failed_msg: @@ -1510,9 +1445,12 @@ err_build_artifact_failed: err_packages_update_runtime_init: other: Could not initialize runtime. pkg_already_uptodate: - other: Requested dependencies are already configured and installed. + other: Dependencies for your project are already configured and installed. +notice_async_runtime: + other: | + [WARNING]Warning:[/RESET] Skipping runtime sourcing since {{.V0}} is enabled. Please run '[ACTIONABLE]state refresh[/RESET]' to manually source the runtime. install_runtime: - other: Installing Runtime + other: Sourcing Runtime install_runtime_info: other: "Installing your runtime and dependencies.\n" update_runtime: @@ -1528,17 +1466,12 @@ err_projectfile_version_too_high: err_headless: other: Cannot operate on a headless project. Please visit {{.V0}} to convert your project and try again. notice_needs_buildscript_reset: - other: Your project is missing its buildscript file, please run '[ACTIONABLE]state reset LOCAL[/RESET]' to recreate it. - -err_initial_no_requirement: - other: | - Could not find compatible requirement for initial commit. Please ensure that you are trying to install a valid package. - To check for available packages run '[ACTIONABLE]state search [/RESET]'. + other: Your project is missing its buildscript file. Please run '[ACTIONABLE]state reset LOCAL[/RESET]' to recreate it. manifest_deprecation_warning: other: | - [WARNING]Warning:[/RESET] This command is deprecated, please use '[ACTIONABLE]state manifest[/RESET]' instead. + [WARNING]Warning:[/RESET] This command is deprecated. Please use '[ACTIONABLE]state manifest[/RESET]' instead. manifest_runtime_needs_update: - other: "[WARNING]WARNING:[/RESET] Your runtime is out of date, in order to ensure an accurate manifest please run [ACTIONABLE]state refresh[/RESET].\n" + other: "[WARNING]WARNING:[/RESET] Your runtime is out of date. In order to ensure an accurate manifest please run [ACTIONABLE]state refresh[/RESET].\n" vulnerability_critical: other: "[RED]{{.V0}} Critical[/RESET]" vulnerability_high: @@ -1549,15 +1482,95 @@ vulnerability_low: other: "[GREEN]{{.V0}} Low[/RESET]" err_main_jwt: other: | - State Tool could not obtain an authentication token from its internal service. - Please try again or contact support if this issue persists. + State Tool could not obtain an authentication token from its internal service. + Please try again or contact support if this issue persists. Error received: {{.V0}} -err_runtime_needs_refresh: - other: Your runtime needs to be updated, please run '[ACTIONABLE]state refresh[/RESET]' and then try again. err_pull_no_common_parent: other: | The local commit ID [NOTICE]{{.V0}}[/RESET] and latest remote commit ID [NOTICE]{{.V1}}[/RESET] have no common parent. To review your project history run '[ACTIONABLE]state history[/RESET]'. -warn_package_list_runtime: - other: | - [WARNING]WARNING:[/RESET] Could not initialize runtime. Resolved version information will not be available. Run '[ACTIONABLE]state refresh[/RESET]' for more information. +refresh_runtime_uptodate: + other: Your runtime is already up to date. +warn_additional_requirements: + other: | + [WARNING]WARNING:[/RESET] This project has additional build criteria that cannot be managed through the State Tool. Please edit your [ACTIONABLE]buildscript.as[/RESET] file manually to modify these: +migrate_project_error: + other: Could not migrate your project files. Please address any errors and try again. For full detail view your log file with '[ACTIONABLE]state export log -i 0[/RESET]'. +upgrade_solving: + other: • Searching for available upgrades for your requirements +upgrade_confirm: + other: Would you like to install these upgrades? +upgrade_no_changes: + other: No upgrades were found for your project. Note that requirements with fixed version numbers will never be upgraded. +upgrade_aborted: + other: Upgrade aborted +upgrade_success: + other: Upgrade completed +upgrade_field_same: + other: "[CYAN]{{.V0}}[/RESET]" +upgrade_field_change: + other: "[CYAN]{{.V0}}[/RESET] > [BOLD][ACTIONABLE]{{.V1}}[/RESET]" +name: + other: Name +version: + other: Version +license: + other: License +key: + other: Key +value: + other: Value +default: + other: Default +vulnerabilities: + other: Vulnerabilities (CVEs) +dependency_row: + other: " [DISABLED]{{.V0}}[/RESET] [CYAN]{{.V1}}[/RESET] [DISABLED]transitive dependencies touched[/RESET]" +dependency_detail_row: + other: " [DISABLED]{{.V0}} {{.V1}}[/RESET] {{.V2}}" +namespace_row: + other: " [DISABLED]{{.V0}} namespace:[/RESET] [CYAN]{{.V1}}[/RESET]" +flag_state_upgrade_expand_description: + other: Show individual transitive dependency changes rather than a summary +flag_state_upgrade_ts_description: + other: Manually specify the timestamp to 'upgrade' to. Can be either 'now' or RFC3339 formatted timestamp. +platform_add_not_found: + other: Could not find a platform matching your criteria +err_uninstall_nomatch: + other: "The following package(s) could not be found in your project: {{.V0}}" +err_uninstall_multimatch: + other: | + The following terms match multiple requirements in your project: [ACTIONABLE]{{.V0}}[/RESET]. + Please specify the requirement to uninstall by using its full namespace. + To view the namespace of your project requirements run: [ACTIONABLE]state manifest[/RESET]. +err_uninstall_platform_nomatch: + other: "The specified platform does not exist in your project" +err_uninstall_platform_multimatch: + other: | + The platform query you provided matches multiple platforms in your project. + Please specify the platform to uninstall by using its version and bit-width. + To view the platforms your project uses run: [ACTIONABLE]state platforms[/RESET]. +progress_requirements: + other: "• Updating requirements" +progress_platforms: + other: "• Updating platforms" +prompt_pkgop_ingredient: + other: Multiple Matches +prompt_pkgop_ingredient_msg: + other: "Your query for [ACTIONABLE]{{.V0}}[/RESET] has multiple matches. Which one would you like to use?" +install_report_added: + other: "Added: [NOTICE]{{.V0}}[/RESET]" +install_report_updated: + other: "Updated: [NOTICE]{{.V0}}[/RESET]" +install_report_removed: + other: "Removed: [NOTICE]{{.V0}}[/RESET]" +err_commit_invalid_deps_value_type: + other: "Your buildscript contains an ingredient() function call with an invalid value type for its dependencies" +err_commit_invalid_dep_value_type: + other: "Your buildscript contains an ingredient() function call with an invalid value type for one of its dependencies" +config_get_help: + other: "To GET the value for a specific config key run '[ACTIONABLE]state config get [/RESET]'" +config_set_help: + other: "To SET the value for a specific config key run '[ACTIONABLE]state config set [/RESET]'" +err_clean_in_use: + other: "Could not clean your cache as you appear to have a runtime in use. Please stop any running State Tool processes and project runtime processes and try again." diff --git a/internal/logging/defaults.go b/internal/logging/defaults.go index 5ef19f38f7..68a5c897bf 100644 --- a/internal/logging/defaults.go +++ b/internal/logging/defaults.go @@ -97,6 +97,4 @@ func init() { SetHandler(handler) handler.SetVerbose(os.Getenv("VERBOSE") != "") log.SetOutput(&writer{}) - - Debug("Args: %v", os.Args) } diff --git a/internal/logging/logging.go b/internal/logging/logging.go index 6f0c5e6f73..1ac62a772b 100644 --- a/internal/logging/logging.go +++ b/internal/logging/logging.go @@ -128,6 +128,7 @@ type LoggingHandler interface { type standardHandler struct { formatter Formatter + verbose bool } func (l *standardHandler) SetFormatter(f Formatter) { @@ -135,6 +136,7 @@ func (l *standardHandler) SetFormatter(f Formatter) { } func (l *standardHandler) SetVerbose(v bool) { + l.verbose = v } func (l *standardHandler) Output() io.Writer { @@ -143,7 +145,9 @@ func (l *standardHandler) Output() io.Writer { // default handling interface - just func (l *standardHandler) Emit(ctx *MessageContext, message string, args ...interface{}) error { - fmt.Fprintln(os.Stderr, l.formatter.Format(ctx, message, args...)) + if l.verbose { + fmt.Fprintln(os.Stderr, l.formatter.Format(ctx, message, args...)) + } return nil } @@ -158,6 +162,7 @@ func (l *standardHandler) Close() {} var currentHandler LoggingHandler = &standardHandler{ DefaultFormatter, + os.Getenv("VERBOSE") != "", } // Set the current handler of the library. We currently support one handler, but it might be nice to have more diff --git a/internal/mediators/config/registry.go b/internal/mediators/config/registry.go index 767d87caa6..f6f327f53d 100644 --- a/internal/mediators/config/registry.go +++ b/internal/mediators/config/registry.go @@ -1,17 +1,27 @@ package config +import "sort" + type Type int const ( String Type = iota Int Bool + Enum ) // Event is run when a user tries to set or get a config value via `state config` type Event func(value interface{}) (interface{}, error) -var EmptyEvent = func(value interface{}) (interface{}, error) { return value, nil } +var EmptyEvent = func(value interface{}) (interface{}, error) { + if enum, ok := value.(*Enums); ok { + // In case this config option is not set, return its default value instead + // of the Enums struct itself. + return enum.Default, nil + } + return value, nil +} // Option defines what a config value's name and type should be, along with any get/set events type Option struct { @@ -21,32 +31,73 @@ type Option struct { GetEvent Event SetEvent Event isRegistered bool + isHidden bool } type Registry map[string]Option var registry = make(Registry) +type Enums struct { + Options []string + Default string +} + +func NewEnum(options []string, default_ string) *Enums { + return &Enums{options, default_} +} + // GetOption returns a config option, regardless of whether or not it has been registered. // Use KnownOption to determine if the returned option has been previously registered. func GetOption(key string) Option { rule, ok := registry[key] if !ok { - return Option{key, String, "", EmptyEvent, EmptyEvent, false} + return Option{key, String, "", EmptyEvent, EmptyEvent, false, false} } return rule } // Registers a config option without get/set events. func RegisterOption(key string, t Type, defaultValue interface{}) { - RegisterOptionWithEvents(key, t, defaultValue, EmptyEvent, EmptyEvent) + registerOption(key, t, defaultValue, EmptyEvent, EmptyEvent, false) +} + +// Registers a hidden config option without get/set events. +func RegisterHiddenOption(key string, t Type, defaultValue interface{}) { + registerOption(key, t, defaultValue, EmptyEvent, EmptyEvent, true) } // Registers a config option with get/set events. func RegisterOptionWithEvents(key string, t Type, defaultValue interface{}, get, set Event) { - registry[key] = Option{key, t, defaultValue, get, set, true} + registerOption(key, t, defaultValue, get, set, false) +} + +func registerOption(key string, t Type, defaultValue interface{}, get, set Event, hidden bool) { + registry[key] = Option{key, t, defaultValue, get, set, true, hidden} } func KnownOption(rule Option) bool { return rule.isRegistered } + +func GetDefault(opt Option) interface{} { + if enum, ok := opt.Default.(*Enums); ok { + return enum.Default + } + return opt.Default +} + +// Registered returns all registered options, excluding hidden ones +func Registered() []Option { + var opts []Option + for _, opt := range registry { + if opt.isHidden { + continue + } + opts = append(opts, opt) + } + sort.SliceStable(opts, func(i, j int) bool { + return opts[i].Name < opts[j].Name + }) + return opts +} diff --git a/internal/migrator/migrator.go b/internal/migrator/migrator.go index 8fe9d087a9..cfb69eec18 100644 --- a/internal/migrator/migrator.go +++ b/internal/migrator/migrator.go @@ -1,19 +1,24 @@ package migrator import ( - "path/filepath" - "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/runbits/buildscript" "github.com/ActiveState/cli/pkg/platform/authentication" + "github.com/ActiveState/cli/pkg/platform/model" "github.com/ActiveState/cli/pkg/projectfile" ) -func NewMigrator(auth *authentication.Auth, cfg *config.Instance) projectfile.MigratorFunc { - return func(project *projectfile.Project, configVersion int) (int, error) { +func NewMigrator(auth *authentication.Auth, cfg *config.Instance, svcm *model.SvcModel) projectfile.MigratorFunc { + return func(project *projectfile.Project, configVersion int) (v int, rerr error) { + defer func() { + if rerr != nil { + rerr = locale.WrapError(rerr, "migrate_project_error") + } + }() for v := project.ConfigVersion; v < configVersion; v++ { logging.Debug("Migrating project from version %d", v) switch v { @@ -22,7 +27,7 @@ func NewMigrator(auth *authentication.Auth, cfg *config.Instance) projectfile.Mi case 0: if cfg.GetBool(constants.OptinBuildscriptsConfig) { logging.Debug("Creating buildscript") - if err := buildscript_runbit.Initialize(filepath.Dir(project.Path()), auth); err != nil { + if err := buildscript_runbit.Initialize(project, auth, svcm); err != nil { return v, errs.Wrap(err, "Failed to initialize buildscript") } } diff --git a/internal/osutils/autostart/autostart_darwin.go b/internal/osutils/autostart/autostart_darwin.go index d5299d1fcd..39cb80e933 100644 --- a/internal/osutils/autostart/autostart_darwin.go +++ b/internal/osutils/autostart/autostart_darwin.go @@ -6,6 +6,7 @@ import ( "path/filepath" "github.com/ActiveState/cli/internal/assets" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/logging" @@ -89,6 +90,9 @@ func autostartPath(_ string, opts Options) (string, error) { if err != nil { return "", errs.Wrap(err, "Could not get home directory") } + if testDir, ok := os.LookupEnv(constants.AutostartPathOverrideEnvVarName); ok { + dir = testDir + } path := filepath.Join(dir, "Library/LaunchAgents", fmt.Sprintf(launchFileFormatName, opts.LaunchFileName)) return path, nil } diff --git a/internal/osutils/autostart/autostart_windows.go b/internal/osutils/autostart/autostart_windows.go index e03fcd013f..a05bec3cf9 100644 --- a/internal/osutils/autostart/autostart_windows.go +++ b/internal/osutils/autostart/autostart_windows.go @@ -59,8 +59,8 @@ func isEnabled(_ string, opts Options) (bool, error) { return fileutils.FileExists(shortcutFilename(opts.Name)), nil } -func autostartPath(name string, _ Options) (string, error) { - return shortcutFilename(name), nil +func autostartPath(_ string, opts Options) (string, error) { + return shortcutFilename(opts.Name), nil } func upgrade(exec string, opts Options) error { diff --git a/internal/osutils/exeutils.go b/internal/osutils/exeutils.go index a789ba209d..1119df5a3e 100644 --- a/internal/osutils/exeutils.go +++ b/internal/osutils/exeutils.go @@ -16,7 +16,30 @@ import ( "github.com/ActiveState/cli/internal/logging" ) -// Executables will return all the Executables that need to be symlinked in the various provided bin directories +func ExecutablePaths(env map[string]string) ([]string, error) { + // Retrieve artifact binary directory + var bins []string + p, ok := env["PATH"] + if !ok { + return []string{}, nil + } + bins = strings.Split(p, string(os.PathListSeparator)) + + exes, err := Executables(bins) + if err != nil { + return nil, errs.Wrap(err, "Could not detect executables") + } + + // Remove duplicate executables as per PATH and PATHEXT + exes, err = UniqueExes(exes, os.Getenv("PATHEXT")) + if err != nil { + return nil, errs.Wrap(err, "Could not detect unique executables, make sure your PATH and PATHEXT environment variables are properly configured.") + } + + return exes, nil +} + +// Executables will find all directories that contain executables from the provided list of paths func Executables(bins []string) ([]string, error) { exes := []string{} diff --git a/internal/osutils/find.go b/internal/osutils/find.go index 6e0e14d189..97cd2b50fa 100644 --- a/internal/osutils/find.go +++ b/internal/osutils/find.go @@ -6,12 +6,13 @@ import ( "strings" "github.com/ActiveState/cli/internal/fileutils" + "github.com/thoas/go-funk" ) // FindExeOnPATH returns the first path from the PATH env var for which the executable exists -func FindExeOnPATH(executable string) string { - exes := findExes(executable, os.Getenv("PATH"), exts, fileutils.TargetExists, nil) +func FindExeOnPATH(executable string, PATH string) string { + exes := findExes(executable, PATH, exts, fileutils.TargetExists, nil) if len(exes) == 0 { return "" } diff --git a/internal/osutils/lockfile/pidlock.go b/internal/osutils/lockfile/pidlock.go index 501abb28eb..f40e77545a 100644 --- a/internal/osutils/lockfile/pidlock.go +++ b/internal/osutils/lockfile/pidlock.go @@ -1,6 +1,7 @@ package lockfile import ( + "errors" "fmt" "io" "os" @@ -105,7 +106,8 @@ func (pl *PidLock) WaitForLock(timeout time.Duration) error { for { err := pl.TryLock() if err != nil { - if !errs.Matches(err, &AlreadyLockedError{}) { + var errAlreadyLocked *AlreadyLockedError + if !errors.As(err, &errAlreadyLocked) { return errs.Wrap(err, "Could not acquire lock") } diff --git a/internal/osutils/osutils.go b/internal/osutils/osutils.go index 3618d31389..cd436e4bb4 100644 --- a/internal/osutils/osutils.go +++ b/internal/osutils/osutils.go @@ -80,6 +80,14 @@ func Getwd() (string, error) { return r, nil } +func GetwdUnsafe() string { + r, err := Getwd() + if err != nil { + panic(err) + } + return r +} + func EnvSliceToMap(envSlice []string) map[string]string { env := map[string]string{} for _, v := range envSlice { diff --git a/internal/osutils/shortcut/shortcut_windows.go b/internal/osutils/shortcut/shortcut_windows.go index 3e5c3ca802..365b493077 100644 --- a/internal/osutils/shortcut/shortcut_windows.go +++ b/internal/osutils/shortcut/shortcut_windows.go @@ -1,6 +1,7 @@ package shortcut import ( + "errors" "fmt" "os" "os/exec" @@ -74,7 +75,10 @@ func (s *Shortcut) Enable() error { cmd := exec.Command("powershell.exe", args...) out, err := cmd.CombinedOutput() if err != nil { - return locale.WrapError(err, "err_clean_start", "Could not create shortcut, received error: {{.V0}}", string(out)) + if errors.Is(err, exec.ErrNotFound) { + return locale.WrapError(err, "err_prepare_shortcut_powershell_not_found", "Could not create shortcut because powershell was not found on your PATH (searched '{{.V0}}')", os.Getenv("PATH")) + } + return locale.WrapError(err, "err_clean_start", "Could not create shortcut. Received error: {{.V0}}", string(out)) } return nil diff --git a/internal/osutils/user/user.go b/internal/osutils/user/user.go index 56bacb3791..1b485d0fab 100644 --- a/internal/osutils/user/user.go +++ b/internal/osutils/user/user.go @@ -23,7 +23,7 @@ func (e *HomeDirNotFoundError) Error() string { return homeDirNotFoundErrorMessage } -func (e *HomeDirNotFoundError) LocalizedError() string { +func (e *HomeDirNotFoundError) LocaleError() string { return homeDirNotFoundErrorMessage } diff --git a/internal/output/plain.go b/internal/output/plain.go index fc3e82907e..3859303cf9 100644 --- a/internal/output/plain.go +++ b/internal/output/plain.go @@ -39,6 +39,8 @@ const ( OmitEmpty PlainOpts = "omitEmpty" // HideDash hides the dash in table output HideDash PlainOpts = "hideDash" + // OmitKey hides the current struct key from output, its value is still printed + OmitKey PlainOpts = "omitKey" ) // Plain is our plain outputer, it uses reflect to marshal the data. @@ -195,14 +197,6 @@ func sprintStruct(value interface{}) (string, error) { return sprintTable(true, false, slice) } - if funk.Contains(field.opts, string(HideDash)) { - slice, err := asSlice(field.value) - if err != nil { - return "", err - } - return sprintTable(false, true, slice) - } - stringValue, err := sprint(field.value, field.opts) if err != nil { return "", err @@ -211,6 +205,11 @@ func sprintStruct(value interface{}) (string, error) { continue } + if funk.Contains(field.opts, string(OmitKey)) { + result = append(result, stringValue) + continue + } + if isStruct(field.value) || isSlice(field.value) { stringValue = "\n" + stringValue } diff --git a/internal/output/presets.go b/internal/output/presets.go index 3fa98e7693..1033d44246 100644 --- a/internal/output/presets.go +++ b/internal/output/presets.go @@ -32,19 +32,35 @@ func (h Emphasize) MarshalStructured(f Format) interface{} { return Suppress } -type preparedOutput struct { - plain interface{} +type plainOutput struct { + plain interface{} +} + +type structuredOutput struct { structured interface{} } -func (o *preparedOutput) MarshalOutput(_ Format) interface{} { +type preparedOutput struct { + *plainOutput + *structuredOutput +} + +func (o *plainOutput) MarshalOutput(_ Format) interface{} { return o.plain } -func (o *preparedOutput) MarshalStructured(_ Format) interface{} { +func (o *structuredOutput) MarshalStructured(_ Format) interface{} { return o.structured } func Prepare(plain interface{}, structured interface{}) *preparedOutput { - return &preparedOutput{plain, structured} + return &preparedOutput{&plainOutput{plain}, &structuredOutput{structured}} +} + +func Structured(structured interface{}) *structuredOutput { + return &structuredOutput{structured} } + +const TreeMid = "├─" +const TreeLink = "│" +const TreeEnd = "└─" diff --git a/internal/output/progress.go b/internal/output/progress.go index 6aff32be14..9331a40f59 100644 --- a/internal/output/progress.go +++ b/internal/output/progress.go @@ -26,9 +26,9 @@ func (d *Spinner) MarshalOutput(f Format) interface{} { } func StartSpinner(out Outputer, msg string, interval time.Duration) *Spinner { - frames := []string{".", "..", "..."} + frames := []string{"."} if out.Config().Interactive { - frames = []string{`|`, `/`, `-`, `\`} + frames = SpinnerFrames } d := &Spinner{0, frames, out, make(chan struct{}, 1), interval, false} diff --git a/internal/primer/primer.go b/internal/primer/primer.go index f3cd8d8d8f..8ad3854415 100644 --- a/internal/primer/primer.go +++ b/internal/primer/primer.go @@ -1,9 +1,13 @@ package primer import ( + "fmt" + "github.com/ActiveState/cli/internal/analytics" + "github.com/ActiveState/cli/internal/condition" "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constraints" + "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/subshell" @@ -28,31 +32,50 @@ type Values struct { analytics analytics.Dispatcher } -func New( - project *project.Project, output output.Outputer, auth *authentication.Auth, prompt prompt.Prompter, - subshell subshell.SubShell, conditional *constraints.Conditional, config *config.Instance, - ipComm svcctl.IPCommunicator, svcModel *model.SvcModel, an analytics.Dispatcher) *Values { - - v := &Values{ - output: output, - auth: auth, - prompt: prompt, - subshell: subshell, - conditional: conditional, - config: config, - ipComm: ipComm, - svcModel: svcModel, - analytics: an, - } - if project != nil { - v.project = project - v.projectfile = project.Source() +func New(values ...any) *Values { + result := &Values{} + for _, v := range values { + switch typed := v.(type) { + case *project.Project: + result.project = typed + result.projectfile = typed.Source() + case output.Outputer: + result.output = typed + case *authentication.Auth: + result.auth = typed + case prompt.Prompter: + result.prompt = typed + case subshell.SubShell: + result.subshell = typed + case *constraints.Conditional: + result.conditional = typed + case *config.Instance: + result.config = typed + case svcctl.IPCommunicator: + result.ipComm = typed + case *model.SvcModel: + result.svcModel = typed + case analytics.Dispatcher: + result.analytics = typed + default: + if condition.BuiltOnDevMachine() || condition.InActiveStateCI() { + panic(fmt.Sprintf("invalid type %T", v)) + } else { + multilog.Critical("Primer passed invalid type: %T", v) + } + } } - return v + return result +} + +func (v *Values) SetProject(p *project.Project) { + v.project = p + v.projectfile = p.Source() } type Projecter interface { Project() *project.Project + SetProject(p *project.Project) } type Projectfiler interface { diff --git a/internal/process/process.go b/internal/process/process.go index b331a8c44b..eb5f267f78 100644 --- a/internal/process/process.go +++ b/internal/process/process.go @@ -29,14 +29,10 @@ func ActivationPID(cfg Configurable) int32 { seen := map[int32]bool{} for pid != 0 && pid != ppid { - logging.Debug("Current PID: %d, Parent PID: %d", pid, ppid) pidFileName := ActivationPIDFileName(cfg.ConfigPath(), int(pid)) - logging.Debug("Looking for activation pid file: %s", pidFileName) if fileutils.FileExists(pidFileName) { - logging.Debug("Found activation pid file: %s", pidFileName) return pid } - logging.Debug("Activation pid file not found") if ppid == 0 { logging.Debug("Parent PID is 0") diff --git a/internal/proxyreader/proxyreader.go b/internal/proxyreader/proxyreader.go index 108252223e..3ad9a1b202 100644 --- a/internal/proxyreader/proxyreader.go +++ b/internal/proxyreader/proxyreader.go @@ -46,10 +46,8 @@ func (pr *ProxyReader) ReadAt(p []byte, offset int64) (int, error) { } n, err := prAt.ReadAt(p, offset) if n > 0 { - if offset == 0 { - if err := pr.increment.ReportIncrement(n); err != nil { - return n, errs.Wrap(err, "Could not report increment") - } + if err := pr.increment.ReportIncrement(n); err != nil { + return n, errs.Wrap(err, "Could not report increment") } } return n, err diff --git a/internal/proxyreader/proxyreader_test.go b/internal/proxyreader/proxyreader_test.go new file mode 100644 index 0000000000..b94d7776c7 --- /dev/null +++ b/internal/proxyreader/proxyreader_test.go @@ -0,0 +1,37 @@ +package proxyreader + +import ( + "bytes" + "errors" + "io" + "strings" + "testing" +) + +type progressReport struct { + reports []int +} + +func (p *progressReport) ReportIncrement(i int) error { + p.reports = append(p.reports, i) + return nil +} + +func TestProxyReader(t *testing.T) { + b := []byte(strings.Repeat("bogus line\n", 100)) + p := &progressReport{} + reader := NewProxyReader(p, bytes.NewBuffer(b)) + for i := 0; i < 10; i++ { + read := make([]byte, 10) + n, err := reader.Read(read) + if err != nil && !errors.Is(err, io.EOF) { + t.Errorf("Error reading: %v", err) + } + if n != 10 { + t.Errorf("Expected 10 bytes, got %d", n) + } + } + if len(p.reports) != 10 { + t.Errorf("Expected 10 reports, got %d", len(p.reports)) + } +} diff --git a/internal/retryhttp/roundtripper.go b/internal/retryhttp/roundtripper.go index dad3cee128..6184e73484 100644 --- a/internal/retryhttp/roundtripper.go +++ b/internal/retryhttp/roundtripper.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/pkg/platform" + "github.com/ActiveState/cli/pkg/platform/api/errors" "github.com/hashicorp/go-retryablehttp" ) @@ -30,7 +30,7 @@ func (rt *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { resp, err := rt.client.Do(retryableReq) if err != nil && resp != nil && resp.StatusCode == http.StatusForbidden && strings.EqualFold(resp.Header.Get("server"), "cloudfront") { - return nil, platform.NewCountryBlockedError() + return nil, api_errors.NewCountryBlockedError() } return resp, err diff --git a/internal/runbits/auth/keypair.go b/internal/runbits/auth/keypair.go index 51b0e8fc05..611060376e 100644 --- a/internal/runbits/auth/keypair.go +++ b/internal/runbits/auth/keypair.go @@ -1,6 +1,8 @@ package auth import ( + "errors" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/keypairs" @@ -16,9 +18,10 @@ import ( // and saved. func ensureUserKeypair(passphrase string, cfg keypairs.Configurable, out output.Outputer, prompt prompt.Prompter, auth *authentication.Auth) error { keypairRes, err := keypairs.FetchRaw(secretsapi.Get(auth), cfg, auth) + var errKeypairNotFound *keypairs.ErrKeypairNotFound if err == nil { err = processExistingKeypairForUser(keypairRes, passphrase, cfg, out, prompt, auth) - } else if errs.Matches(err, &keypairs.ErrKeypairNotFound{}) { + } else if errors.As(err, &errKeypairNotFound) { err = generateKeypairForUser(cfg, passphrase, auth) } @@ -52,10 +55,11 @@ func generateKeypairForUser(cfg keypairs.Configurable, passphrase string, auth * // provided passphrase and then uploaded; unless the user declines, which results in err. func processExistingKeypairForUser(keypairRes *secretsModels.Keypair, passphrase string, cfg keypairs.Configurable, out output.Outputer, prompt prompt.Prompter, auth *authentication.Auth) error { keypair, err := keypairs.ParseEncryptedRSA(*keypairRes.EncryptedPrivateKey, passphrase) + var errKeypairPassphrase *keypairs.ErrKeypairPassphrase if err == nil { // yay, store keypair locally just in case it isn't return keypairs.SaveWithDefaults(cfg, keypair) - } else if !errs.Matches(err, &keypairs.ErrKeypairPassphrase{}) { + } else if !errors.As(err, &errKeypairPassphrase) { // err did not involve an unmatched passphrase return err } @@ -74,7 +78,7 @@ func processExistingKeypairForUser(keypairRes *secretsModels.Keypair, passphrase // failed to validate with local private-key, try using previous passphrase err = recoverKeypairFromPreviousPassphrase(keypairRes, passphrase, cfg, out, prompt, auth) - if err != nil && errs.Matches(err, &keypairs.ErrKeypairPassphrase{}) { + if err != nil && errors.As(err, &errKeypairPassphrase) { // that failed, see if they want to regenerate their passphrase err = promptUserToRegenerateKeypair(passphrase, cfg, out, prompt, auth) } diff --git a/internal/runbits/auth/login.go b/internal/runbits/auth/login.go index 33f47f397a..1159613f9a 100644 --- a/internal/runbits/auth/login.go +++ b/internal/runbits/auth/login.go @@ -1,6 +1,7 @@ package auth import ( + "errors" "net/url" "time" @@ -49,12 +50,15 @@ func AuthenticateWithInput( err := AuthenticateWithCredentials(credentials, auth) if err != nil { + var errTokenRequired *authentication.ErrTokenRequired + var errUnauthorized *authentication.ErrUnauthorized + switch { - case errs.Matches(err, &authentication.ErrTokenRequired{}): + case errors.As(err, &errTokenRequired): if err := promptToken(credentials, out, prompt, auth); err != nil { return errs.Wrap(err, "promptToken failed") } - case errs.Matches(err, &authentication.ErrUnauthorized{}): + case errors.As(err, &errUnauthorized): return locale.WrapError(err, "err_auth_failed") default: return locale.WrapError(err, "err_auth_failed_unknown_cause", "", err.Error()) diff --git a/internal/runbits/buildplanner/buildplanner.go b/internal/runbits/buildplanner/buildplanner.go new file mode 100644 index 0000000000..85db3935c2 --- /dev/null +++ b/internal/runbits/buildplanner/buildplanner.go @@ -0,0 +1,189 @@ +package buildplanner + +import ( + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/request" + "github.com/ActiveState/cli/pkg/platform/model" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" + "github.com/ActiveState/cli/pkg/project" + "github.com/go-openapi/strfmt" +) + +type ErrInvalidCommitId struct { + Id string +} + +func (e *ErrInvalidCommitId) Error() string { + return "Invalid commit ID" +} + +type ErrCommitDoesNotExistInProject struct { + Project string + CommitID string +} + +func (e *ErrCommitDoesNotExistInProject) Error() string { + return "Commit does not exist in project" +} + +type primeable interface { + primer.Projecter + primer.Auther + primer.Outputer + primer.SvcModeler +} + +// GetCommit returns a commit from the given arguments. By default, the local commit for the +// current project is returned, but a commit for a given commitID for the current project can be +// returned, as can the commit for a remote project (and optional commitID). +func GetCommit( + namespace *project.Namespaced, + commitID string, + target string, + prime primeable, +) (commit *bpModel.Commit, rerr error) { + pj := prime.Project() + out := prime.Output() + auth := prime.Auth() + svcm := prime.SvcModel() + + if pj == nil && !namespace.IsValid() { + return nil, rationalize.ErrNoProject + } + + commitUUID := strfmt.UUID(commitID) + if commitUUID != "" && !strfmt.IsUUID(commitUUID.String()) { + return nil, &ErrInvalidCommitId{commitUUID.String()} + } + + namespaceProvided := namespace.IsValid() + commitIdProvided := commitUUID != "" + + // Show a spinner when fetching a buildplan. + // Sourcing the local runtime for a buildplan has its own spinner. + pb := output.StartSpinner(out, locale.T("progress_solve"), constants.TerminalAnimationInterval) + defer func() { + message := locale.T("progress_success") + if rerr != nil { + message = locale.T("progress_fail") + } + pb.Stop(message + "\n") // extra empty line + }() + + targetPtr := ptr.To(request.TargetAll) + if target != "" { + targetPtr = &target + } + + var err error + switch { + // Return the buildplan from this runtime. + case !namespaceProvided && !commitIdProvided: + localCommitID, err := localcommit.Get(pj.Path()) + if err != nil { + return nil, errs.Wrap(err, "Could not get local commit") + } + + bp := bpModel.NewBuildPlannerModel(auth, svcm) + commit, err = bp.FetchCommit(localCommitID, pj.Owner(), pj.Name(), targetPtr) + if err != nil { + return nil, errs.Wrap(err, "Failed to fetch commit") + } + + // Return buildplan from the given commitID for the current project. + case !namespaceProvided && commitIdProvided: + bp := bpModel.NewBuildPlannerModel(auth, svcm) + commit, err = bp.FetchCommit(commitUUID, pj.Owner(), pj.Name(), targetPtr) + if err != nil { + return nil, errs.Wrap(err, "Failed to fetch commit") + } + + // Return the buildplan for the latest commitID of the given project. + case namespaceProvided && !commitIdProvided: + pj, err := model.FetchProjectByName(namespace.Owner, namespace.Project, auth) + if err != nil { + return nil, locale.WrapExternalError(err, "err_fetch_project", "", namespace.String()) + } + + branch, err := model.DefaultBranchForProject(pj) + if err != nil { + return nil, errs.Wrap(err, "Could not grab branch for project") + } + + branchCommitUUID, err := model.BranchCommitID(namespace.Owner, namespace.Project, branch.Label) + if err != nil { + return nil, errs.Wrap(err, "Could not get commit ID for project") + } + commitUUID = *branchCommitUUID + + bp := bpModel.NewBuildPlannerModel(auth, svcm) + commit, err = bp.FetchCommit(commitUUID, namespace.Owner, namespace.Project, targetPtr) + if err != nil { + return nil, errs.Wrap(err, "Failed to fetch commit") + } + + // Return the buildplan for the given commitID of the given project. + case namespaceProvided && commitIdProvided: + bp := bpModel.NewBuildPlannerModel(auth, svcm) + commit, err = bp.FetchCommit(commitUUID, namespace.Owner, namespace.Project, targetPtr) + if err != nil { + return nil, errs.Wrap(err, "Failed to fetch commit") + } + + default: + return nil, errs.New("Unhandled case") + } + + // Note: the Platform does not raise an error when requesting a commit ID that does not exist in + // a given project, so we have verify existence client-side. See DS-1705 (yes, DS, not DX). + var owner, name, nsString string + var localCommitID *strfmt.UUID + if namespaceProvided { + owner = namespace.Owner + name = namespace.Project + nsString = namespace.String() + } else { + owner = pj.Owner() + name = pj.Name() + nsString = pj.NamespaceString() + commitID, err := localcommit.Get(pj.Path()) + if err != nil { + return nil, errs.Wrap(err, "Could not get local commit") + } + localCommitID = &commitID + } + _, err = model.GetCommitWithinProjectHistory(commit.CommitID, owner, name, localCommitID, auth) + if err != nil { + if err == model.ErrCommitNotInHistory { + return nil, errs.Pack(err, &ErrCommitDoesNotExistInProject{nsString, commit.CommitID.String()}) + } + return nil, errs.Wrap(err, "Unable to determine if commit exists in project") + } + + return commit, nil +} + +// GetBuildPlan returns a project's buildplan, depending on the given arguments. By default, the +// buildplan for the current project is returned, but a buildplan for a given commitID for the +// current project can be returned, as can the buildplan for a remote project (and optional +// commitID). +func GetBuildPlan( + namespace *project.Namespaced, + commitID string, + target string, + prime primeable, +) (bp *buildplan.BuildPlan, rerr error) { + commit, err := GetCommit(namespace, commitID, target, prime) + if err != nil { + return nil, errs.Wrap(err, "Could not get commit") + } + return commit.BuildPlan(), nil +} diff --git a/internal/runbits/buildscript/buildscript_test.go b/internal/runbits/buildscript/buildscript_test.go index 5ef9836dde..8f201e2814 100644 --- a/internal/runbits/buildscript/buildscript_test.go +++ b/internal/runbits/buildscript/buildscript_test.go @@ -11,11 +11,21 @@ import ( "github.com/stretchr/testify/require" ) +const testProject = "https://platform.activestate.com/org/project?branch=main&commitID=00000000-0000-0000-0000-000000000000" +const testTime = "2000-01-01T00:00:00Z" + +func checkoutInfo(project, time string) string { + return "```\n" + + "Project: " + project + "\n" + + "Time: " + time + "\n" + + "```\n" +} + func TestDiff(t *testing.T) { script, err := buildscript.Unmarshal([]byte( - `at_time = "2000-01-01T00:00:00.000Z" + checkoutInfo(testProject, testTime) + ` runtime = solve( - at_time = at_time, + at_time = TIME, platforms = [ "12345", "67890" @@ -38,9 +48,9 @@ main = runtime`)) // Generate the difference between the modified script and the original expression. result, err := generateDiff(modifiedScript, script) require.NoError(t, err) - assert.Equal(t, `at_time = "2000-01-01T00:00:00.000Z" + assert.Equal(t, checkoutInfo(testProject, testTime)+` runtime = solve( - at_time = at_time, + at_time = TIME, platforms = [ <<<<<<< local "77777", @@ -71,11 +81,16 @@ func TestRealWorld(t *testing.T) { require.NoError(t, err) result, err := generateDiff(script1, script2) require.NoError(t, err) - assert.Equal(t, `<<<<<<< local -at_time = "2023-10-16T22:20:29.000Z" -======= -at_time = "2023-08-01T16:20:11.985Z" ->>>>>>> remote + assert.Equal(t, + "```\n"+ + "<<<<<<< local\n"+ + "Project: https://platform.activestate.com/ActiveState-CLI/Merge?branch=main&commitID=d908a758-6a81-40d4-b0eb-87069cd7f07d\n"+ + "Time: 2024-05-10T00:00:13Z\n"+ + "=======\n"+ + "Project: https://platform.activestate.com/ActiveState-CLI/Merge?branch=main&commitID=f3263ee4-ac4c-41ee-b778-2585333f49f7\n"+ + "Time: 2023-08-01T16:20:11Z\n"+ + ">>>>>>> remote\n"+ + "```\n"+` runtime = state_tool_artifacts_v1( build_flags = [ ], @@ -84,7 +99,7 @@ runtime = state_tool_artifacts_v1( src = sources ) sources = solve( - at_time = at_time, + at_time = TIME, platforms = [ "78977bc8-0f32-519d-80f3-9043f059398c", "7c998ec2-7491-4e75-be4d-8885800ef5f2", diff --git a/internal/runbits/buildscript/file.go b/internal/runbits/buildscript/file.go index 36868e34c5..e1b30fcc79 100644 --- a/internal/runbits/buildscript/file.go +++ b/internal/runbits/buildscript/file.go @@ -2,6 +2,7 @@ package buildscript_runbit import ( "errors" + "net/url" "os" "path/filepath" @@ -9,23 +10,24 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/pkg/buildscript" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/authentication" + "github.com/ActiveState/cli/pkg/platform/model" "github.com/ActiveState/cli/pkg/platform/model/buildplanner" ) // projecter is a union between project.Project and setup.Targeter type projecter interface { - ProjectDir() string - Owner() string - Name() string + Dir() string + URL() string } var ErrBuildscriptNotExist = errors.New("Build script does not exist") func ScriptFromProject(proj projecter) (*buildscript.BuildScript, error) { - path := filepath.Join(proj.ProjectDir(), constants.BuildScriptFileName) + path := filepath.Join(proj.Dir(), constants.BuildScriptFileName) return ScriptFromFile(path) } @@ -40,33 +42,39 @@ func ScriptFromFile(path string) (*buildscript.BuildScript, error) { return buildscript.Unmarshal(data) } -func Initialize(path string, auth *authentication.Auth) error { - scriptPath := filepath.Join(path, constants.BuildScriptFileName) - script, err := ScriptFromFile(scriptPath) - if err == nil { - return nil // nothing to do, buildscript already exists - } - if !errors.Is(err, os.ErrNotExist) { - return errs.Wrap(err, "Could not read build script from file") - } +type primeable interface { + primer.Auther + primer.SvcModeler +} - logging.Debug("Build script does not exist. Creating one.") - commitId, err := localcommit.Get(path) +// Initialize creates a new build script for the local project. It will overwrite an existing one so +// commands like `state reset` will work. +func Initialize(proj projecter, auth *authentication.Auth, svcm *model.SvcModel) error { + logging.Debug("Initializing build script") + commitId, err := localcommit.Get(proj.Dir()) if err != nil { return errs.Wrap(err, "Unable to get the local commit ID") } - buildplanner := buildplanner.NewBuildPlannerModel(auth) - script, err = buildplanner.GetBuildScript(commitId.String()) + buildplanner := buildplanner.NewBuildPlannerModel(auth, svcm) + script, err := buildplanner.GetBuildScript(commitId.String()) if err != nil { return errs.Wrap(err, "Unable to get the remote build expression and time") } + if url, err := projectURL(proj, commitId.String()); err == nil { + script.SetProject(url) + } else { + return errs.Wrap(err, "Unable to set project") + } + // Note: script.SetAtTime() was done in GetBuildScript(). + scriptBytes, err := script.Marshal() if err != nil { return errs.Wrap(err, "Unable to marshal build script") } + scriptPath := filepath.Join(proj.Dir(), constants.BuildScriptFileName) logging.Debug("Initializing build script at %s", scriptPath) err = fileutils.WriteFile(scriptPath, scriptBytes) if err != nil { @@ -76,27 +84,41 @@ func Initialize(path string, auth *authentication.Auth) error { return nil } -func Update(proj projecter, newScript *buildscript.BuildScript) error { - script, err := ScriptFromProject(proj) +// projectURL returns proj.URL(), but with the given, updated commitID. +func projectURL(proj projecter, commitID string) (string, error) { + u, err := url.Parse(proj.URL()) if err != nil { - return errs.Wrap(err, "Could not read build script") + return "", errs.Wrap(err, "Unable to parse URL") } + q := u.Query() + q.Set("commitID", commitID) + u.RawQuery = q.Encode() + return u.String(), nil +} - equals, err := script.Equals(newScript) +func Update(proj projecter, newScript *buildscript.BuildScript) error { + // Update the new script's project field to match the current one, except for a new commit ID. + commitID, err := localcommit.Get(proj.Dir()) + if err != nil { + return errs.Wrap(err, "Unable to get the local commit ID") + } + url, err := projectURL(proj, commitID.String()) if err != nil { - return errs.Wrap(err, "Could not compare build script") + return errs.Wrap(err, "Could not construct project URL") } - if script != nil && equals { - return nil // no changes to write + newScript2, err := newScript.Clone() + if err != nil { + return errs.Wrap(err, "Could not clone buildscript") } + newScript2.SetProject(url) - sb, err := newScript.Marshal() + sb, err := newScript2.Marshal() if err != nil { return errs.Wrap(err, "Could not marshal build script") } logging.Debug("Writing build script") - if err := fileutils.WriteFile(filepath.Join(proj.ProjectDir(), constants.BuildScriptFileName), sb); err != nil { + if err := fileutils.WriteFile(filepath.Join(proj.Dir(), constants.BuildScriptFileName), sb); err != nil { return errs.Wrap(err, "Could not write build script to file") } return nil diff --git a/internal/runbits/buildscript/testdata/buildscript1.as b/internal/runbits/buildscript/testdata/buildscript1.as index 1bbc21f6b3..9ed3f42adc 100644 --- a/internal/runbits/buildscript/testdata/buildscript1.as +++ b/internal/runbits/buildscript/testdata/buildscript1.as @@ -1,4 +1,8 @@ -at_time = "2023-10-16T22:20:29.000000Z" +``` +Project: https://platform.activestate.com/ActiveState-CLI/Merge?branch=main&commitID=d908a758-6a81-40d4-b0eb-87069cd7f07d +Time: 2024-05-10T00:00:13Z +``` + runtime = state_tool_artifacts_v1( build_flags = [ ], @@ -7,7 +11,7 @@ runtime = state_tool_artifacts_v1( src = sources ) sources = solve( - at_time = at_time, + at_time = TIME, platforms = [ "78977bc8-0f32-519d-80f3-9043f059398c", "7c998ec2-7491-4e75-be4d-8885800ef5f2", @@ -20,4 +24,4 @@ sources = solve( solver_version = null ) -main = runtime \ No newline at end of file +main = runtime diff --git a/internal/runbits/buildscript/testdata/buildscript2.as b/internal/runbits/buildscript/testdata/buildscript2.as index 335b721546..8e1458918c 100644 --- a/internal/runbits/buildscript/testdata/buildscript2.as +++ b/internal/runbits/buildscript/testdata/buildscript2.as @@ -1,4 +1,8 @@ -at_time = "2023-08-01T16:20:11.985000Z" +``` +Project: https://platform.activestate.com/ActiveState-CLI/Merge?branch=main&commitID=f3263ee4-ac4c-41ee-b778-2585333f49f7 +Time: 2023-08-01T16:20:11Z +``` + runtime = state_tool_artifacts_v1( build_flags = [ ], @@ -7,7 +11,7 @@ runtime = state_tool_artifacts_v1( src = sources ) sources = solve( - at_time = at_time, + at_time = TIME, platforms = [ "78977bc8-0f32-519d-80f3-9043f059398c", "7c998ec2-7491-4e75-be4d-8885800ef5f2", @@ -20,4 +24,4 @@ sources = solve( solver_version = null ) -main = runtime \ No newline at end of file +main = runtime diff --git a/internal/runbits/checkout/archive.go b/internal/runbits/checkout/archive.go new file mode 100644 index 0000000000..1dc615213a --- /dev/null +++ b/internal/runbits/checkout/archive.go @@ -0,0 +1,128 @@ +package checkout + +import ( + "encoding/json" + "os" + "path/filepath" + + "github.com/go-openapi/strfmt" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/unarchiver" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/project" +) + +type Archive struct { + Dir string + Namespace *project.Namespaced + Branch string + PlatformID strfmt.UUID + BuildPlan *buildplan.BuildPlan +} + +const ArchiveExt = ".tar.gz" +const ArtifactExt = ".tar.gz" +const BuildPlanJson = "buildplan.json" +const InstallerConfigJson = "installer_config.json" +const BuildExpressionJson = "buildexpression.json" + +type configJson struct { + Owner string `json:"org_name"` + Project string `json:"project_name"` + Branch string `json:"branch"` + CommitID string `json:"commit_id"` + PlatformID string `json:"platform_id"` +} + +// NewArchive unpacks the given archive to a temporary location. +// The caller should invoke the `Cleanup()` method when finished with this archive. +func NewArchive(archivePath string) (_ *Archive, rerr error) { + dir, err := os.MkdirTemp("", "") + if err != nil { + return nil, errs.Wrap(err, "Unable to create temporary directory") + } + defer func() { + if rerr == nil { + return + } + // Delete the temporary directory if there was an error unpacking the archive. + if err := os.RemoveAll(dir); err != nil { + if rerr != nil { + err = errs.Pack(rerr, errs.Wrap(err, "Unable to delete temporary directory")) + } + rerr = err + } + }() + + // Prepare. + ua := unarchiver.NewTarGz() + f, size, err := ua.PrepareUnpacking(archivePath, dir) + if err != nil { + if err2 := os.RemoveAll(dir); err2 != nil { + err = errs.Pack(err, errs.Wrap(err2, "Unable to delete temporary directory")) + } + return nil, errs.Wrap(err, "Unable to read archive") + } + + // Unpack. + err = ua.Unarchive(f, size, dir) + if err != nil { + return nil, errs.Wrap(err, "Unable to extract archive") + } + + // Read from config JSON. + ns, branch, platformID, err := readProject(dir) + if err != nil { + return nil, errs.Wrap(err, "Unable to read project from archive") + } + + // Read from buildplan JSON. + buildPlan, err := readBuildPlan(dir) + if err != nil { + return nil, errs.Wrap(err, "Unable to read buildplan from archive") + } + + return &Archive{dir, ns, branch, platformID, buildPlan}, nil +} + +// Cleanup should be called after the archive is no longer needed. +// Otherwise, its contents will remain on disk. +func (a *Archive) Cleanup() error { + return os.RemoveAll(a.Dir) +} + +// readProject reads and returns a project namespace (with commitID) and branch from +// config JSON, as well as a platformID. +func readProject(dir string) (*project.Namespaced, string, strfmt.UUID, error) { + jsonBytes, err := fileutils.ReadFile(filepath.Join(dir, InstallerConfigJson)) + if err != nil { + return nil, "", "", errs.Wrap(err, "Invalid archive: %s not found", InstallerConfigJson) + } + + var proj *configJson + err = json.Unmarshal(jsonBytes, &proj) + if err != nil { + return nil, "", "", errs.Wrap(err, "Unable to read %s", InstallerConfigJson) + } + + ns := &project.Namespaced{Owner: proj.Owner, Project: proj.Project, CommitID: ptr.To(strfmt.UUID(proj.CommitID))} + return ns, proj.Branch, strfmt.UUID(proj.PlatformID), nil +} + +// readBuildPlan reads and returns a buildplan from buildplan JSON. +func readBuildPlan(dir string) (*buildplan.BuildPlan, error) { + buildplanBytes, err := fileutils.ReadFile(filepath.Join(dir, BuildPlanJson)) + if err != nil { + return nil, errs.Wrap(err, "Invalid archive: %s not found", BuildPlanJson) + } + + buildPlan, err := buildplan.Unmarshal(buildplanBytes) + if err != nil { + return nil, errs.Wrap(err, "Unable to unmarshal build plan") + } + + return buildPlan, nil +} diff --git a/internal/runbits/checkout/checkout.go b/internal/runbits/checkout/checkout.go index 006ec9a121..8e25d88b4e 100644 --- a/internal/runbits/checkout/checkout.go +++ b/internal/runbits/checkout/checkout.go @@ -3,11 +3,6 @@ package checkout import ( "path/filepath" - "github.com/ActiveState/cli/internal/analytics" - "github.com/ActiveState/cli/internal/config" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/runbits/buildscript" "github.com/go-openapi/strfmt" "github.com/ActiveState/cli/internal/constants" @@ -15,7 +10,8 @@ import ( "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/language" "github.com/ActiveState/cli/internal/osutils" - "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/runbits/buildscript" "github.com/ActiveState/cli/internal/runbits/git" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" @@ -30,18 +26,15 @@ type primeable interface { primer.Analyticer primer.Configurer primer.Auther + primer.SvcModeler } // Checkout will checkout the given platform project at the given path // This includes cloning an associated repository and creating the activestate.yaml // It does not activate any environment type Checkout struct { - repo git.Repository - output.Outputer - config *config.Instance - analytics analytics.Dispatcher - branchName string - auth *authentication.Auth + repo git.Repository + prime primeable } type errCommitDoesNotBelong struct { @@ -52,11 +45,14 @@ func (e errCommitDoesNotBelong) Error() string { return "commitID does not belong to the given branch" } +var errNoCommitID = errs.New("commitID is nil") +var ErrNoOrg = errs.New("unable to get org name") + func New(repo git.Repository, prime primeable) *Checkout { - return &Checkout{repo, prime.Output(), prime.Config(), prime.Analytics(), "", prime.Auth()} + return &Checkout{repo, prime} } -func (r *Checkout) Run(ns *project.Namespaced, branchName, cachePath, targetPath string, noClone bool) (_ string, rerr error) { +func (r *Checkout) Run(ns *project.Namespaced, branchName, cachePath, targetPath string, noClone, bareCheckout bool) (_ string, rerr error) { defer r.rationalizeError(&rerr) path, err := r.pathToUse(ns, targetPath) @@ -69,36 +65,86 @@ func (r *Checkout) Run(ns *project.Namespaced, branchName, cachePath, targetPath return "", errs.Wrap(err, "Could not get absolute path") } + if cachePath != "" && !filepath.IsAbs(cachePath) { + cachePath, err = filepath.Abs(cachePath) + if err != nil { + return "", errs.Wrap(err, "Could not get absolute path for cache") + } + } + + owner := ns.Owner + proj := ns.Project + commitID := ns.CommitID + var language string + if !bareCheckout { + var repoURL *string + owner, proj, commitID, branchName, language, repoURL, err = r.fetchProject(ns, branchName, commitID) + if err != nil { + return "", errs.Wrap(err, "Unable to checkout project") + } + + // Clone the related repo, if it is defined + if !noClone && repoURL != nil && *repoURL != "" { + err := r.repo.CloneProject(ns.Owner, ns.Project, path, r.prime.Output(), r.prime.Analytics()) + if err != nil { + return "", errs.Wrap(err, "Could not clone associated git repository") + } + } + } else if commitID == nil { + return "", errNoCommitID + } + + if err := CreateProjectFiles(path, cachePath, owner, proj, branchName, commitID.String(), language); err != nil { + return "", errs.Wrap(err, "Could not create project files") + } + + if r.prime.Config().GetBool(constants.OptinBuildscriptsConfig) { + pjf, err := projectfile.FromPath(path) + if err != nil { + return "", errs.Wrap(err, "Unable to load project file") + } + + if err := buildscript_runbit.Initialize(pjf, r.prime.Auth(), r.prime.SvcModel()); err != nil { + return "", errs.Wrap(err, "Unable to initialize buildscript") + } + } + + return path, nil +} + +func (r *Checkout) fetchProject( + ns *project.Namespaced, branchName string, commitID *strfmt.UUID) (string, string, *strfmt.UUID, string, string, *string, error) { + // If project does not exist at path then we must checkout // the project and create the project file - pj, err := model.FetchProjectByName(ns.Owner, ns.Project, r.auth) + pj, err := model.FetchProjectByName(ns.Owner, ns.Project, r.prime.Auth()) if err != nil { - return "", locale.WrapError(err, "err_fetch_project", "", ns.String()) + return "", "", nil, "", "", nil, errs.Wrap(err, "Unable to fetch project '%s'", ns.String()) } + proj := pj.Name var branch *mono_models.Branch - commitID := ns.CommitID switch { // Fetch the branch the given commitID is on. case commitID != nil: for _, b := range pj.Branches { - if belongs, err := model.CommitBelongsToBranch(ns.Owner, ns.Project, b.Label, *commitID, r.auth); err == nil && belongs { + if belongs, err := model.CommitBelongsToBranch(ns.Owner, ns.Project, b.Label, *commitID, r.prime.Auth()); err == nil && belongs { branch = b break } else if err != nil { - return "", errs.Wrap(err, "Could not determine which branch the given commitID belongs to") + return "", "", nil, "", "", nil, errs.Wrap(err, "Could not determine which branch the given commitID belongs to") } } if branch == nil { - return "", &errCommitDoesNotBelong{CommitID: *commitID} + return "", "", nil, "", "", nil, &errCommitDoesNotBelong{CommitID: *commitID} } // Fetch the given project branch. case branchName != "": branch, err = model.BranchForProjectByName(pj, branchName) if err != nil { - return "", locale.WrapError(err, "err_fetch_branch", "", branchName) + return "", "", nil, "", "", nil, errs.Wrap(err, "Could not get branch '%s'", branchName) } commitID = branch.CommitID @@ -106,83 +152,66 @@ func (r *Checkout) Run(ns *project.Namespaced, branchName, cachePath, targetPath default: branch, err = model.DefaultBranchForProject(pj) if err != nil { - return "", errs.Wrap(err, "Could not grab branch for project") + return "", "", nil, "", "", nil, errs.Wrap(err, "Could not grab branch for project") } commitID = branch.CommitID } + branchName = branch.Label if commitID == nil { - return "", errs.New("commitID is nil") + return "", "", nil, "", "", nil, errNoCommitID } - // Clone the related repo, if it is defined - if !noClone && pj.RepoURL != nil && *pj.RepoURL != "" { - err := r.repo.CloneProject(ns.Owner, ns.Project, path, r.Outputer, r.analytics) - if err != nil { - return "", locale.WrapError(err, "err_clone_project", "Could not clone associated git repository") - } - } - - language, err := getLanguage(*commitID, r.auth) + lang, err := getLanguage(*commitID, r.prime.Auth()) if err != nil { - return "", errs.Wrap(err, "Could not get language from commitID") - } - - if cachePath != "" && !filepath.IsAbs(cachePath) { - cachePath, err = filepath.Abs(cachePath) - if err != nil { - return "", errs.Wrap(err, "Could not get absolute path for cache") - } + return "", "", nil, "", "", nil, errs.Wrap(err, "Could not get language from commitID") } + language := lang.String() // Match the case of the organization. // Otherwise the incorrect case will be written to the project file. - owners, err := model.FetchOrganizationsByIDs([]strfmt.UUID{pj.OrganizationID}, r.auth) + owners, err := model.FetchOrganizationsByIDs([]strfmt.UUID{pj.OrganizationID}, r.prime.Auth()) if err != nil { - return "", errs.Wrap(err, "Unable to get the project's org") + return "", "", nil, "", "", nil, errs.Wrap(err, "Unable to get the project's org") } if len(owners) == 0 { - return "", locale.NewInputError("err_no_org_name", "Your project's organization name could not be found") + return "", "", nil, "", "", nil, ErrNoOrg } owner := owners[0].URLName - // Create the config file, if the repo clone didn't already create it - configFile := filepath.Join(path, constants.ConfigFileName) + return owner, proj, commitID, branchName, language, pj.RepoURL, nil +} + +func CreateProjectFiles(checkoutPath, cachePath, owner, name, branch, commitID, language string) error { + configFile := filepath.Join(checkoutPath, constants.ConfigFileName) if !fileutils.FileExists(configFile) { - _, err = projectfile.Create(&projectfile.CreateParams{ + _, err := projectfile.Create(&projectfile.CreateParams{ Owner: owner, - Project: pj.Name, // match case on the Platform - BranchName: branch.Label, - Directory: path, - Language: language.String(), + Project: name, // match case on the Platform + BranchName: branch, + Directory: checkoutPath, + Language: language, Cache: cachePath, }) if err != nil { if osutils.IsAccessDeniedError(err) { - return "", &ErrNoPermission{err, path} + return &ErrNoPermission{checkoutPath} } - return "", errs.Wrap(err, "Could not create projectfile") + return errs.Wrap(err, "Could not create projectfile") } } - err = localcommit.Set(path, commitID.String()) - if err != nil { - return "", errs.Wrap(err, "Could not create local commit file") - } - - if r.config.GetBool(constants.OptinBuildscriptsConfig) { - if err := buildscript_runbit.Initialize(path, r.auth); err != nil { - return "", errs.Wrap(err, "Unable to initialize buildscript") - } + if err := localcommit.Set(checkoutPath, commitID); err != nil { + return errs.Wrap(err, "Could not create local commit file") } - return path, nil + return nil } func getLanguage(commitID strfmt.UUID, auth *authentication.Auth) (language.Language, error) { modelLanguage, err := model.LanguageByCommit(commitID, auth) if err != nil { - return language.Unset, locale.WrapError(err, "err_language_by_commit", "", string(commitID)) + return language.Unset, errs.Wrap(err, "Could not get language from commit ID '%s'", string(commitID)) } return language.MakeByNameAndVersion(modelLanguage.Name, modelLanguage.Version), nil diff --git a/internal/runbits/checkout/path.go b/internal/runbits/checkout/path.go index 372c7ed89f..3d0c52e7ac 100644 --- a/internal/runbits/checkout/path.go +++ b/internal/runbits/checkout/path.go @@ -37,15 +37,21 @@ func (r *Checkout) pathToUse(namespace *project.Namespaced, preferredPath string } type ErrAlreadyCheckedOut struct { - error Path string } +func (e ErrAlreadyCheckedOut) Error() string { + return "already checked out" +} + type ErrNoPermission struct { - error Path string } +func (e ErrNoPermission) Error() string { + return "no permission" +} + func validatePath(ns *project.Namespaced, path string) error { if !fileutils.TargetExists(path) { return nil @@ -61,7 +67,7 @@ func validatePath(ns *project.Namespaced, path string) error { configFile := filepath.Join(path, constants.ConfigFileName) if fileutils.FileExists(configFile) { - return &ErrAlreadyCheckedOut{errs.New("already checked out at %s", path), path} + return &ErrAlreadyCheckedOut{path} } return nil diff --git a/internal/runbits/checkout/rationalize.go b/internal/runbits/checkout/rationalize.go index d704d70901..4473917fc7 100644 --- a/internal/runbits/checkout/rationalize.go +++ b/internal/runbits/checkout/rationalize.go @@ -25,7 +25,7 @@ func (c *Checkout) rationalizeError(err *error) { case errors.As(*err, &errProjectNotFound): *err = errs.WrapUserFacing(*err, locale.Tr("err_api_project_not_found", errProjectNotFound.Organization, errProjectNotFound.Project), - errs.SetIf(!c.auth.Authenticated(), errs.SetTips(locale.T("tip_private_project_auth"))), + errs.SetIf(!c.prime.Auth().Authenticated(), errs.SetTips(locale.T("tip_private_project_auth"))), errs.SetInput(), ) case errors.As(*err, &errNoPermssion): diff --git a/internal/runbits/commits_runbit/time.go b/internal/runbits/commits_runbit/time.go new file mode 100644 index 0000000000..2ee606bd19 --- /dev/null +++ b/internal/runbits/commits_runbit/time.go @@ -0,0 +1,82 @@ +package commits_runbit + +import ( + "time" + + "github.com/ActiveState/cli/internal/captain" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/pkg/buildscript" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/platform/authentication" + "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/project" +) + +// ExpandTime returns a timestamp based on the given "--ts" value. +// If the timestamp was already defined, we just return it. +// If "now" was given, returns "now" according to the platform. +// Otherwise, returns the specified timestamp or nil (which falls back on the default Platform +// timestamp for a given operation) +func ExpandTime(ts *captain.TimeValue, auth *authentication.Auth) (time.Time, error) { + if ts != nil && ts.Time != nil { + return *ts.Time, nil + } + + if ts != nil && ts.Now() { + latest, err := model.FetchLatestRevisionTimeStamp(auth) + if err != nil { + return time.Time{}, errs.Wrap(err, "Unable to determine latest revision time") + } + return latest, nil + } + + latest, err := model.FetchLatestTimeStamp(auth) + if err != nil { + return time.Time{}, errs.Wrap(err, "Unable to fetch latest Platform timestamp") + } + + return latest, nil +} + +// ExpandTimeForProject is the same as ExpandTime except that it ensures the returned time is either the same or +// later than that of the most recent commit. +func ExpandTimeForProject(ts *captain.TimeValue, auth *authentication.Auth, proj *project.Project) (time.Time, error) { + timestamp, err := ExpandTime(ts, auth) + if err != nil { + return time.Time{}, errs.Wrap(err, "Unable to expand time") + } + + if proj != nil { + commitID, err := localcommit.Get(proj.Dir()) + if err != nil { + return time.Time{}, errs.Wrap(err, "Unable to get commit ID") + } + + atTime, err := model.FetchTimeStampForCommit(commitID, auth) + if err != nil { + return time.Time{}, errs.Wrap(err, "Unable to get commit time") + } + + if atTime.After(timestamp) { + return *atTime, nil + } + } + + return timestamp, nil +} + +// ExpandTimeForBuildScript is the same as ExpandTimeForProject except that it works off of a buildscript, allowing for +// fewer API round trips. +func ExpandTimeForBuildScript(ts *captain.TimeValue, auth *authentication.Auth, script *buildscript.BuildScript) (time.Time, error) { + timestamp, err := ExpandTime(ts, auth) + if err != nil { + return time.Time{}, errs.Wrap(err, "Unable to expand time") + } + + atTime := script.AtTime() + if atTime != nil && atTime.After(timestamp) { + return *atTime, nil + } + + return timestamp, nil +} diff --git a/internal/runbits/cves/cves.go b/internal/runbits/cves/cves.go new file mode 100644 index 0000000000..b9b598482b --- /dev/null +++ b/internal/runbits/cves/cves.go @@ -0,0 +1,269 @@ +package cves + +import ( + "fmt" + "strconv" + "strings" + + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/logging" + configMediator "github.com/ActiveState/cli/internal/mediators/config" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/pkg/buildplan" + vulnModel "github.com/ActiveState/cli/pkg/platform/api/vulnerabilities/model" + "github.com/ActiveState/cli/pkg/platform/api/vulnerabilities/request" + "github.com/ActiveState/cli/pkg/platform/model" +) + +func init() { + configMediator.RegisterOption(constants.SecurityPromptConfig, configMediator.Bool, true) + severities := configMediator.NewEnum([]string{ + vulnModel.SeverityCritical, + vulnModel.SeverityHigh, + vulnModel.SeverityMedium, + vulnModel.SeverityLow, + }, vulnModel.SeverityCritical) + configMediator.RegisterOption(constants.SecurityPromptLevelConfig, configMediator.Enum, severities) +} + +type primeable interface { + primer.Outputer + primer.Prompter + primer.Auther + primer.Configurer +} + +type CveReport struct { + prime primeable +} + +func NewCveReport(prime primeable) *CveReport { + return &CveReport{prime} +} + +func (c *CveReport) Report(newBuildPlan *buildplan.BuildPlan, oldBuildPlan *buildplan.BuildPlan) error { + changeset := newBuildPlan.DiffArtifacts(oldBuildPlan, oldBuildPlan == nil) + if c.shouldSkipReporting(changeset) { + logging.Debug("Skipping CVE reporting") + return nil + } + + var ingredients []*request.Ingredient + for _, change := range changeset.Filter(buildplan.ArtifactAdded) { + for _, ing := range change.Artifact.Ingredients { + ingredients = append(ingredients, &request.Ingredient{ + Namespace: ing.Namespace, + Name: ing.Name, + Version: ing.Version, + }) + } + } + + for _, change := range changeset.Filter(buildplan.ArtifactUpdated) { + if !change.VersionsChanged() { + continue // For CVE reporting we only care about ingredient changes + } + + for _, ing := range change.Artifact.Ingredients { + ingredients = append(ingredients, &request.Ingredient{ + Namespace: ing.Namespace, + Name: ing.Name, + Version: ing.Version, + }) + } + } + + names := changedRequirements(oldBuildPlan, newBuildPlan) + pg := output.StartSpinner(c.prime.Output(), locale.Tr("progress_cve_search", strings.Join(names, ", ")), constants.TerminalAnimationInterval) + + ingredientVulnerabilities, err := model.FetchVulnerabilitiesForIngredients(c.prime.Auth(), ingredients) + if err != nil { + return errs.Wrap(err, "Failed to retrieve vulnerabilities") + } + + // No vulnerabilities, nothing further to do here + if len(ingredientVulnerabilities) == 0 { + logging.Debug("No vulnerabilities found for ingredients") + pg.Stop(locale.T("progress_safe")) + pg = nil + return nil + } + + pg.Stop(locale.T("progress_unsafe")) + pg = nil + + vulnerabilities := model.CombineVulnerabilities(ingredientVulnerabilities, names...) + + if c.prime.Prompt() == nil || !c.shouldPromptForSecurity(vulnerabilities) { + c.warnCVEs(vulnerabilities) + return nil + } + + c.summarizeCVEs(vulnerabilities) + cont, err := c.promptForSecurity() + if err != nil { + return errs.Wrap(err, "Failed to prompt for security") + } + + if !cont { + if !c.prime.Prompt().IsInteractive() { + return errs.AddTips( + locale.NewInputError("err_pkgop_security_prompt", "Operation aborted due to security prompt"), + locale.Tl("more_info_prompt", "To disable security prompting run: [ACTIONABLE]state config set security.prompt.enabled false[/RESET]"), + ) + } + return locale.NewInputError("err_pkgop_security_prompt", "Operation aborted due to security prompt") + } + + return nil +} + +func (c *CveReport) shouldSkipReporting(changeset buildplan.ArtifactChangeset) bool { + if !c.prime.Auth().Authenticated() { + return true + } + + if c.prime.Output().Type().IsStructured() { + return true + } + + return len(changeset.Filter(buildplan.ArtifactAdded, buildplan.ArtifactUpdated)) == 0 +} + +func (c *CveReport) shouldPromptForSecurity(vulnerabilities model.VulnerableIngredientsByLevels) bool { + if !c.prime.Config().GetBool(constants.SecurityPromptConfig) || vulnerabilities.Count == 0 { + return false + } + + promptLevel := c.prime.Config().GetString(constants.SecurityPromptLevelConfig) + + logging.Debug("Prompt level: %s", promptLevel) + switch promptLevel { + case vulnModel.SeverityCritical: + return vulnerabilities.Critical.Count > 0 + case vulnModel.SeverityHigh: + return vulnerabilities.Critical.Count > 0 || + vulnerabilities.High.Count > 0 + case vulnModel.SeverityMedium: + return vulnerabilities.Critical.Count > 0 || + vulnerabilities.High.Count > 0 || + vulnerabilities.Medium.Count > 0 + case vulnModel.SeverityLow: + return vulnerabilities.Critical.Count > 0 || + vulnerabilities.High.Count > 0 || + vulnerabilities.Medium.Count > 0 || + vulnerabilities.Low.Count > 0 + } + + return false +} + +func (c *CveReport) warnCVEs(vulnerabilities model.VulnerableIngredientsByLevels) { + if vulnerabilities.Count == 0 { + return + } + + c.prime.Output().Notice("") + + counts := []string{} + formatString := "%d [%s]%s[/RESET]" + if count := vulnerabilities.Critical.Count; count > 0 { + counts = append(counts, fmt.Sprintf(formatString, count, "RED", locale.T("cve_critical"))) + } + if count := vulnerabilities.High.Count; count > 0 { + counts = append(counts, fmt.Sprintf(formatString, count, "ORANGE", locale.T("cve_high"))) + } + if count := vulnerabilities.Medium.Count; count > 0 { + counts = append(counts, fmt.Sprintf(formatString, count, "YELLOW", locale.T("cve_medium"))) + } + if count := vulnerabilities.Low.Count; count > 0 { + counts = append(counts, fmt.Sprintf(formatString, count, "MAGENTA", locale.T("cve_low"))) + } + + c.prime.Output().Notice(" " + locale.Tr("warning_vulnerable_short", strconv.Itoa(vulnerabilities.Count), strings.Join(counts, ", "))) +} + +func (c *CveReport) summarizeCVEs(vulnerabilities model.VulnerableIngredientsByLevels) { + out := c.prime.Output() + out.Print("") + + switch { + case vulnerabilities.CountPrimary == 0: + out.Print(" " + locale.Tr("warning_vulnerable_indirectonly", strconv.Itoa(vulnerabilities.Count))) + case vulnerabilities.CountPrimary == vulnerabilities.Count: + out.Print(" " + locale.Tr("warning_vulnerable_directonly", strconv.Itoa(vulnerabilities.Count))) + default: + out.Print(" " + locale.Tr("warning_vulnerable", strconv.Itoa(vulnerabilities.CountPrimary), strconv.Itoa(vulnerabilities.Count-vulnerabilities.CountPrimary))) + } + + printVulnerabilities := func(vulnerableIngredients model.VulnerableIngredientsByLevel, name, color string) { + if vulnerableIngredients.Count > 0 { + ings := []string{} + for _, vulns := range vulnerableIngredients.Ingredients { + prefix := "" + if vulnerabilities.Count > vulnerabilities.CountPrimary { + prefix = fmt.Sprintf("%s@%s: ", vulns.IngredientName, vulns.IngredientVersion) + } + ings = append(ings, fmt.Sprintf("%s[CYAN]%s[/RESET]", prefix, strings.Join(vulns.CVEIDs, ", "))) + } + out.Print(fmt.Sprintf(" • [%s]%d %s:[/RESET] %s", color, vulnerableIngredients.Count, name, strings.Join(ings, ", "))) + } + } + + printVulnerabilities(vulnerabilities.Critical, locale.T("cve_critical"), "RED") + printVulnerabilities(vulnerabilities.High, locale.T("cve_high"), "ORANGE") + printVulnerabilities(vulnerabilities.Medium, locale.T("cve_medium"), "YELLOW") + printVulnerabilities(vulnerabilities.Low, locale.T("cve_low"), "MAGENTA") + + out.Print("") + out.Print(" " + locale.T("more_info_vulnerabilities")) + out.Print(" " + locale.T("disable_prompting_vulnerabilities")) + out.Print("") +} + +func (c *CveReport) promptForSecurity() (bool, error) { + confirm, err := c.prime.Prompt().Confirm("", locale.Tr("prompt_continue_pkg_operation"), ptr.To(false)) + if err != nil { + return false, locale.WrapError(err, "err_pkgop_confirm", "Need a confirmation.") + } + c.prime.Output().Notice("") // Empty line + + return confirm, nil +} + +func changedRequirements(oldBuildPlan *buildplan.BuildPlan, newBuildPlan *buildplan.BuildPlan) []string { + var names []string + var oldRequirements buildplan.Requirements + if oldBuildPlan != nil { + oldRequirements = oldBuildPlan.Requirements() + } + newRequirements := newBuildPlan.Requirements() + + oldReqs := make(map[string]string) + for _, req := range oldRequirements { + oldReqs[qualifiedName(req)] = req.Ingredient.Version + } + + for _, req := range newRequirements { + if req.Namespace == buildplan.NamespaceInternal { + continue + } + if version, exists := oldReqs[qualifiedName(req)]; exists && version == req.Ingredient.Version { + continue + } + names = append(names, req.Name) + } + + return names +} + +func qualifiedName(req *buildplan.Requirement) string { + if req.Namespace == "" { + return req.Name + } + return req.Namespace + "/" + req.Name +} diff --git a/internal/runbits/dependencies/changesummary.go b/internal/runbits/dependencies/changesummary.go index c1e95af3f5..38720f40d1 100644 --- a/internal/runbits/dependencies/changesummary.go +++ b/internal/runbits/dependencies/changesummary.go @@ -28,21 +28,52 @@ func OutputChangeSummary(out output.Outputer, newBuildPlan *buildplan.BuildPlan, dependencies := buildplan.Ingredients{} directDependencies := buildplan.Ingredients{} changeset := newBuildPlan.DiffArtifacts(oldBuildPlan, false) - for _, a := range changeset.Added { - if _, exists := requested[a.ArtifactID]; exists { - v := fmt.Sprintf("%s@%s", a.Name(), a.Version()) - addedString = append(addedLocale, v) - addedLocale = append(addedLocale, fmt.Sprintf("[ACTIONABLE]%s[/RESET]", v)) + for _, change := range changeset.Filter(buildplan.ArtifactAdded) { + a := change.Artifact + if _, exists := requested[a.ArtifactID]; !exists { + continue } + v := fmt.Sprintf("%s@%s", a.Name(), a.Version()) + addedString = append(addedLocale, v) + addedLocale = append(addedLocale, fmt.Sprintf("[ACTIONABLE]%s[/RESET]", v)) + for _, i := range a.Ingredients { dependencies = append(dependencies, i.RuntimeDependencies(true)...) - directDependencies = append(dependencies, i.RuntimeDependencies(false)...) + directDependencies = append(directDependencies, i.RuntimeDependencies(false)...) + } + } + + // Check for any direct dependencies added by a requested package update. + for _, change := range changeset.Filter(buildplan.ArtifactUpdated) { + if _, exists := requested[change.Artifact.ArtifactID]; !exists { + continue + } + for _, dep := range change.Artifact.RuntimeDependencies(false, nil) { + for _, subchange := range changeset.Filter(buildplan.ArtifactAdded) { + a := subchange.Artifact + if a.ArtifactID != dep.ArtifactID { + continue + } + v := fmt.Sprintf("%s@%s", change.Artifact.Name(), change.Artifact.Version()) // updated/requested package, not added package + addedString = append(addedLocale, v) + addedLocale = append(addedLocale, fmt.Sprintf("[ACTIONABLE]%s[/RESET]", v)) + + for _, i := range a.Ingredients { // added package, not updated/requested package + dependencies = append(dependencies, i) + directDependencies = append(dependencies, i) + } + break + + } } } dependencies = sliceutils.UniqueByProperty(dependencies, func(i *buildplan.Ingredient) any { return i.IngredientID }) directDependencies = sliceutils.UniqueByProperty(directDependencies, func(i *buildplan.Ingredient) any { return i.IngredientID }) - numIndirect := len(dependencies) - len(directDependencies) + // Duplicate entries may occur when multiple artifacts share common dependencies. + addedLocale = sliceutils.Unique(addedLocale) + commonDependencies := directDependencies.CommonRuntimeDependencies().ToIDMap() + numIndirect := len(dependencies) - len(directDependencies) - len(commonDependencies) sort.SliceStable(directDependencies, func(i, j int) bool { return directDependencies[i].Name < directDependencies[j].Name @@ -54,6 +85,9 @@ func OutputChangeSummary(out output.Outputer, newBuildPlan *buildplan.BuildPlan, return } + // Output a summary of changes. + out.Notice("") // blank line + // Process the existing runtime requirements into something we can easily compare against. alreadyInstalled := buildplan.Artifacts{} if oldBuildPlan != nil { @@ -65,7 +99,7 @@ func OutputChangeSummary(out output.Outputer, newBuildPlan *buildplan.BuildPlan, if numIndirect > 0 { localeKey = "additional_total_dependencies" } - out.Notice(" " + locale.Tr(localeKey, strings.Join(addedLocale, ", "), strconv.Itoa(len(directDependencies)), strconv.Itoa(numIndirect))) + out.Notice(" " + locale.Tr(localeKey, strings.Join(addedLocale, ", "), strconv.Itoa(len(directDependencies)), strconv.Itoa(numIndirect))) // A direct dependency list item is of the form: // ├─ name@version (X dependencies) @@ -74,13 +108,17 @@ func OutputChangeSummary(out output.Outputer, newBuildPlan *buildplan.BuildPlan, // depending on whether or not it has subdependencies, and whether or not showUpdatedPackages is // `true`. for i, ingredient := range directDependencies { - prefix := " ├─" + prefix := output.TreeMid if i == len(directDependencies)-1 { - prefix = " └─" + prefix = output.TreeEnd } + // Retrieve runtime dependencies, and then filter out any dependencies that are common between all added ingredients. + runtimeDeps := ingredient.RuntimeDependencies(true) + runtimeDeps = runtimeDeps.Filter(func(i *buildplan.Ingredient) bool { _, ok := commonDependencies[i.IngredientID]; return !ok }) + subdependencies := "" - if numSubs := len(ingredient.RuntimeDependencies(true)); numSubs > 0 { + if numSubs := len(runtimeDeps); numSubs > 0 { subdependencies = fmt.Sprintf(" ([ACTIONABLE]%s[/RESET] dependencies)", // intentional leading space strconv.Itoa(numSubs)) } diff --git a/internal/runbits/dependencies/summary.go b/internal/runbits/dependencies/summary.go index 341275c37c..33fc2f6a49 100644 --- a/internal/runbits/dependencies/summary.go +++ b/internal/runbits/dependencies/summary.go @@ -18,25 +18,33 @@ func OutputSummary(out output.Outputer, directDependencies buildplan.Artifacts) } ingredients := directDependencies.Filter(buildplan.FilterStateArtifacts()).Ingredients() + commonDependencies := ingredients.CommonRuntimeDependencies().ToIDMap() sort.SliceStable(ingredients, func(i, j int) bool { return ingredients[i].Name < ingredients[j].Name }) - out.Notice(locale.Tl("setting_up_dependencies", "Setting up the following dependencies:")) + out.Notice("") // blank line + out.Notice(locale.Tl("setting_up_dependencies", " Setting up the following dependencies:")) for i, ingredient := range ingredients { - prefix := "├─" + prefix := " " + output.TreeMid if i == len(ingredients)-1 { - prefix = "└─" + prefix = " " + output.TreeEnd } - subdependencies := "" - if numSubs := len(ingredient.RuntimeDependencies(true)); numSubs > 0 { - subdependencies = locale.Tl("summary_subdeps", "([ACTIONABLE]{{.V0}}[/RESET] sub-dependencies)", strconv.Itoa(numSubs)) + subDependencies := ingredient.RuntimeDependencies(true) + if _, isCommon := commonDependencies[ingredient.IngredientID]; !isCommon { + // If the ingredient is itself not a common sub-dependency; filter out any common sub dependencies so we don't + // report counts multiple times. + subDependencies = subDependencies.Filter(buildplan.FilterOutIngredients{commonDependencies}.Filter) + } + subdepLocale := "" + if numSubs := len(subDependencies); numSubs > 0 { + subdepLocale = locale.Tl("summary_subdeps", "([ACTIONABLE]{{.V0}}[/RESET] sub-dependencies)", strconv.Itoa(numSubs)) } - item := fmt.Sprintf("[ACTIONABLE]%s@%s[/RESET] %s", ingredient.Name, ingredient.Version, subdependencies) + item := fmt.Sprintf("[ACTIONABLE]%s@%s[/RESET] %s", ingredient.Name, ingredient.Version, subdepLocale) out.Notice(fmt.Sprintf("[DISABLED]%s[/RESET] %s", prefix, item)) } diff --git a/internal/runbits/errors/errors.go b/internal/runbits/errors/errors.go index 4ca65b7166..eb7cd1c865 100644 --- a/internal/runbits/errors/errors.go +++ b/internal/runbits/errors/errors.go @@ -177,7 +177,7 @@ func ReportError(err error, cmd *captain.Command, an analytics.Dispatcher) { _, hasMarshaller := err.(output.Marshaller) cmdName := cmd.Name() - childCmd, findErr := cmd.Find(os.Args[1:]) + childCmd, findErr := cmd.FindChild(os.Args[1:]) if findErr != nil { logging.Error("Could not find child command: %v", findErr) } diff --git a/internal/runbits/hello_example.go b/internal/runbits/example/hello_example.go similarity index 96% rename from internal/runbits/hello_example.go rename to internal/runbits/example/hello_example.go index 53e852d31f..4b4b39b0ff 100644 --- a/internal/runbits/hello_example.go +++ b/internal/runbits/example/hello_example.go @@ -1,4 +1,4 @@ -package runbits +package example import ( "github.com/ActiveState/cli/internal/errs" diff --git a/internal/runbits/findproject/project.go b/internal/runbits/findproject/project.go index 024307f927..b488365884 100644 --- a/internal/runbits/findproject/project.go +++ b/internal/runbits/findproject/project.go @@ -1,6 +1,7 @@ package findproject import ( + "errors" "sort" "strings" @@ -18,7 +19,8 @@ type LocalProjectDoesNotExist struct{ *locale.LocalizedError } // IsLocalProjectDoesNotExistError checks if the error is a LocalProjectDoesNotExist. func IsLocalProjectDoesNotExistError(err error) bool { - return errs.Matches(err, &LocalProjectDoesNotExist{}) + var errLocalProjectDoesNotExist *LocalProjectDoesNotExist + return errors.As(err, &errLocalProjectDoesNotExist) } func FromInputByPriority(path string, ns *project.Namespaced, cfg projectfile.ConfigGetter, prompt prompt.Prompter) (*project.Project, error) { diff --git a/internal/runbits/git/git.go b/internal/runbits/git/git.go index aa3a6ace06..76d4d5483a 100644 --- a/internal/runbits/git/git.go +++ b/internal/runbits/git/git.go @@ -58,7 +58,7 @@ func (r *Repo) CloneProject(owner, name, path string, out output.Outputer, an an Progress: os.Stdout, }) if err != nil { - err = locale.WrapError(err, "err_clone_repo", "Could not clone repository with URL: {{.V0}}, error received: {{.V1}}.", *project.RepoURL, err.Error()) + err = locale.WrapInputError(err, "err_clone_repo", "Could not clone repository with URL: {{.V0}}. Error received: {{.V1}}.", *project.RepoURL, err.Error()) tipMsg := locale.Tl( "err_tip_git_ssh-add", "If you are using an SSH key please ensure it's configured by running '[ACTIONABLE]ssh-add [/RESET]'.", diff --git a/internal/runbits/org/org.go b/internal/runbits/org/org.go new file mode 100644 index 0000000000..0da7640e55 --- /dev/null +++ b/internal/runbits/org/org.go @@ -0,0 +1,70 @@ +package org + +import ( + "strings" + + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/pkg/platform/authentication" + "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/project" +) + +var ErrNoOwner = errs.New("Could not find organization") + +type ErrOwnerNotFound struct { + DesiredOwner string +} + +func (e ErrOwnerNotFound) Error() string { + return "could not find this organization" +} + +type configurer interface { + GetString(string) string +} + +// Get returns the name of an organization/owner in order of precedence: +// - Returns the normalized form of the given org name. +// - Returns the name of the most recently used org. +// - Returns the name of the first org you are a member of. +func Get(desiredOrg string, auth *authentication.Auth, cfg configurer) (string, error) { + orgs, err := model.FetchOrganizations(auth) + if err != nil { + return "", errs.Wrap(err, "Unable to get the user's writable orgs") + } + + // Prefer the desired org if it's valid + if desiredOrg != "" { + // Match the case of the organization. + // Otherwise the incorrect case will be written to the project file. + for _, org := range orgs { + if strings.EqualFold(org.URLname, desiredOrg) { + return org.URLname, nil + } + } + return "", &ErrOwnerNotFound{desiredOrg} + } + + // Use the last used namespace if it's valid + lastUsed := cfg.GetString(constants.LastUsedNamespacePrefname) + if lastUsed != "" { + ns, err := project.ParseNamespace(lastUsed) + if err != nil { + return "", errs.Wrap(err, "Unable to parse last used namespace") + } + + for _, org := range orgs { + if strings.EqualFold(org.URLname, ns.Owner) { + return org.URLname, nil + } + } + } + + // Use the first org if there is one + if len(orgs) > 0 { + return orgs[0].URLname, nil + } + + return "", ErrNoOwner +} diff --git a/internal/runbits/rationalizers/commit.go b/internal/runbits/rationalizers/commit.go new file mode 100644 index 0000000000..eff0a3a151 --- /dev/null +++ b/internal/runbits/rationalizers/commit.go @@ -0,0 +1,46 @@ +package rationalizers + +import ( + "errors" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" +) + +func HandleCommitErrors(rerr *error) { + var commitError *bpResp.CommitError + if !errors.As(*rerr, &commitError) { + return + } + switch commitError.Type { + case types.NotFoundErrorType: + *rerr = errs.WrapUserFacing(*rerr, + locale.Tl("err_packages_not_found", "Could not make runtime changes because your project was not found."), + errs.SetInput(), + errs.SetTips(locale.T("tip_private_project_auth")), + ) + case types.ForbiddenErrorType: + *rerr = errs.WrapUserFacing(*rerr, + locale.Tl("err_packages_forbidden", "Could not make runtime changes because you do not have permission to do so."), + errs.SetInput(), + errs.SetTips(locale.T("tip_private_project_auth")), + ) + case types.HeadOnBranchMovedErrorType: + *rerr = errs.WrapUserFacing(*rerr, + locale.T("err_buildplanner_head_on_branch_moved"), + errs.SetInput(), + ) + case types.NoChangeSinceLastCommitErrorType: + *rerr = errs.WrapUserFacing(*rerr, + locale.Tl("err_commit_nochanges", "There are no changes since the last commit."), + errs.SetInput(), + ) + default: + *rerr = errs.WrapUserFacing(*rerr, + locale.Tl("err_packages_buildplanner_error", "Could not make runtime changes due to the following error: {{.V0}}", commitError.Message), + errs.SetInput(), + ) + } +} diff --git a/internal/runbits/rationalizers/readme.md b/internal/runbits/rationalizers/readme.md new file mode 100644 index 0000000000..aed768812d --- /dev/null +++ b/internal/runbits/rationalizers/readme.md @@ -0,0 +1,4 @@ +The rationalizers package is intended to be used for common error rationalizers that are shared between multiple +runners. + +In MOST cases your rationalizer should be package specific, so don't default to using the rationalizers package. diff --git a/internal/runbits/reqop_runbit/update.go b/internal/runbits/reqop_runbit/update.go new file mode 100644 index 0000000000..395f4797c7 --- /dev/null +++ b/internal/runbits/reqop_runbit/update.go @@ -0,0 +1,149 @@ +package reqop_runbit + +import ( + "errors" + "fmt" + "strings" + + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/runbits/buildscript" + "github.com/ActiveState/cli/internal/runbits/cves" + "github.com/ActiveState/cli/internal/runbits/dependencies" + "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" + "github.com/ActiveState/cli/pkg/buildscript" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/platform/model/buildplanner" + "github.com/ActiveState/cli/pkg/runtime" + "github.com/go-openapi/strfmt" +) + +type primeable interface { + primer.Outputer + primer.Prompter + primer.Projecter + primer.Auther + primer.Configurer + primer.Analyticer + primer.SvcModeler +} + +type requirements []*Requirement + +func (r requirements) String() string { + result := []string{} + for _, req := range r { + result = append(result, fmt.Sprintf("%s/%s", req.Namespace, req.Name)) + } + return strings.Join(result, ", ") +} + +type Requirement struct { + Name string + Namespace model.Namespace + Version []types.VersionRequirement +} + +func UpdateAndReload(prime primeable, script *buildscript.BuildScript, oldCommit *buildplanner.Commit, commitMsg string, trigger trigger.Trigger) error { + pj := prime.Project() + out := prime.Output() + cfg := prime.Config() + bp := buildplanner.NewBuildPlannerModel(prime.Auth(), prime.SvcModel()) + + var pg *output.Spinner + defer func() { + if pg != nil { + pg.Stop(locale.T("progress_fail")) + } + }() + pg = output.StartSpinner(out, locale.T("progress_solve_preruntime"), constants.TerminalAnimationInterval) + + commitParams := buildplanner.StageCommitParams{ + Owner: pj.Owner(), + Project: pj.Name(), + ParentCommit: string(oldCommit.CommitID), + Description: commitMsg, + Script: script, + } + + // Solve runtime + newCommit, err := bp.StageCommit(commitParams) + if err != nil { + return errs.Wrap(err, "Could not stage commit") + } + + // Stop process of creating the commit + pg.Stop(locale.T("progress_success")) + pg = nil + + // Report changes and CVEs to user + dependencies.OutputChangeSummary(out, newCommit.BuildPlan(), oldCommit.BuildPlan()) + if err := cves.NewCveReport(prime).Report(newCommit.BuildPlan(), oldCommit.BuildPlan()); err != nil { + return errs.Wrap(err, "Could not report CVEs") + } + + // Start runtime sourcing UI + // Note normally we'd defer to Update's logic of async runtimes, but the reason we do this is to allow for solve + // errors to still be relayed even when using async. In this particular case the solving logic already happened + // when we created the commit, so running it again doesn't provide any value and only would slow things down. + if !cfg.GetBool(constants.AsyncRuntimeConfig) { + // refresh or install runtime + _, err := runtime_runbit.Update(prime, trigger, + runtime_runbit.WithCommit(newCommit), + runtime_runbit.WithoutBuildscriptValidation(), + ) + if err != nil { + if !isBuildError(err) { + // If the error is not a build error we still want to update the commit + if err2 := updateCommitID(prime, newCommit.CommitID); err2 != nil { + return errs.Pack(err, locale.WrapError(err2, "err_package_update_commit_id")) + } + } + return errs.Wrap(err, "Failed to refresh runtime") + } + } else { + prime.Output().Notice("") // blank line + prime.Output().Notice(locale.Tr("notice_async_runtime", constants.AsyncRuntimeConfig)) + } + + // Update commit ID + if err := updateCommitID(prime, newCommit.CommitID); err != nil { + return locale.WrapError(err, "err_package_update_commit_id") + } + return nil +} + +func updateCommitID(prime primeable, commitID strfmt.UUID) error { + if err := localcommit.Set(prime.Project().Dir(), commitID.String()); err != nil { + return locale.WrapError(err, "err_package_update_commit_id") + } + + if prime.Config().GetBool(constants.OptinBuildscriptsConfig) { + bp := buildplanner.NewBuildPlannerModel(prime.Auth(), prime.SvcModel()) + script, err := bp.GetBuildScript(commitID.String()) + if err != nil { + return errs.Wrap(err, "Could not get remote build expr and time") + } + + err = buildscript_runbit.Update(prime.Project(), script) + if err != nil { + return locale.WrapError(err, "err_update_build_script") + } + } + + return nil +} + +func isBuildError(err error) bool { + var errBuild *runtime.BuildError + var errBuildPlanner *response.BuildPlannerError + + return errors.As(err, &errBuild) || errors.As(err, &errBuildPlanner) +} diff --git a/internal/runbits/requirements/rationalize.go b/internal/runbits/requirements/rationalize.go deleted file mode 100644 index 469066cf17..0000000000 --- a/internal/runbits/requirements/rationalize.go +++ /dev/null @@ -1,87 +0,0 @@ -package requirements - -import ( - "errors" - - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/runbits/rationalize" - bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" - "github.com/ActiveState/cli/pkg/platform/model" -) - -func (r *RequirementOperation) rationalizeError(err *error) { - var tooManyMatchesErr *model.ErrTooManyMatches - var noMatchesErr *ErrNoMatches - var buildPlannerErr *bpResp.BuildPlannerError - var resolveNamespaceErr *ResolveNamespaceError - - switch { - case err == nil: - return - - // Too many matches - case errors.As(*err, &tooManyMatchesErr): - *err = errs.WrapUserFacing(*err, - locale.Tr("err_searchingredient_toomany", tooManyMatchesErr.Query), - errs.SetInput()) - - // No matches, and no alternate suggestions - case errors.As(*err, &noMatchesErr) && noMatchesErr.Alternatives == nil: - *err = errs.WrapUserFacing(*err, - locale.Tr("package_ingredient_alternatives_nosuggest", noMatchesErr.Query), - errs.SetInput()) - - // No matches, but have alternate suggestions - case errors.As(*err, &noMatchesErr) && noMatchesErr.Alternatives != nil: - *err = errs.WrapUserFacing(*err, - locale.Tr("package_ingredient_alternatives", noMatchesErr.Query, *noMatchesErr.Alternatives), - errs.SetInput()) - - // We communicate buildplanner errors verbatim as the intend is that these are curated by the buildplanner - case errors.As(*err, &buildPlannerErr): - *err = errs.WrapUserFacing(*err, - buildPlannerErr.LocalizedError(), - errs.SetIf(buildPlannerErr.InputError(), errs.SetInput())) - - // Headless - case errors.Is(*err, rationalize.ErrHeadless): - *err = errs.WrapUserFacing(*err, - locale.Tl( - "err_requirement_headless", - "Cannot update requirements for a headless project. Please visit {{.V0}} to convert your project and try again.", - r.Project.URL(), - ), - errs.SetInput()) - - case errors.Is(*err, errNoRequirements): - *err = errs.WrapUserFacing(*err, - locale.Tl("err_no_requirements", - "No requirements have been provided for this operation.", - ), - errs.SetInput(), - ) - - case errors.As(*err, &resolveNamespaceErr): - *err = errs.WrapUserFacing(*err, - locale.Tl("err_resolve_namespace", - "Could not resolve namespace for requirement '{{.V0}}'.", - resolveNamespaceErr.Name, - ), - errs.SetInput(), - ) - - case errors.Is(*err, errInitialNoRequirement): - *err = errs.WrapUserFacing(*err, - locale.T("err_initial_no_requirement"), - errs.SetInput(), - ) - - case errors.Is(*err, errNoLanguage): - *err = errs.WrapUserFacing(*err, - locale.Tl("err_no_language", "Could not determine which language namespace to search for packages in. Please supply the language flag."), - errs.SetInput(), - ) - - } -} diff --git a/internal/runbits/requirements/requirements.go b/internal/runbits/requirements/requirements.go deleted file mode 100644 index 09e6d21457..0000000000 --- a/internal/runbits/requirements/requirements.go +++ /dev/null @@ -1,940 +0,0 @@ -package requirements - -import ( - "fmt" - "os" - "regexp" - "strconv" - "strings" - "time" - - "github.com/ActiveState/cli/internal/analytics" - anaConsts "github.com/ActiveState/cli/internal/analytics/constants" - "github.com/ActiveState/cli/internal/captain" - "github.com/ActiveState/cli/internal/config" - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" - configMediator "github.com/ActiveState/cli/internal/mediators/config" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/internal/output" - "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/prompt" - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/ActiveState/cli/internal/runbits" - buildscript_runbit "github.com/ActiveState/cli/internal/runbits/buildscript" - "github.com/ActiveState/cli/internal/runbits/dependencies" - "github.com/ActiveState/cli/internal/runbits/rationalize" - runbit "github.com/ActiveState/cli/internal/runbits/runtime" - "github.com/ActiveState/cli/pkg/buildplan" - "github.com/ActiveState/cli/pkg/buildscript" - "github.com/ActiveState/cli/pkg/localcommit" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - medmodel "github.com/ActiveState/cli/pkg/platform/api/mediator/model" - vulnModel "github.com/ActiveState/cli/pkg/platform/api/vulnerabilities/model" - "github.com/ActiveState/cli/pkg/platform/api/vulnerabilities/request" - "github.com/ActiveState/cli/pkg/platform/authentication" - "github.com/ActiveState/cli/pkg/platform/model" - bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/platform/runtime/target" - "github.com/ActiveState/cli/pkg/project" - "github.com/ActiveState/cli/pkg/sysinfo" - "github.com/go-openapi/strfmt" - "github.com/thoas/go-funk" -) - -func init() { - configMediator.RegisterOption(constants.SecurityPromptConfig, configMediator.Bool, true) - configMediator.RegisterOption(constants.SecurityPromptLevelConfig, configMediator.String, vulnModel.SeverityCritical) -} - -type PackageVersion struct { - captain.NameVersionValue -} - -func (pv *PackageVersion) Set(arg string) error { - err := pv.NameVersionValue.Set(arg) - if err != nil { - return locale.WrapInputError(err, "err_package_format", "The package and version provided is not formatting correctly, must be in the form of @") - } - return nil -} - -type RequirementOperation struct { - Output output.Outputer - Prompt prompt.Prompter - Project *project.Project - Auth *authentication.Auth - Config *config.Instance - Analytics analytics.Dispatcher - SvcModel *model.SvcModel -} - -type primeable interface { - primer.Outputer - primer.Prompter - primer.Projecter - primer.Auther - primer.Configurer - primer.Analyticer - primer.SvcModeler -} - -func NewRequirementOperation(prime primeable) *RequirementOperation { - return &RequirementOperation{ - prime.Output(), - prime.Prompt(), - prime.Project(), - prime.Auth(), - prime.Config(), - prime.Analytics(), - prime.SvcModel(), - } -} - -const latestVersion = "latest" - -type ErrNoMatches struct { - *locale.LocalizedError - Query string - Alternatives *string -} - -var errNoRequirements = errs.New("No requirements were provided") - -var errInitialNoRequirement = errs.New("Could not find compatible requirement for initial commit") - -var errNoLanguage = errs.New("No language") - -var versionRe = regexp.MustCompile(`^\d(\.\d+)*$`) - -// Requirement represents a package, language or platform requirement -// For now, be aware that you should never provide BOTH ns AND nsType, one or the other should always be nil, but never both. -// The refactor should clean this up. -type Requirement struct { - Name string - Version string - Revision *int - BitWidth int // Only needed for platform requirements - Namespace *model.Namespace - NamespaceType *model.NamespaceType - Operation types.Operation - - // The following fields are set during execution - langName string - langVersion string - validatePkg bool - appendVersionWildcard bool - originalRequirementName string - versionRequirements []types.VersionRequirement -} - -// ExecuteRequirementOperation executes the operation on the requirement -// This has become quite unwieldy, and is ripe for a refactor - https://activestatef.atlassian.net/browse/DX-1897 -func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requirements ...*Requirement) (rerr error) { - defer r.rationalizeError(&rerr) - - if len(requirements) == 0 { - return errNoRequirements - } - - out := r.Output - var pg *output.Spinner - defer func() { - if pg != nil { - // This is a bit awkward, but it would be even more awkward to manually address this for every error condition - pg.Stop(locale.T("progress_fail")) - } - }() - - if r.Project == nil { - return rationalize.ErrNoProject - } - if r.Project.IsHeadless() { - return rationalize.ErrHeadless - } - out.Notice(locale.Tr("operating_message", r.Project.NamespaceString(), r.Project.Dir())) - - if err := r.resolveNamespaces(ts, requirements...); err != nil { - return errs.Wrap(err, "Could not resolve namespaces") - } - - if err := r.validatePackages(requirements...); err != nil { - return errs.Wrap(err, "Could not validate packages") - } - - parentCommitID, err := localcommit.Get(r.Project.Dir()) - if err != nil { - return errs.Wrap(err, "Unable to get local commit") - } - hasParentCommit := parentCommitID != "" - - pg = output.StartSpinner(out, locale.T("progress_commit"), constants.TerminalAnimationInterval) - - if err := r.checkForUpdate(parentCommitID, requirements...); err != nil { - return locale.WrapError(err, "err_check_for_update", "Could not check for requirements updates") - } - - if !hasParentCommit { - // Use first requirement to extract language for initial commit - var requirement *Requirement - for _, r := range requirements { - if r.Namespace.Type() == model.NamespacePackage || r.Namespace.Type() == model.NamespaceBundle { - requirement = r - break - } - } - - if requirement == nil { - return errInitialNoRequirement - } - - languageFromNs := model.LanguageFromNamespace(requirement.Namespace.String()) - parentCommitID, err = model.CommitInitial(sysinfo.OS().String(), languageFromNs, requirement.langVersion, r.Auth) - if err != nil { - return locale.WrapError(err, "err_install_no_project_commit", "Could not create initial commit for new project") - } - } - - if err := r.resolveRequirements(requirements...); err != nil { - return locale.WrapError(err, "err_resolve_requirements", "Could not resolve one or more requirements") - } - - bp := bpModel.NewBuildPlannerModel(r.Auth) - script, err := r.prepareBuildScript(bp, parentCommitID, requirements, ts) - if err != nil { - return errs.Wrap(err, "Could not prepare build script") - } - - params := bpModel.StageCommitParams{ - Owner: r.Project.Owner(), - Project: r.Project.Name(), - ParentCommit: string(parentCommitID), - Description: commitMessage(requirements...), - Script: script, - } - - commitID, err := bp.StageCommit(params) - if err != nil { - return locale.WrapError(err, "err_package_save_and_build", "Error occurred while trying to create a commit") - } - - pg.Stop(locale.T("progress_success")) - pg = nil - - if strings.ToLower(os.Getenv(constants.DisableRuntime)) != "true" { - ns := requirements[0].Namespace - var trigger target.Trigger - switch ns.Type() { - case model.NamespaceLanguage: - trigger = target.TriggerLanguage - case model.NamespacePlatform: - trigger = target.TriggerPlatform - default: - trigger = target.TriggerPackage - } - - // Solve runtime - rt, rtCommit, err := runbit.Solve(r.Auth, r.Output, r.Analytics, r.Project, &commitID, trigger, r.SvcModel, r.Config, runbit.OptNone) - if err != nil { - return errs.Wrap(err, "Could not solve runtime") - } - - // Get old buildplan - // We can't use the local store here; because it might not exist (ie. integrationt test, user cleaned cache, ..), - // but also there's no guarantee the old one is sequential to the current. - oldCommit, err := model.GetCommit(commitID, r.Auth) - if err != nil { - return errs.Wrap(err, "Could not get commit") - } - - var oldBuildPlan *buildplan.BuildPlan - rtTarget := target.NewProjectTarget(r.Project, &commitID, trigger) - if oldCommit.ParentCommitID != "" { - bpm := bpModel.NewBuildPlannerModel(r.Auth) - commit, err := bpm.FetchCommit(oldCommit.ParentCommitID, rtTarget.Owner(), rtTarget.Name(), nil) - if err != nil { - return errs.Wrap(err, "Failed to fetch build result") - } - oldBuildPlan = commit.BuildPlan() - } - - r.Output.Notice("") // blank line - dependencies.OutputChangeSummary(r.Output, rtCommit.BuildPlan(), oldBuildPlan) - - // Report CVEs - changedArtifacts := rtCommit.BuildPlan().DiffArtifacts(oldBuildPlan, false) - if err := r.cveReport(changedArtifacts, requirements...); err != nil { - return errs.Wrap(err, "Could not report CVEs") - } - - // Start runtime update UI - if !r.Config.GetBool(constants.AsyncRuntimeConfig) { - out.Notice("") - if !rt.HasCache() { - out.Notice(output.Title(locale.T("install_runtime"))) - out.Notice(locale.T("install_runtime_info")) - } else { - out.Notice(output.Title(locale.T("update_runtime"))) - out.Notice(locale.T("update_runtime_info")) - } - - // refresh or install runtime - err = runbit.UpdateByReference(rt, rtCommit, r.Auth, r.Project, r.Output, r.Config, runbit.OptMinimalUI) - if err != nil { - if !runbits.IsBuildError(err) { - // If the error is not a build error we want to retain the changes - if err2 := r.updateCommitID(commitID); err2 != nil { - return errs.Pack(err, locale.WrapError(err2, "err_package_update_commit_id")) - } - } - return errs.Wrap(err, "Failed to refresh runtime") - } - } - } - - if err := r.updateCommitID(commitID); err != nil { - return locale.WrapError(err, "err_package_update_commit_id") - } - - if !hasParentCommit { - out.Notice(locale.Tr("install_initial_success", r.Project.Source().Path())) - } - - // Print the result - r.outputResults(requirements...) - - out.Notice(locale.T("operation_success_local")) - - return nil -} - -func (r *RequirementOperation) prepareBuildScript(bp *bpModel.BuildPlanner, parentCommit strfmt.UUID, requirements []*Requirement, ts *time.Time) (*buildscript.BuildScript, error) { - script, err := bp.GetBuildScript(string(parentCommit)) - if err != nil { - return nil, errs.Wrap(err, "Failed to get build expression") - } - - if ts != nil { - script.SetAtTime(*ts) - } else { - // If no atTime was provided then we need to ensure that the atTime in the script is updated to use - // the most recent, which is either the current value or the platform latest. - latest, err := model.FetchLatestTimeStamp(r.Auth) - if err != nil { - return nil, errs.Wrap(err, "Unable to fetch latest Platform timestamp") - } - atTime := script.AtTime() - if atTime == nil || latest.After(*atTime) { - script.SetAtTime(latest) - } - } - - for _, req := range requirements { - if req.Namespace.String() == types.NamespacePlatform { - err = script.UpdatePlatform(req.Operation, strfmt.UUID(req.Name)) - if err != nil { - return nil, errs.Wrap(err, "Failed to update build expression with platform") - } - } else { - requirement := types.Requirement{ - Namespace: req.Namespace.String(), - Name: req.Name, - VersionRequirement: req.versionRequirements, - Revision: req.Revision, - } - - err = script.UpdateRequirement(req.Operation, requirement) - if err != nil { - return nil, errs.Wrap(err, "Failed to update build expression with requirement") - } - } - } - - return script, nil -} - -type ResolveNamespaceError struct { - error - Name string -} - -func (r *RequirementOperation) resolveNamespaces(ts *time.Time, requirements ...*Requirement) error { - for _, requirement := range requirements { - if err := r.resolveNamespace(ts, requirement); err != nil { - if err != errNoLanguage { - err = &ResolveNamespaceError{err, requirement.Name} - } - return errs.Wrap(err, "Unable to resolve namespace") - } - } - return nil -} - -func (r *RequirementOperation) resolveNamespace(ts *time.Time, requirement *Requirement) error { - requirement.langName = "undetermined" - - if requirement.NamespaceType != nil { - switch *requirement.NamespaceType { - case model.NamespacePackage, model.NamespaceBundle: - commitID, err := localcommit.Get(r.Project.Dir()) - if err != nil { - return errs.Wrap(err, "Unable to get local commit") - } - - language, err := model.LanguageByCommit(commitID, r.Auth) - if err != nil { - logging.Debug("Could not get language from project: %v", err) - } - if language.Name == "" { - return errNoLanguage - } - requirement.langName = language.Name - requirement.Namespace = ptr.To(model.NewNamespacePkgOrBundle(requirement.langName, *requirement.NamespaceType)) - case model.NamespaceLanguage: - requirement.Namespace = ptr.To(model.NewNamespaceLanguage()) - case model.NamespacePlatform: - requirement.Namespace = ptr.To(model.NewNamespacePlatform()) - } - } - - ns := requirement.Namespace - nsType := requirement.NamespaceType - requirement.validatePkg = requirement.Operation == types.OperationAdded && ns != nil && (ns.Type() == model.NamespacePackage || ns.Type() == model.NamespaceBundle || ns.Type() == model.NamespaceLanguage) - if (ns == nil || !ns.IsValid()) && nsType != nil && (*nsType == model.NamespacePackage || *nsType == model.NamespaceBundle) { - pg := output.StartSpinner(r.Output, locale.Tr("progress_pkg_nolang", requirement.Name), constants.TerminalAnimationInterval) - - supported, err := model.FetchSupportedLanguages(sysinfo.OS().String()) - if err != nil { - return errs.Wrap(err, "Failed to retrieve the list of supported languages") - } - - var nsv model.Namespace - var supportedLang *medmodel.SupportedLanguage - requirement.Name, nsv, supportedLang, err = resolvePkgAndNamespace(r.Prompt, requirement.Name, *requirement.NamespaceType, supported, ts, r.Auth) - if err != nil { - return errs.Wrap(err, "Could not resolve pkg and namespace") - } - requirement.Namespace = &nsv - requirement.langVersion = supportedLang.DefaultVersion - requirement.langName = supportedLang.Name - - requirement.validatePkg = false - - pg.Stop(locale.T("progress_found")) - } - - if requirement.Namespace == nil { - return locale.NewError("err_package_invalid_namespace_detected", "No valid namespace could be detected") - } - - return nil -} - -func (r *RequirementOperation) validatePackages(requirements ...*Requirement) error { - var requirementsToValidate []*Requirement - for _, requirement := range requirements { - if !requirement.validatePkg { - continue - } - requirementsToValidate = append(requirementsToValidate, requirement) - } - - if len(requirementsToValidate) == 0 { - return nil - } - - pg := output.StartSpinner(r.Output, locale.Tr("progress_search", strings.Join(requirementNames(requirementsToValidate...), ", ")), constants.TerminalAnimationInterval) - for _, requirement := range requirementsToValidate { - if err := r.validatePackage(requirement); err != nil { - return errs.Wrap(err, "Could not validate package") - } - } - pg.Stop(locale.T("progress_found")) - - return nil -} - -func (r *RequirementOperation) validatePackage(requirement *Requirement) error { - if strings.ToLower(requirement.Version) == latestVersion { - requirement.Version = "" - } - - requirement.originalRequirementName = requirement.Name - normalized, err := model.FetchNormalizedName(*requirement.Namespace, requirement.Name, r.Auth) - if err != nil { - multilog.Error("Failed to normalize '%s': %v", requirement.Name, err) - } - - packages, err := model.SearchIngredientsStrict(requirement.Namespace.String(), normalized, false, false, nil, r.Auth) // ideally case-sensitive would be true (PB-4371) - if err != nil { - return locale.WrapError(err, "package_err_cannot_obtain_search_results") - } - - if len(packages) == 0 { - suggestions, err := getSuggestions(*requirement.Namespace, requirement.Name, r.Auth) - if err != nil { - multilog.Error("Failed to retrieve suggestions: %v", err) - } - - if len(suggestions) == 0 { - return &ErrNoMatches{ - locale.WrapExternalError(err, "package_ingredient_alternatives_nosuggest", "", requirement.Name), - requirement.Name, nil} - } - - return &ErrNoMatches{ - locale.WrapExternalError(err, "package_ingredient_alternatives", "", requirement.Name, strings.Join(suggestions, "\n")), - requirement.Name, ptr.To(strings.Join(suggestions, "\n"))} - } - - if normalized != "" && normalized != requirement.Name { - requirement.Name = normalized - } - - // If a bare version number was given, and if it is a partial version number (e.g. requests@2), - // we'll want to ultimately append a '.x' suffix. - if versionRe.MatchString(requirement.Version) { - for _, knownVersion := range packages[0].Versions { - if knownVersion.Version == requirement.Version { - break - } else if strings.HasPrefix(knownVersion.Version, requirement.Version) { - requirement.appendVersionWildcard = true - } - } - } - - return nil -} - -func (r *RequirementOperation) checkForUpdate(parentCommitID strfmt.UUID, requirements ...*Requirement) error { - for _, requirement := range requirements { - // Check if this is an addition or an update - if requirement.Operation == types.OperationAdded && parentCommitID != "" { - req, err := model.GetRequirement(parentCommitID, *requirement.Namespace, requirement.Name, r.Auth) - if err != nil { - return errs.Wrap(err, "Could not get requirement") - } - if req != nil { - requirement.Operation = types.OperationUpdated - } - } - - r.Analytics.EventWithLabel( - anaConsts.CatPackageOp, fmt.Sprintf("%s-%s", requirement.Operation, requirement.langName), requirement.Name, - ) - } - - return nil -} - -func (r *RequirementOperation) resolveRequirements(requirements ...*Requirement) error { - for _, requirement := range requirements { - if err := r.resolveRequirement(requirement); err != nil { - return errs.Wrap(err, "Could not resolve requirement") - } - } - return nil -} - -func (r *RequirementOperation) resolveRequirement(requirement *Requirement) error { - var err error - requirement.Name, requirement.Version, err = model.ResolveRequirementNameAndVersion(requirement.Name, requirement.Version, requirement.BitWidth, *requirement.Namespace, r.Auth) - if err != nil { - return errs.Wrap(err, "Could not resolve requirement name and version") - } - - versionString := requirement.Version - if requirement.appendVersionWildcard { - versionString += ".x" - } - - requirement.versionRequirements, err = bpModel.VersionStringToRequirements(versionString) - if err != nil { - return errs.Wrap(err, "Could not process version string into requirements") - } - - return nil -} - -func (r *RequirementOperation) cveReport(artifactChangeset buildplan.ArtifactChangeset, requirements ...*Requirement) error { - if r.shouldSkipCVEs(requirements...) { - logging.Debug("Skipping CVE reporting") - return nil - } - - names := requirementNames(requirements...) - pg := output.StartSpinner(r.Output, locale.Tr("progress_cve_search", strings.Join(names, ", ")), constants.TerminalAnimationInterval) - - var ingredients []*request.Ingredient - for _, requirement := range requirements { - if requirement.Operation == types.OperationRemoved { - continue - } - - for _, artifact := range artifactChangeset.Added { - for _, ing := range artifact.Ingredients { - ingredients = append(ingredients, &request.Ingredient{ - Namespace: ing.Namespace, - Name: ing.Name, - Version: ing.Version, - }) - } - } - - for _, change := range artifactChangeset.Updated { - if !change.VersionsChanged() { - continue // For CVE reporting we only care about ingredient changes - } - - for _, ing := range change.To.Ingredients { - ingredients = append(ingredients, &request.Ingredient{ - Namespace: ing.Namespace, - Name: ing.Name, - Version: ing.Version, - }) - } - } - } - - ingredientVulnerabilities, err := model.FetchVulnerabilitiesForIngredients(r.Auth, ingredients) - if err != nil { - return errs.Wrap(err, "Failed to retrieve vulnerabilities") - } - - // No vulnerabilities, nothing further to do here - if len(ingredientVulnerabilities) == 0 { - logging.Debug("No vulnerabilities found for ingredients") - pg.Stop(locale.T("progress_safe")) - pg = nil - return nil - } - - pg.Stop(locale.T("progress_unsafe")) - pg = nil - - vulnerabilities := model.CombineVulnerabilities(ingredientVulnerabilities, names...) - r.summarizeCVEs(r.Output, vulnerabilities) - - if r.shouldPromptForSecurity(vulnerabilities) { - cont, err := r.promptForSecurity() - if err != nil { - return errs.Wrap(err, "Failed to prompt for security") - } - - if !cont { - if !r.Prompt.IsInteractive() { - return errs.AddTips( - locale.NewInputError("err_pkgop_security_prompt", "Operation aborted due to security prompt"), - locale.Tl("more_info_prompt", "To disable security prompting run: [ACTIONABLE]state config set security.prompt.enabled false[/RESET]"), - ) - } - return locale.NewInputError("err_pkgop_security_prompt", "Operation aborted due to security prompt") - } - } - - return nil -} - -func (r *RequirementOperation) shouldSkipCVEs(requirements ...*Requirement) bool { - if !r.Auth.Authenticated() { - return true - } - - for _, req := range requirements { - if req.Operation != types.OperationRemoved { - return false - } - } - - return true -} - -func (r *RequirementOperation) updateCommitID(commitID strfmt.UUID) error { - if err := localcommit.Set(r.Project.Dir(), commitID.String()); err != nil { - return locale.WrapError(err, "err_package_update_commit_id") - } - - if r.Config.GetBool(constants.OptinBuildscriptsConfig) { - bp := bpModel.NewBuildPlannerModel(r.Auth) - script, err := bp.GetBuildScript(commitID.String()) - if err != nil { - return errs.Wrap(err, "Could not get remote build expr and time") - } - - err = buildscript_runbit.Update(r.Project, script) - if err != nil { - return locale.WrapError(err, "err_update_build_script") - } - } - - return nil -} - -func (r *RequirementOperation) shouldPromptForSecurity(vulnerabilities model.VulnerableIngredientsByLevels) bool { - if !r.Config.GetBool(constants.SecurityPromptConfig) || vulnerabilities.Count == 0 { - return false - } - - promptLevel := r.Config.GetString(constants.SecurityPromptLevelConfig) - - logging.Debug("Prompt level: ", promptLevel) - switch promptLevel { - case vulnModel.SeverityCritical: - return vulnerabilities.Critical.Count > 0 - case vulnModel.SeverityHigh: - return vulnerabilities.Critical.Count > 0 || - vulnerabilities.High.Count > 0 - case vulnModel.SeverityMedium: - return vulnerabilities.Critical.Count > 0 || - vulnerabilities.High.Count > 0 || - vulnerabilities.Medium.Count > 0 - case vulnModel.SeverityLow: - return vulnerabilities.Critical.Count > 0 || - vulnerabilities.High.Count > 0 || - vulnerabilities.Medium.Count > 0 || - vulnerabilities.Low.Count > 0 - } - - return false -} - -func (r *RequirementOperation) summarizeCVEs(out output.Outputer, vulnerabilities model.VulnerableIngredientsByLevels) { - out.Print("") - - switch { - case vulnerabilities.CountPrimary == 0: - out.Print(" " + locale.Tr("warning_vulnerable_indirectonly", strconv.Itoa(vulnerabilities.Count))) - case vulnerabilities.CountPrimary == vulnerabilities.Count: - out.Print(" " + locale.Tr("warning_vulnerable_directonly", strconv.Itoa(vulnerabilities.Count))) - default: - out.Print(" " + locale.Tr("warning_vulnerable", strconv.Itoa(vulnerabilities.CountPrimary), strconv.Itoa(vulnerabilities.Count-vulnerabilities.CountPrimary))) - } - - printVulnerabilities := func(vulnerableIngredients model.VulnerableIngredientsByLevel, name, color string) { - if vulnerableIngredients.Count > 0 { - ings := []string{} - for _, vulns := range vulnerableIngredients.Ingredients { - prefix := "" - if vulnerabilities.Count > vulnerabilities.CountPrimary { - prefix = fmt.Sprintf("%s@%s: ", vulns.IngredientName, vulns.IngredientVersion) - } - ings = append(ings, fmt.Sprintf("%s[CYAN]%s[/RESET]", prefix, strings.Join(vulns.CVEIDs, ", "))) - } - out.Print(fmt.Sprintf(" • [%s]%d %s:[/RESET] %s", color, vulnerableIngredients.Count, name, strings.Join(ings, ", "))) - } - } - - printVulnerabilities(vulnerabilities.Critical, locale.Tl("cve_critical", "Critical"), "RED") - printVulnerabilities(vulnerabilities.High, locale.Tl("cve_high", "High"), "ORANGE") - printVulnerabilities(vulnerabilities.Medium, locale.Tl("cve_medium", "Medium"), "YELLOW") - printVulnerabilities(vulnerabilities.Low, locale.Tl("cve_low", "Low"), "MAGENTA") - - out.Print("") - out.Print(" " + locale.T("more_info_vulnerabilities")) - out.Print(" " + locale.T("disable_prompting_vulnerabilities")) -} - -func (r *RequirementOperation) promptForSecurity() (bool, error) { - confirm, err := r.Prompt.Confirm("", locale.Tr("prompt_continue_pkg_operation"), ptr.To(false)) - if err != nil { - return false, locale.WrapError(err, "err_pkgop_confirm", "Need a confirmation.") - } - - return confirm, nil -} - -func (r *RequirementOperation) outputResults(requirements ...*Requirement) { - for _, requirement := range requirements { - r.outputResult(requirement) - } -} - -func (r *RequirementOperation) outputResult(requirement *Requirement) { - // Print the result - message := locale.Tr(fmt.Sprintf("%s_version_%s", requirement.Namespace.Type(), requirement.Operation), requirement.Name, requirement.Version) - if requirement.Version == "" { - message = locale.Tr(fmt.Sprintf("%s_%s", requirement.Namespace.Type(), requirement.Operation), requirement.Name) - } - - r.Output.Print(output.Prepare( - message, - &struct { - Name string `json:"name"` - Version string `json:"version,omitempty"` - Type string `json:"type"` - Operation string `json:"operation"` - }{ - requirement.Name, - requirement.Version, - requirement.Namespace.Type().String(), - requirement.Operation.String(), - })) - - if requirement.originalRequirementName != requirement.Name && requirement.Operation != types.OperationRemoved { - r.Output.Notice(locale.Tl("package_version_differs", - "Note: the actual package name ({{.V0}}) is different from the requested package name ({{.V1}})", - requirement.Name, requirement.originalRequirementName)) - } -} - -func supportedLanguageByName(supported []medmodel.SupportedLanguage, langName string) medmodel.SupportedLanguage { - return funk.Find(supported, func(l medmodel.SupportedLanguage) bool { return l.Name == langName }).(medmodel.SupportedLanguage) -} - -func resolvePkgAndNamespace(prompt prompt.Prompter, packageName string, nsType model.NamespaceType, supported []medmodel.SupportedLanguage, ts *time.Time, auth *authentication.Auth) (string, model.Namespace, *medmodel.SupportedLanguage, error) { - ns := model.NewBlankNamespace() - - // Find ingredients that match the input query - ingredients, err := model.SearchIngredientsStrict("", packageName, false, false, ts, auth) - if err != nil { - return "", ns, nil, locale.WrapError(err, "err_pkgop_search_err", "Failed to check for ingredients.") - } - - ingredients, err = model.FilterSupportedIngredients(supported, ingredients) - if err != nil { - return "", ns, nil, errs.Wrap(err, "Failed to filter out unsupported packages") - } - - choices := []string{} - values := map[string][]string{} - for _, i := range ingredients { - language := model.LanguageFromNamespace(*i.Ingredient.PrimaryNamespace) - - // Generate ingredient choices to present to the user - name := fmt.Sprintf("%s (%s)", *i.Ingredient.Name, language) - choices = append(choices, name) - values[name] = []string{*i.Ingredient.Name, language} - } - - if len(choices) == 0 { - return "", ns, nil, locale.WrapExternalError(err, "package_ingredient_alternatives_nolang", "", packageName) - } - - // If we only have one ingredient match we're done; return it. - if len(choices) == 1 { - language := values[choices[0]][1] - supportedLang := supportedLanguageByName(supported, language) - return values[choices[0]][0], model.NewNamespacePkgOrBundle(language, nsType), &supportedLang, nil - } - - // Prompt the user with the ingredient choices - choice, err := prompt.Select( - locale.Tl("prompt_pkgop_ingredient", "Multiple Matches"), - locale.Tl("prompt_pkgop_ingredient_msg", "Your query has multiple matches, which one would you like to use?"), - choices, &choices[0], - ) - if err != nil { - return "", ns, nil, locale.WrapError(err, "err_pkgop_select", "Need a selection.") - } - - // Return the user selected ingredient - language := values[choice][1] - supportedLang := supportedLanguageByName(supported, language) - return values[choice][0], model.NewNamespacePkgOrBundle(language, nsType), &supportedLang, nil -} - -func getSuggestions(ns model.Namespace, name string, auth *authentication.Auth) ([]string, error) { - results, err := model.SearchIngredients(ns.String(), name, false, nil, auth) - if err != nil { - return []string{}, locale.WrapError(err, "package_ingredient_err_search", "Failed to resolve ingredient named: {{.V0}}", name) - } - - maxResults := 5 - if len(results) > maxResults { - results = results[:maxResults] - } - - suggestions := make([]string, 0, maxResults+1) - for _, result := range results { - suggestions = append(suggestions, fmt.Sprintf(" - %s", *result.Ingredient.Name)) - } - - return suggestions, nil -} - -func commitMessage(requirements ...*Requirement) string { - switch len(requirements) { - case 0: - return "" - case 1: - return requirementCommitMessage(requirements[0]) - default: - return commitMessageMultiple(requirements...) - } -} - -func requirementCommitMessage(req *Requirement) string { - switch req.Namespace.Type() { - case model.NamespaceLanguage: - return languageCommitMessage(req.Operation, req.Name, req.Version) - case model.NamespacePlatform: - return platformCommitMessage(req.Operation, req.Name, req.Version, req.BitWidth) - case model.NamespacePackage, model.NamespaceBundle: - return packageCommitMessage(req.Operation, req.Name, req.Version) - } - return "" -} - -func languageCommitMessage(op types.Operation, name, version string) string { - var msgL10nKey string - switch op { - case types.OperationAdded: - msgL10nKey = "commit_message_added_language" - case types.OperationUpdated: - msgL10nKey = "commit_message_updated_language" - case types.OperationRemoved: - msgL10nKey = "commit_message_removed_language" - } - - return locale.Tr(msgL10nKey, name, version) -} - -func platformCommitMessage(op types.Operation, name, version string, word int) string { - var msgL10nKey string - switch op { - case types.OperationAdded: - msgL10nKey = "commit_message_added_platform" - case types.OperationUpdated: - msgL10nKey = "commit_message_updated_platform" - case types.OperationRemoved: - msgL10nKey = "commit_message_removed_platform" - } - - return locale.Tr(msgL10nKey, name, strconv.Itoa(word), version) -} - -func packageCommitMessage(op types.Operation, name, version string) string { - var msgL10nKey string - switch op { - case types.OperationAdded: - msgL10nKey = "commit_message_added_package" - case types.OperationUpdated: - msgL10nKey = "commit_message_updated_package" - case types.OperationRemoved: - msgL10nKey = "commit_message_removed_package" - } - - if version == "" { - version = locale.Tl("package_version_auto", "auto") - } - return locale.Tr(msgL10nKey, name, version) -} - -func commitMessageMultiple(requirements ...*Requirement) string { - var commitDetails []string - for _, req := range requirements { - commitDetails = append(commitDetails, requirementCommitMessage(req)) - } - - return locale.Tl("commit_message_multiple", "Committing changes to multiple requirements: {{.V0}}", strings.Join(commitDetails, ", ")) -} - -func requirementNames(requirements ...*Requirement) []string { - var names []string - for _, requirement := range requirements { - names = append(names, requirement.Name) - } - return names -} diff --git a/internal/runbits/runbits.go b/internal/runbits/runbits.go deleted file mode 100644 index 69facb6a07..0000000000 --- a/internal/runbits/runbits.go +++ /dev/null @@ -1,15 +0,0 @@ -// Package runbits comprises logic that is shared between controllers, ie., code that prints -package runbits - -import ( - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/buildlog" -) - -func IsBuildError(err error) bool { - return errs.Matches(err, &setup.BuildError{}) || - errs.Matches(err, &buildlog.BuildError{}) || - errs.Matches(err, &response.BuildPlannerError{}) -} diff --git a/internal/runbits/runtime/progress/decor.go b/internal/runbits/runtime/progress/decor.go index 151f1dcacc..9c7a3e75fe 100644 --- a/internal/runbits/runtime/progress/decor.go +++ b/internal/runbits/runtime/progress/decor.go @@ -4,15 +4,15 @@ import ( "fmt" "time" + "github.com/go-openapi/strfmt" + "github.com/vbauerster/mpb/v7" + "github.com/vbauerster/mpb/v7/decor" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/termutils" - "github.com/go-openapi/strfmt" - "github.com/vbauerster/mpb/v7" - "github.com/vbauerster/mpb/v7/decor" ) const progressBarWidth = 40 @@ -45,21 +45,30 @@ func (p *ProgressDigester) trimName(name string) string { // addTotalBar adds a bar counting a number of sub-events adding up to total func (p *ProgressDigester) addTotalBar(name string, total int64, options ...mpb.BarOption) *bar { - logging.Debug("Adding total bar: %s", name) return p.addBar(name, total, false, append(options, mpb.BarFillerClearOnComplete())...) } // addArtifactBar adds a bar counting the progress in a specific artifact setup step func (p *ProgressDigester) addArtifactBar(id strfmt.UUID, step step, total int64, countsBytes bool) error { name := locale.T("artifact_unknown_name") - if aname, ok := p.artifacts[id]; ok { - name = aname + switch step { + case StepBuild: + if a, ok := p.buildsExpected[id]; ok { + name = a.NameAndVersion() + } + case StepDownload, StepUnpack: + if a, ok := p.downloadsExpected[id]; ok { + name = a.NameAndVersion() + } + case StepInstall: + if a, ok := p.installsExpected[id]; ok { + name = a.NameAndVersion() + } } - logging.Debug("Adding %s artifact bar: %s", step.verb, name) aStep := artifactStep{id, step} if _, ok := p.artifactBars[aStep.ID()]; ok { - return errs.New("Artifact bar already exists") + return errs.New("Artifact bar %s for step %s already exists", id, step.name) } p.artifactBars[aStep.ID()] = p.addBar(fmt.Sprintf(" - %s %s", step.verb, name), total, countsBytes, mpb.BarRemoveOnComplete(), mpb.BarPriority(step.priority+len(p.artifactBars))) return nil @@ -73,25 +82,11 @@ func (p *ProgressDigester) updateArtifactBar(id strfmt.UUID, step step, inc int) } p.artifactBars[aStep.ID()].IncrBy(inc) - name := locale.T("artifact_unknown_name") - if aname, ok := p.artifacts[id]; ok { - name = aname - } - if p.artifactBars[aStep.ID()].Current() >= p.artifactBars[aStep.ID()].total { - logging.Debug("%s Artifact bar reached total: %s", step.verb, name) - } - return nil } // dropArtifactBar removes an artifact bar from the progress display func (p *ProgressDigester) dropArtifactBar(id strfmt.UUID, step step) error { - name := locale.T("artifact_unknown_name") - if aname, ok := p.artifacts[id]; ok { - name = aname - } - logging.Debug("Dropping %s artifact bar: %s", step.verb, name) - aStep := artifactStep{id, step} if _, ok := p.artifactBars[aStep.ID()]; !ok { return errs.New("Artifact bar doesn't exists") @@ -124,6 +119,25 @@ func (p *ProgressDigester) addBar(name string, total int64, countsBytes bool, op return &bar{p.mainProgress.AddBar(total, options...), time.Now(), total} } +func (p *ProgressDigester) artifactName(id strfmt.UUID, step step) string { + name := locale.T("artifact_unknown_name") + switch step { + case StepBuild: + if a, ok := p.buildsExpected[id]; ok { + name = a.NameAndVersion() + } + case StepDownload, StepUnpack: + if a, ok := p.downloadsExpected[id]; ok { + name = a.NameAndVersion() + } + case StepInstall: + if a, ok := p.installsExpected[id]; ok { + name = a.NameAndVersion() + } + } + return name +} + // MaxNameWidth returns the maximum width to be used for a name in a progress bar func MaxNameWidth() int { tw := termutils.GetWidth() diff --git a/internal/runbits/runtime/progress/dotprogress.go b/internal/runbits/runtime/progress/dotprogress.go index d676327f88..4d4efa5566 100644 --- a/internal/runbits/runtime/progress/dotprogress.go +++ b/internal/runbits/runtime/progress/dotprogress.go @@ -6,7 +6,7 @@ import ( "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/events" + "github.com/ActiveState/cli/pkg/runtime/events" ) type DotProgressDigester struct { @@ -15,15 +15,15 @@ type DotProgressDigester struct { success bool } -// NewDotProgressIndicator prints dots at an interval while a runtime is being setup (during solve, +// newDotProgressIndicator prints dots at an interval while a runtime is being setup (during solve, // download, and install steps). // The primary goal is to indicate to various CI systems (or during non-interactive mode) that // progress is being made. -func NewDotProgressIndicator(out output.Outputer) *DotProgressDigester { +func newDotProgressIndicator(out output.Outputer) *DotProgressDigester { return &DotProgressDigester{out: out} } -func (d *DotProgressDigester) Handle(event events.Eventer) error { +func (d *DotProgressDigester) Handle(event events.Event) error { switch event.(type) { case events.Start: d.spinner = output.StartSpinner(d.out, locale.T("setup_runtime"), time.Second) diff --git a/internal/runbits/runtime/progress/progress.go b/internal/runbits/runtime/progress/progress.go index 25eb353faf..a071d5774e 100644 --- a/internal/runbits/runtime/progress/progress.go +++ b/internal/runbits/runtime/progress/progress.go @@ -3,21 +3,23 @@ package progress import ( "fmt" "io" + "os" "strings" "sync" "time" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/internal/sliceutils" "github.com/go-openapi/strfmt" "github.com/vbauerster/mpb/v7" "golang.org/x/net/context" + "github.com/ActiveState/cli/internal/multilog" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/runtime/events" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/events" ) type step struct { @@ -33,7 +35,8 @@ func (s step) String() string { var ( StepBuild = step{"build", locale.T("building"), 10000} // the priority is high because the artifact progress bars need to fit in between the steps StepDownload = step{"download", locale.T("downloading"), 20000} - StepInstall = step{"install", locale.T("installing"), 30000} + StepUnpack = step{"unpack", locale.T("unpacking"), 30000} + StepInstall = step{"install", locale.T("installing"), 40000} ) type artifactStepID string @@ -55,21 +58,20 @@ type ProgressDigester struct { mainProgress *mpb.Progress buildBar *bar downloadBar *bar + unpackBar *bar installBar *bar solveSpinner *output.Spinner artifactBars map[artifactStepID]*bar - // Artifact name lookup map - artifacts map[strfmt.UUID]string - // Recipe that we're performing progress for recipeID strfmt.UUID // Track the totals required as the bars for these are only initialized for the first artifact received, at which // time we won't have the totals unless we previously recorded them. - buildsExpected map[strfmt.UUID]struct{} - downloadsExpected map[strfmt.UUID]struct{} - installsExpected map[strfmt.UUID]struct{} + buildsExpected buildplan.ArtifactIDMap + downloadsExpected buildplan.ArtifactIDMap + unpacksExpected buildplan.ArtifactIDMap + installsExpected buildplan.ArtifactIDMap // Debug properties used to reduce the number of log entries generated dbgEventLog []string @@ -88,7 +90,18 @@ type ProgressDigester struct { success bool } -func NewProgressIndicator(w io.Writer, out output.Outputer) *ProgressDigester { +func NewRuntimeProgressIndicator(out output.Outputer) events.Handler { + var w io.Writer = os.Stdout + if out.Type() != output.PlainFormatName { + w = nil + } + if out.Config().Interactive { + return newProgressIndicator(w, out) + } + return newDotProgressIndicator(out) +} + +func newProgressIndicator(w io.Writer, out output.Outputer) *ProgressDigester { ctx, cancel := context.WithCancel(context.Background()) return &ProgressDigester{ mainProgress: mpb.NewWithContext( @@ -98,7 +111,6 @@ func NewProgressIndicator(w io.Writer, out output.Outputer) *ProgressDigester { mpb.WithRefreshRate(refreshRate), ), - artifacts: map[strfmt.UUID]string{}, artifactBars: map[artifactStepID]*bar{}, cancelMpb: cancel, @@ -110,7 +122,7 @@ func NewProgressIndicator(w io.Writer, out output.Outputer) *ProgressDigester { } } -func (p *ProgressDigester) Handle(ev events.Eventer) error { +func (p *ProgressDigester) Handle(ev events.Event) error { p.dbgEventLog = append(p.dbgEventLog, fmt.Sprintf("%T", ev)) p.mutex.Lock() @@ -125,8 +137,6 @@ func (p *ProgressDigester) Handle(ev events.Eventer) error { switch v := ev.(type) { case events.Start: - logging.Debug("Initialize Event: %#v", v) - // Ensure Start event is first.. because otherwise the prints below will cause output to be malformed. if p.buildBar != nil || p.downloadBar != nil || p.installBar != nil || p.solveSpinner != nil { return errs.New("Received Start event after bars were already initialized, event log: %v", p.dbgEventLog) @@ -140,11 +150,11 @@ func (p *ProgressDigester) Handle(ev events.Eventer) error { } p.recipeID = v.RecipeID - p.artifacts = v.Artifacts - p.buildsExpected = sliceutils.ToLookupMap(v.ArtifactsToBuild) - p.downloadsExpected = sliceutils.ToLookupMap(v.ArtifactsToDownload) - p.installsExpected = sliceutils.ToLookupMap(v.ArtifactsToInstall) + p.buildsExpected = v.ArtifactsToBuild + p.downloadsExpected = v.ArtifactsToDownload + p.unpacksExpected = v.ArtifactsToUnpack + p.installsExpected = v.ArtifactsToInstall if len(v.ArtifactsToBuild)+len(v.ArtifactsToDownload)+len(v.ArtifactsToInstall) == 0 { p.out.Notice(locale.T("progress_nothing_to_do")) @@ -155,29 +165,6 @@ func (p *ProgressDigester) Handle(ev events.Eventer) error { case events.Success: p.success = true - case events.SolveStart: - p.out.Notice(locale.T("setup_runtime")) - p.solveSpinner = output.StartSpinner(p.out, locale.T("progress_solve"), refreshRate) - - case events.SolveError: - if p.solveSpinner == nil { - return errs.New("SolveError called before solveBar was initialized") - } - p.solveSpinner.Stop(locale.T("progress_fail")) - p.solveSpinner = nil - - case events.SolveSuccess: - if p.solveSpinner == nil { - return errs.New("SolveSuccess called before solveBar was initialized") - } - p.solveSpinner.Stop(locale.T("progress_success")) - p.solveSpinner = nil - - case events.BuildSkipped: - if p.buildBar != nil { - return errs.New("BuildSkipped called, but buildBar was initialized.. this should not happen as they should be mutually exclusive") - } - case events.BuildStarted: if p.buildBar != nil { return errs.New("BuildStarted called after buildbar was already initialized") @@ -225,7 +212,6 @@ func (p *ProgressDigester) Handle(ev events.Eventer) error { if p.buildBar.Current() == p.buildBar.total { return errs.New("Build bar is already complete, this should not happen") } - delete(p.buildsExpected, v.ArtifactID) p.buildBar.Increment() case events.ArtifactDownloadStarted: @@ -243,11 +229,6 @@ func (p *ProgressDigester) Handle(ev events.Eventer) error { return errs.Wrap(err, "Failed to add or update artifact bar") } - case events.ArtifactDownloadSkipped: - initDownloadBar() - delete(p.downloadsExpected, v.ArtifactID) - p.downloadBar.Increment() - case events.ArtifactDownloadSuccess: if p.downloadBar == nil { return errs.New("ArtifactDownloadSuccess called before downloadBar was initialized") @@ -261,26 +242,49 @@ func (p *ProgressDigester) Handle(ev events.Eventer) error { if p.downloadBar.Current() == p.downloadBar.total { return errs.New("Download bar is already complete, this should not happen") } - delete(p.downloadsExpected, v.ArtifactID) p.downloadBar.Increment() - case events.ArtifactInstallStarted: - if p.installBar == nil { - p.installBar = p.addTotalBar(locale.Tl("progress_building", "Installing"), int64(len(p.installsExpected)), mpb.BarPriority(StepInstall.priority)) + case events.ArtifactUnpackStarted: + if p.unpackBar == nil { + p.unpackBar = p.addTotalBar(locale.Tl("progress_unpacking", "Unpacking"), int64(len(p.unpacksExpected)), mpb.BarPriority(StepUnpack.priority)) } - if _, ok := p.installsExpected[v.ArtifactID]; !ok { - return errs.New("ArtifactInstallStarted called for an artifact that was not expected: %s", v.ArtifactID.String()) + if _, ok := p.unpacksExpected[v.ArtifactID]; !ok { + return errs.New("ArtifactUnpackStarted called for an artifact that was not expected: %s", v.ArtifactID.String()) } - if err := p.addArtifactBar(v.ArtifactID, StepInstall, int64(v.TotalSize), true); err != nil { - return errs.Wrap(err, "Failed to add or update artifact bar") + if err := p.addArtifactBar(v.ArtifactID, StepUnpack, int64(v.TotalSize), true); err != nil { + return errs.Wrap(err, "Failed to add or update artifact unpack bar") + } + + case events.ArtifactUnpackProgress: + if _, ok := p.unpacksExpected[v.ArtifactID]; !ok { + return errs.New("ArtifactUnpackSuccess called for an artifact that was not expected: %s", v.ArtifactID.String()) + } + if err := p.updateArtifactBar(v.ArtifactID, StepUnpack, v.IncrementBySize); err != nil { + return errs.Wrap(err, "Failed to add or update artifact unpack bar") + } + + case events.ArtifactUnpackSuccess: + if p.unpackBar == nil { + return errs.New("ArtifactUnpackSuccess called before unpackBar was initialized") + } + if _, ok := p.unpacksExpected[v.ArtifactID]; !ok { + return errs.New("ArtifactUnpackSuccess called for an artifact that was not expected: %s", v.ArtifactID.String()) + } + if err := p.dropArtifactBar(v.ArtifactID, StepUnpack); err != nil { + return errs.Wrap(err, "Failed to drop unpack bar") } + if p.unpackBar.Current() == p.unpackBar.total { + return errs.New("Unpack bar is already complete, this should not happen") + } + p.unpackBar.Increment() - case events.ArtifactInstallSkipped: + case events.ArtifactInstallStarted: if p.installBar == nil { - return errs.New("ArtifactInstallSkipped called before installBar was initialized, artifact ID: %s", v.ArtifactID.String()) + p.installBar = p.addTotalBar(locale.Tl("progress_installing", "Installing"), int64(len(p.installsExpected)), mpb.BarPriority(StepInstall.priority)) + } + if _, ok := p.installsExpected[v.ArtifactID]; !ok { + return errs.New("ArtifactUnpackStarted called for an artifact that was not expected: %s", v.ArtifactID.String()) } - delete(p.installsExpected, v.ArtifactID) - p.installBar.Increment() case events.ArtifactInstallSuccess: if p.installBar == nil { @@ -289,20 +293,11 @@ func (p *ProgressDigester) Handle(ev events.Eventer) error { if _, ok := p.installsExpected[v.ArtifactID]; !ok { return errs.New("ArtifactInstallSuccess called for an artifact that was not expected: %s", v.ArtifactID.String()) } - if err := p.dropArtifactBar(v.ArtifactID, StepInstall); err != nil { - return errs.Wrap(err, "Failed to drop install bar") - } if p.installBar.Current() == p.installBar.total { return errs.New("Install bar is already complete, this should not happen") } - delete(p.installsExpected, v.ArtifactID) p.installBar.Increment() - case events.ArtifactInstallProgress: - if err := p.updateArtifactBar(v.ArtifactID, StepInstall, v.IncrementBySize); err != nil { - return errs.Wrap(err, "Failed to add or update artifact bar") - } - } return nil @@ -349,18 +344,7 @@ func (p *ProgressDigester) Close() error { }())) } - multilog.Error(` -Timed out waiting for progress bars to close. Recipe: %s -Progress bars status: -%s -Still expecting: - - Builds: %v - - Downloads: %v - - Installs: %v`, - p.recipeID.String(), - strings.Join(debugMsg, "\n"), - p.buildsExpected, p.downloadsExpected, p.installsExpected, - ) + multilog.Error(`Timed out waiting for progress bars to close. %s`, strings.Join(debugMsg, "\n")) /* https://activestatef.atlassian.net/browse/DX-1831 if pending > 0 { diff --git a/internal/runbits/runtime/rationalize.go b/internal/runbits/runtime/rationalize.go index 84043b2cbb..3feac4ac8d 100644 --- a/internal/runbits/runtime/rationalize.go +++ b/internal/runbits/runtime/rationalize.go @@ -1,81 +1,45 @@ -package runtime +package runtime_runbit import ( "errors" "fmt" "strings" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/graph" "github.com/ActiveState/cli/internal/locale" + buildscript_runbit "github.com/ActiveState/cli/internal/runbits/buildscript" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/pkg/platform/api" bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" - "github.com/ActiveState/cli/pkg/platform/authentication" + auth "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/buildlog" "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/cli/pkg/runtime" ) -func rationalizeError(auth *authentication.Auth, proj *project.Project, rerr *error) { - if *rerr == nil { - return - } - var noMatchingPlatformErr *model.ErrNoMatchingPlatform - var artifactDownloadErr *setup.ArtifactDownloadError - var buildPlannerErr *bpResp.BuildPlannerError - var artifactCachedBuildErr *setup.ArtifactCachedBuildFailed - var artifactBuildErr *buildlog.ArtifactBuildError - - switch { - case errors.Is(*rerr, rationalize.ErrHeadless): - *rerr = errs.WrapUserFacing(*rerr, - locale.Tr("err_headless", proj.URL()), - errs.SetInput()) +var ErrBuildscriptNotExist = buildscript_runbit.ErrBuildscriptNotExist - // Could not find a platform that matches on the given branch, so suggest alternate branches if ones exist - case errors.As(*rerr, &noMatchingPlatformErr): - branches, err := model.BranchNamesForProjectFiltered(proj.Owner(), proj.Name(), proj.BranchName()) - if err == nil && len(branches) > 0 { - // Suggest alternate branches - *rerr = errs.NewUserFacing(locale.Tr( - "err_alternate_branches", - noMatchingPlatformErr.HostPlatform, noMatchingPlatformErr.HostArch, - proj.BranchName(), strings.Join(branches, "\n - "))) - } else { - libcErr := noMatchingPlatformErr.LibcVersion != "" - *rerr = errs.NewUserFacing( - locale.Tr("err_no_platform_data_remains", noMatchingPlatformErr.HostPlatform, noMatchingPlatformErr.HostArch), - errs.SetIf(libcErr, errs.SetInput()), - errs.SetIf(libcErr, errs.SetTips(locale.Tr("err_user_libc_solution", api.GetPlatformURL(fmt.Sprintf("%s/%s", proj.NamespaceString(), "customize")).String()))), - ) - } +var ErrBuildScriptNeedsCommit = errors.New("buildscript is dirty, need to run state commit") - // If there was an artifact download error, say so, rather than reporting a generic "could not - // update runtime" error. - case errors.As(*rerr, &artifactDownloadErr): - *rerr = errs.WrapUserFacing(*rerr, - locale.Tl("err_runtime_setup_download", "Your runtime could not be installed or updated because one or more artifacts failed to download."), - errs.SetInput(), - errs.SetTips(locale.Tr("err_user_network_solution", constants.ForumsURL)), - ) +type RuntimeInUseError struct { + Processes []*graph.ProcessInfo +} - // We communicate buildplanner errors verbatim as the intend is that these are curated by the buildplanner - case errors.As(*rerr, &buildPlannerErr): - *rerr = errs.WrapUserFacing(*rerr, - buildPlannerErr.LocalizedError(), - errs.SetIf(buildPlannerErr.InputError(), errs.SetInput())) +func (err RuntimeInUseError) Error() string { + return "runtime is in use" +} - // User has modified the buildscript and needs to run `state commit` - case errors.Is(*rerr, runtime.NeedsCommitError): - *rerr = errs.WrapUserFacing(*rerr, locale.T("notice_commit_build_script"), errs.SetInput()) +func rationalizeUpdateError(prime primeable, rerr *error) { + if *rerr == nil { + return + } - // Buildscript is missing and needs to be recreated - case errors.Is(*rerr, runtime.NeedsBuildscriptResetError): - *rerr = errs.WrapUserFacing(*rerr, locale.T("notice_needs_buildscript_reset"), errs.SetInput()) + var artifactCachedBuildErr *runtime.ArtifactCachedBuildFailed + var artifactBuildErr *runtime.ArtifactBuildError + var runtimeInUseErr *RuntimeInUseError + switch { // Artifact cached build errors case errors.As(*rerr, &artifactCachedBuildErr): errMsg := locale.Tr("err_build_artifact_failed_msg", artifactCachedBuildErr.Artifact.Name()) @@ -96,6 +60,73 @@ func rationalizeError(auth *authentication.Auth, proj *project.Project, rerr *er errs.SetInput(), ) + // Runtime in use + case errors.As(*rerr, &runtimeInUseErr): + list := []string{} + for _, proc := range runtimeInUseErr.Processes { + list = append(list, fmt.Sprintf(" - %s (process: %d)", proc.Exe, proc.Pid)) + } + *rerr = errs.WrapUserFacing(*rerr, + locale.Tr("runtime_setup_in_use_err", strings.Join(list, "\n")), + errs.SetInput(), + ) + + // Headless + case errors.Is(*rerr, rationalize.ErrHeadless): + *rerr = errs.WrapUserFacing(*rerr, + locale.Tr("err_headless", prime.Project().URL()), + errs.SetInput()) + + default: + RationalizeSolveError(prime.Project(), prime.Auth(), rerr) + + } +} + +func RationalizeSolveError(proj *project.Project, auth *auth.Auth, rerr *error) { + if *rerr == nil { + return + } + + var noMatchingPlatformErr *model.ErrNoMatchingPlatform + var buildPlannerErr *bpResp.BuildPlannerError + + switch { + // User has modified the buildscript and needs to run `state commit` + case errors.Is(*rerr, ErrBuildScriptNeedsCommit): + *rerr = errs.WrapUserFacing(*rerr, locale.T("notice_commit_build_script"), errs.SetInput()) + + // Buildscript is missing and needs to be recreated + case errors.Is(*rerr, ErrBuildscriptNotExist): + *rerr = errs.WrapUserFacing(*rerr, locale.T("notice_needs_buildscript_reset"), errs.SetInput()) + + // Could not find a platform that matches on the given branch, so suggest alternate branches if ones exist + case errors.As(*rerr, &noMatchingPlatformErr): + if proj != nil { + branches, err := model.BranchNamesForProjectFiltered(proj.Owner(), proj.Name(), proj.BranchName()) + if err == nil && len(branches) > 0 { + // Suggest alternate branches + *rerr = errs.NewUserFacing(locale.Tr( + "err_alternate_branches", + noMatchingPlatformErr.HostPlatform, noMatchingPlatformErr.HostArch, + proj.BranchName(), strings.Join(branches, "\n - ")), + errs.SetInput()) + return + } + } + libcErr := noMatchingPlatformErr.LibcVersion != "" + *rerr = errs.NewUserFacing( + locale.Tr("err_no_platform_data_remains", noMatchingPlatformErr.HostPlatform, noMatchingPlatformErr.HostArch), + errs.SetIf(libcErr, errs.SetInput()), + errs.SetIf(libcErr, errs.SetTips(locale.Tr("err_user_libc_solution", api.GetPlatformURL(fmt.Sprintf("%s/%s", proj.NamespaceString(), "customize")).String()))), + ) + + // We communicate buildplanner errors verbatim as the intend is that these are curated by the buildplanner + case errors.As(*rerr, &buildPlannerErr): + *rerr = errs.WrapUserFacing(*rerr, + buildPlannerErr.LocaleError(), + errs.SetIf(buildPlannerErr.InputError(), errs.SetInput())) + // If updating failed due to unidentified errors, and the user is not authenticated, add a tip suggesting that they authenticate as // this may be a private project. // Note since we cannot assert the actual error type we do not wrap this as user-facing, as we do not know what we're @@ -104,7 +135,7 @@ func rationalizeError(auth *authentication.Auth, proj *project.Project, rerr *er // Add authentication tip if we could not assert the error type // This must only happen after all error assertions have failed, because if we can assert the error we can give // an appropriate message, rather than a vague tip that suggests MAYBE this is a private project. - if !auth.Authenticated() { + if auth != nil && !auth.Authenticated() { *rerr = errs.AddTips(*rerr, locale.T("tip_private_project_auth"), ) diff --git a/internal/runbits/runtime/refresh.go b/internal/runbits/runtime/refresh.go deleted file mode 100644 index 4bcc1528d5..0000000000 --- a/internal/runbits/runtime/refresh.go +++ /dev/null @@ -1,210 +0,0 @@ -package runtime - -import ( - "github.com/ActiveState/cli/internal/analytics" - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" - configMediator "github.com/ActiveState/cli/internal/mediators/config" - "github.com/ActiveState/cli/internal/output" - "github.com/ActiveState/cli/internal/rtutils" - "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/pkg/platform/authentication" - "github.com/ActiveState/cli/pkg/platform/model" - bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/platform/runtime" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/events" - "github.com/ActiveState/cli/pkg/platform/runtime/target" - "github.com/ActiveState/cli/pkg/project" - "github.com/go-openapi/strfmt" - "github.com/imacks/bitflags-go" -) - -func init() { - configMediator.RegisterOption(constants.AsyncRuntimeConfig, configMediator.Bool, false) -} - -type Opts int - -const ( - OptNone Opts = 1 << iota - OptNoIndent // Don't indent progress output - OptMinimalUI // Only print progress output, don't decorate the UI in any other way - OptNoUI // Don't print progress output, don't decorate the UI in any other way - OptOrderChanged // Indicate that the order has changed, and the runtime should be refreshed regardless of internal dirty checking mechanics -) - -type Configurable interface { - GetString(key string) string - GetBool(key string) bool -} - -var overrideAsyncTriggers = map[target.Trigger]bool{ - target.TriggerRefresh: true, - target.TriggerExec: true, - target.TriggerActivate: true, - target.TriggerShell: true, - target.TriggerScript: true, - target.TriggerDeploy: true, - target.TriggerUse: true, - target.TriggerExport: true, -} - -// SolveAndUpdate should be called after runtime mutations. -func SolveAndUpdate( - auth *authentication.Auth, - out output.Outputer, - an analytics.Dispatcher, - proj *project.Project, - customCommitID *strfmt.UUID, - trigger target.Trigger, - svcm *model.SvcModel, - cfg Configurable, - opts Opts, -) (_ *runtime.Runtime, rerr error) { - defer rationalizeError(auth, proj, &rerr) - - if proj == nil { - return nil, rationalize.ErrNoProject - } - - if proj.IsHeadless() { - return nil, rationalize.ErrHeadless - } - - if cfg.GetBool(constants.AsyncRuntimeConfig) && !overrideAsyncTriggers[trigger] { - logging.Debug("Skipping runtime solve due to async runtime") - return nil, nil - } - - target := target.NewProjectTarget(proj, customCommitID, trigger) - rt, err := runtime.New(target, an, svcm, auth, cfg, out) - if err != nil { - return nil, locale.WrapError(err, "err_packages_update_runtime_init") - } - - if !bitflags.Has(opts, OptOrderChanged) && !bitflags.Has(opts, OptMinimalUI) && !rt.NeedsUpdate() { - out.Notice(locale.T("pkg_already_uptodate")) - return rt, nil - } - - if rt.NeedsUpdate() && !bitflags.Has(opts, OptMinimalUI) { - if !rt.HasCache() { - out.Notice(output.Title(locale.T("install_runtime"))) - out.Notice(locale.T("install_runtime_info")) - } else { - out.Notice(output.Title(locale.T("update_runtime"))) - out.Notice(locale.T("update_runtime_info")) - } - } - - if rt.NeedsUpdate() { - pg := NewRuntimeProgressIndicator(out) - defer rtutils.Closer(pg.Close, &rerr) - - err := rt.SolveAndUpdate(pg) - if err != nil { - return nil, locale.WrapError(err, "err_packages_update_runtime_install") - } - } - - return rt, nil -} - -func Solve( - auth *authentication.Auth, - out output.Outputer, - an analytics.Dispatcher, - proj *project.Project, - customCommitID *strfmt.UUID, - trigger target.Trigger, - svcm *model.SvcModel, - cfg Configurable, - opts Opts, -) (_ *runtime.Runtime, _ *bpModel.Commit, rerr error) { - defer rationalizeError(auth, proj, &rerr) - - if proj == nil { - return nil, nil, rationalize.ErrNoProject - } - - if proj.IsHeadless() { - return nil, nil, rationalize.ErrHeadless - } - - var spinner *output.Spinner - if !bitflags.Has(opts, OptMinimalUI) { - localeName := "progress_solve_preruntime" - if bitflags.Has(opts, OptNoIndent) { - localeName = "progress_solve" - } - spinner = output.StartSpinner(out, locale.T(localeName), constants.TerminalAnimationInterval) - } - - defer func() { - if spinner == nil { - return - } - if rerr != nil { - spinner.Stop(locale.T("progress_fail")) - } else { - spinner.Stop(locale.T("progress_success")) - } - }() - - rtTarget := target.NewProjectTarget(proj, customCommitID, trigger) - rt, err := runtime.New(rtTarget, an, svcm, auth, cfg, out) - if err != nil { - return nil, nil, locale.WrapError(err, "err_packages_update_runtime_init") - } - - setup := rt.Setup(&events.VoidHandler{}) - commit, err := setup.Solve() - if err != nil { - return nil, nil, errs.Wrap(err, "Solve failed") - } - - return rt, commit, nil -} - -// UpdateByReference will update the given runtime if necessary. This is functionally the same as SolveAndUpdateByReference -// except that it does not do its own solve. -func UpdateByReference( - rt *runtime.Runtime, - commit *bpModel.Commit, - auth *authentication.Auth, - proj *project.Project, - out output.Outputer, - cfg Configurable, - opts Opts, -) (rerr error) { - defer rationalizeError(auth, proj, &rerr) - - if cfg.GetBool(constants.AsyncRuntimeConfig) { - logging.Debug("Skipping runtime update due to async runtime") - return nil - } - - if rt.NeedsUpdate() { - if !bitflags.Has(opts, OptMinimalUI) { - if !rt.HasCache() { - out.Notice(output.Title(locale.T("install_runtime"))) - out.Notice(locale.T("install_runtime_info")) - } else { - out.Notice(output.Title(locale.T("update_runtime"))) - out.Notice(locale.T("update_runtime_info")) - } - } - - pg := NewRuntimeProgressIndicator(out) - defer rtutils.Closer(pg.Close, &rerr) - - err := rt.Setup(pg).Update(commit) - if err != nil { - return locale.WrapError(err, "err_packages_update_runtime_install") - } - } - - return nil -} diff --git a/internal/runbits/runtime/runtime.go b/internal/runbits/runtime/runtime.go new file mode 100644 index 0000000000..f4b72ba59b --- /dev/null +++ b/internal/runbits/runtime/runtime.go @@ -0,0 +1,343 @@ +package runtime_runbit + +import ( + "os" + + anaConsts "github.com/ActiveState/cli/internal/analytics/constants" + "github.com/ActiveState/cli/internal/analytics/dimensions" + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/instanceid" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/logging" + configMediator "github.com/ActiveState/cli/internal/mediators/config" + "github.com/ActiveState/cli/internal/multilog" + "github.com/ActiveState/cli/internal/osutils" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/rtutils" + "github.com/ActiveState/cli/internal/rtutils/ptr" + buildscript_runbit "github.com/ActiveState/cli/internal/runbits/buildscript" + "github.com/ActiveState/cli/internal/runbits/checkout" + "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/internal/runbits/runtime/progress" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/platform/model" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" + "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/cli/pkg/runtime" + "github.com/ActiveState/cli/pkg/runtime/events" + "github.com/ActiveState/cli/pkg/runtime_helpers" + "github.com/go-openapi/strfmt" + "golang.org/x/net/context" +) + +func init() { + configMediator.RegisterHiddenOption(constants.AsyncRuntimeConfig, configMediator.Bool, false) +} + +type Opts struct { + PrintHeaders bool + TargetDir string + + // Note CommitID and Commit are mutually exclusive. If Commit is provided then CommitID is disregarded. + // Also, Archive and Commit are mutually exclusive, as both contain a BuildPlan. + CommitID strfmt.UUID + Commit *bpModel.Commit + Archive *checkout.Archive + + ValidateBuildscript bool + IgnoreAsync bool +} + +type SetOpt func(*Opts) + +func WithoutHeaders() SetOpt { + return func(opts *Opts) { + opts.PrintHeaders = false + } +} + +func WithTargetDir(targetDir string) SetOpt { + return func(opts *Opts) { + opts.TargetDir = targetDir + } +} + +func WithCommit(commit *bpModel.Commit) SetOpt { + return func(opts *Opts) { + opts.Commit = commit + } +} + +func WithCommitID(commitID strfmt.UUID) SetOpt { + return func(opts *Opts) { + opts.CommitID = commitID + } +} + +// WithoutBuildscriptValidation skips validating whether the local buildscript has changed. This is useful when trying +// to source a runtime that doesn't yet reflect the state of the project files (ie. as.yaml and buildscript). +func WithoutBuildscriptValidation() SetOpt { + return func(opts *Opts) { + opts.ValidateBuildscript = false + } +} + +func WithArchive(archive *checkout.Archive) SetOpt { + return func(opts *Opts) { + opts.Archive = archive + } +} + +func WithIgnoreAsync() SetOpt { + return func(opts *Opts) { + opts.IgnoreAsync = true + } +} + +type primeable interface { + primer.Projecter + primer.Auther + primer.Outputer + primer.Configurer + primer.SvcModeler + primer.Analyticer +} + +func Update( + prime primeable, + trigger trigger.Trigger, + setOpts ...SetOpt, +) (_ *runtime.Runtime, rerr error) { + defer rationalizeUpdateError(prime, &rerr) + + opts := &Opts{ + PrintHeaders: true, + ValidateBuildscript: true, + } + for _, setOpt := range setOpts { + setOpt(opts) + } + + proj := prime.Project() + + if proj == nil { + return nil, rationalize.ErrNoProject + } + + if proj.IsHeadless() { + return nil, rationalize.ErrHeadless + } + + targetDir := opts.TargetDir + if targetDir == "" { + targetDir = runtime_helpers.TargetDirFromProject(proj) + } + + rt, err := runtime.New(targetDir) + if err != nil { + return nil, errs.Wrap(err, "Could not initialize runtime") + } + + commitID := opts.CommitID + if opts.Commit != nil { + commitID = opts.Commit.CommitID + } + if commitID == "" { + commitID, err = localcommit.Get(proj.Dir()) + if err != nil { + return nil, errs.Wrap(err, "Failed to get local commit") + } + } + + ah, err := newAnalyticsHandler(prime, trigger, commitID) + if err != nil { + return nil, errs.Wrap(err, "Could not create event handler") + } + + // Runtime debugging encapsulates more than just sourcing of the runtime, so we handle some of these events + // external from the runtime event handling. + ah.fire(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeStart, nil) + defer func() { + if rerr == nil { + ah.fire(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeSuccess, nil) + } else { + ah.fireFailure(rerr) + } + }() + + rtHash, err := runtime_helpers.Hash(proj, &commitID) + if err != nil { + ah.fire(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeCache, nil) + return nil, errs.Wrap(err, "Failed to get runtime hash") + } + + if opts.PrintHeaders { + prime.Output().Notice(output.Title(locale.T("install_runtime"))) + } + + if rt.Hash() == rtHash { + prime.Output().Notice(locale.T("pkg_already_uptodate")) + return rt, nil + } + + var buildPlan *buildplan.BuildPlan + commit := opts.Commit + switch { + case opts.Archive != nil: + buildPlan = opts.Archive.BuildPlan + case commit != nil: + buildPlan = commit.BuildPlan() + default: + // Solve + solveSpinner := output.StartSpinner(prime.Output(), locale.T("progress_solve"), constants.TerminalAnimationInterval) + + bpm := bpModel.NewBuildPlannerModel(prime.Auth(), prime.SvcModel()) + commit, err = bpm.FetchCommit(commitID, proj.Owner(), proj.Name(), nil) + if err != nil { + solveSpinner.Stop(locale.T("progress_fail")) + return nil, errs.Wrap(err, "Failed to fetch build result") + } + buildPlan = commit.BuildPlan() + + solveSpinner.Stop(locale.T("progress_success")) + } + + // Validate buildscript + if prime.Config().GetBool(constants.OptinBuildscriptsConfig) && opts.ValidateBuildscript && os.Getenv(constants.DisableBuildscriptDirtyCheck) != "true" { + bs, err := buildscript_runbit.ScriptFromProject(proj) + if err != nil { + return nil, errs.Wrap(err, "Failed to get buildscript") + } + isClean, err := bs.Equals(commit.BuildScript()) + if err != nil { + return nil, errs.Wrap(err, "Failed to compare buildscript") + } + if !isClean { + return nil, ErrBuildScriptNeedsCommit + } + } + + // Async runtimes should still do everything up to the actual update itself, because we still want to raise + // any errors regarding solves, buildscripts, etc. + if prime.Config().GetBool(constants.AsyncRuntimeConfig) && !opts.IgnoreAsync { + logging.Debug("Skipping runtime update due to async runtime") + prime.Output().Notice("") // blank line + prime.Output().Notice(locale.Tr("notice_async_runtime", constants.AsyncRuntimeConfig)) + return rt, nil + } + + // Determine if this runtime is currently in use. + ctx, cancel := context.WithTimeout(context.Background(), model.SvcTimeoutMinimal) + defer cancel() + if procs, err := prime.SvcModel().GetProcessesInUse(ctx, rt.Env(false).ExecutorsPath); err == nil { + if len(procs) > 0 { + return nil, &RuntimeInUseError{procs} + } + } else { + multilog.Error("Unable to determine if runtime is in use: %v", errs.JoinMessage(err)) + } + + pg := progress.NewRuntimeProgressIndicator(prime.Output()) + defer rtutils.Closer(pg.Close, &rerr) + + rtOpts := []runtime.SetOpt{ + runtime.WithAnnotations(proj.Owner(), proj.Name(), commitID), + runtime.WithEventHandlers(pg.Handle, ah.handle), + runtime.WithPreferredLibcVersion(prime.Config().GetString(constants.PreferredGlibcVersionConfig)), + } + if opts.Archive != nil { + rtOpts = append(rtOpts, runtime.WithArchive(opts.Archive.Dir, opts.Archive.PlatformID, checkout.ArtifactExt)) + } + + if err := rt.Update(buildPlan, rtHash, rtOpts...); err != nil { + return nil, locale.WrapError(err, "err_packages_update_runtime_install") + } + + return rt, nil +} + +type analyticsHandler struct { + prime primeable + trigger trigger.Trigger + commitID strfmt.UUID + dimensionJson string + errorStage string +} + +func newAnalyticsHandler(prime primeable, trig trigger.Trigger, commitID strfmt.UUID) (*analyticsHandler, error) { + h := &analyticsHandler{prime, trig, commitID, "", ""} + dims := h.dimensions() + + dimsJson, err := dims.Marshal() + if err != nil { + return nil, errs.Wrap(err, "Could not marshal dimensions") + } + h.dimensionJson = dimsJson + + return h, nil +} + +func (h *analyticsHandler) fire(category, action string, dimensions *dimensions.Values) { + if dimensions == nil { + dimensions = h.dimensions() + } + h.prime.Analytics().Event(category, action, dimensions) +} + +func (h *analyticsHandler) fireFailure(err error) { + errorType := h.errorStage + if errorType == "" { + errorType = "unknown" + if locale.IsInputError(err) { + errorType = "input" + } + } + dims := h.dimensions() + dims.Error = ptr.To(errorType) + dims.Message = ptr.To(errs.JoinMessage(err)) + h.prime.Analytics().Event(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeFailure, dims) +} + +func (h *analyticsHandler) dimensions() *dimensions.Values { + return &dimensions.Values{ + Trigger: ptr.To(h.trigger.String()), + CommitID: ptr.To(h.commitID.String()), + ProjectNameSpace: ptr.To(project.NewNamespace(h.prime.Project().Owner(), h.prime.Project().Name(), h.commitID.String()).String()), + InstanceID: ptr.To(instanceid.ID()), + } +} + +func (h *analyticsHandler) handle(event events.Event) error { + switch event.(type) { + case events.Start: + h.prime.Analytics().Event(anaConsts.CatRuntimeUsage, anaConsts.ActRuntimeAttempt, h.dimensions()) + case events.Success: + if err := h.prime.SvcModel().ReportRuntimeUsage(context.Background(), os.Getpid(), osutils.Executable(), anaConsts.SrcStateTool, h.dimensionJson); err != nil { + multilog.Critical("Could not report runtime usage: %s", errs.JoinMessage(err)) + } + case events.ArtifactBuildFailure: + h.errorStage = anaConsts.ActRuntimeBuild + h.fire(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeBuild, nil) + case events.ArtifactDownloadFailure: + h.errorStage = anaConsts.ActRuntimeDownload + h.fire(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeDownload, nil) + case events.ArtifactUnpackFailure: + h.errorStage = anaConsts.ActRuntimeUnpack + h.fire(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeUnpack, nil) + case events.ArtifactInstallFailure: + h.errorStage = anaConsts.ActRuntimeInstall + h.fire(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeInstall, nil) + case events.ArtifactUninstallFailure: + h.errorStage = anaConsts.ActRuntimeUninstall + h.fire(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeUninstall, nil) + case events.PostProcessFailure: + h.errorStage = anaConsts.ActRuntimePostprocess + h.fire(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimePostprocess, nil) + } + + return nil +} diff --git a/internal/runbits/runtime/runtimeevents.go b/internal/runbits/runtime/runtimeevents.go deleted file mode 100644 index 2089f484da..0000000000 --- a/internal/runbits/runtime/runtimeevents.go +++ /dev/null @@ -1,21 +0,0 @@ -package runtime - -import ( - "io" - "os" - - "github.com/ActiveState/cli/internal/output" - "github.com/ActiveState/cli/internal/runbits/runtime/progress" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/events" -) - -func NewRuntimeProgressIndicator(out output.Outputer) events.Handler { - var w io.Writer = os.Stdout - if out.Type() != output.PlainFormatName { - w = nil - } - if out.Config().Interactive { - return progress.NewProgressIndicator(w, out) - } - return progress.NewDotProgressIndicator(out) -} diff --git a/internal/runbits/runtime/trigger/trigger.go b/internal/runbits/runtime/trigger/trigger.go new file mode 100644 index 0000000000..80c752d9b7 --- /dev/null +++ b/internal/runbits/runtime/trigger/trigger.go @@ -0,0 +1,36 @@ +package trigger + +import ( + "fmt" +) + +type Trigger string + +func (t Trigger) String() string { + return string(t) +} + +const ( + TriggerActivate Trigger = "activate" + TriggerScript Trigger = "script" + TriggerDeploy Trigger = "deploy" + TriggerExec Trigger = "exec-cmd" + TriggerExecutor Trigger = "exec" + TriggerSwitch Trigger = "switch" + TriggerImport Trigger = "import" + TriggerInit Trigger = "init" + TriggerPlatform Trigger = "platform" + TriggerPull Trigger = "pull" + TriggerRefresh Trigger = "refresh" + TriggerReset Trigger = "reset" + TriggerRevert Trigger = "revert" + TriggerShell Trigger = "shell" + TriggerCheckout Trigger = "checkout" + TriggerUse Trigger = "use" + TriggerInstall Trigger = "install" + TriggerUninstall Trigger = "uninstall" +) + +func NewExecTrigger(cmd string) Trigger { + return Trigger(fmt.Sprintf("%s: %s", TriggerExec, cmd)) +} diff --git a/internal/runners/activate/activate.go b/internal/runners/activate/activate.go index caf86cfcc2..1cf3c2f389 100644 --- a/internal/runners/activate/activate.go +++ b/internal/runners/activate/activate.go @@ -25,16 +25,20 @@ import ( "github.com/ActiveState/cli/internal/runbits/findproject" "github.com/ActiveState/cli/internal/runbits/git" "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/virtualenvironment" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" ) type Activate struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 activateCheckout *checkout.Checkout auth *authentication.Auth out output.Outputer @@ -66,6 +70,7 @@ type primeable interface { func NewActivate(prime primeable) *Activate { return &Activate{ + prime, checkout.New(git.NewRepo(), prime), prime.Auth(), prime.Output(), @@ -90,7 +95,7 @@ func (r *Activate) Run(params *ActivateParams) (rerr error) { } // Perform fresh checkout - pathToUse, err := r.activateCheckout.Run(params.Namespace, params.Branch, "", params.PreferredPath, false) + pathToUse, err := r.activateCheckout.Run(params.Namespace, params.Branch, "", params.PreferredPath, false, false) if err != nil { return locale.WrapError(err, "err_activate_pathtouse", "Could not figure out what path to use.") } @@ -101,6 +106,8 @@ func (r *Activate) Run(params *ActivateParams) (rerr error) { } } + r.prime.SetProject(proj) + alreadyActivated := process.IsActivated(r.config) if alreadyActivated { if !params.Default { @@ -169,7 +176,7 @@ func (r *Activate) Run(params *ActivateParams) (rerr error) { } } - rt, err := runtime.SolveAndUpdate(r.auth, r.out, r.analytics, proj, nil, target.TriggerActivate, r.svcModel, r.config, runtime.OptMinimalUI) + rt, err := runtime_runbit.Update(r.prime, trigger.TriggerActivate, runtime_runbit.WithoutHeaders(), runtime_runbit.WithIgnoreAsync()) if err != nil { return locale.WrapError(err, "err_could_not_activate_venv", "Could not activate project") } @@ -194,7 +201,7 @@ func (r *Activate) Run(params *ActivateParams) (rerr error) { return errs.Wrap(err, "Unable to get local commit") } if commitID == "" { - err := locale.NewInputError("err_project_no_commit", "Your project does not have a commit ID, please run [ACTIONIABLE]'state push'[/RESET] first.", model.ProjectURL(proj.Owner(), proj.Name(), "")) + err := locale.NewInputError("err_project_no_commit", "Your project does not have a commit ID. Please run [ACTIONIABLE]'state push'[/RESET] first.", model.ProjectURL(proj.Owner(), proj.Name(), "")) return errs.AddTips(err, "Run → [ACTIONABLE]state push[/RESET] to create your project") } diff --git a/internal/runners/artifacts/artifacts.go b/internal/runners/artifacts/artifacts.go index b56620a4b0..078d2668a1 100644 --- a/internal/runners/artifacts/artifacts.go +++ b/internal/runners/artifacts/artifacts.go @@ -9,23 +9,18 @@ import ( "github.com/ActiveState/cli/internal/analytics" "github.com/ActiveState/cli/internal/config" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/ActiveState/cli/internal/runbits/rationalize" + buildplanner_runbit "github.com/ActiveState/cli/internal/runbits/buildplanner" "github.com/ActiveState/cli/pkg/buildplan" - "github.com/ActiveState/cli/pkg/localcommit" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/request" bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" "github.com/ActiveState/cli/pkg/project" - "github.com/go-openapi/strfmt" "github.com/google/uuid" ) @@ -52,6 +47,7 @@ type Configurable interface { } type Artifacts struct { + prime primeable out output.Outputer project *project.Project analytics analytics.Dispatcher @@ -88,6 +84,7 @@ type structuredArtifact struct { func New(p primeable) *Artifacts { return &Artifacts{ + prime: p, out: p.Output(), project: p.Project(), auth: p.Auth(), @@ -97,24 +94,7 @@ func New(p primeable) *Artifacts { } } -type errInvalidCommitId struct { - id string -} - -func (e *errInvalidCommitId) Error() string { - return "Invalid commit ID" -} - -type errCommitDoesNotExistInProject struct { - Project string - CommitID string -} - -func (e *errCommitDoesNotExistInProject) Error() string { - return "Commit does not exist in project" -} - -func rationalizeArtifactsError(rerr *error, auth *authentication.Auth) { +func rationalizeArtifactsError(proj *project.Project, auth *authentication.Auth, rerr *error) { if rerr == nil { return } @@ -126,19 +106,19 @@ func rationalizeArtifactsError(rerr *error, auth *authentication.Auth) { *rerr = errs.WrapUserFacing(*rerr, planningError.Error()) default: - rationalizeCommonError(rerr, auth) + rationalizeCommonError(proj, auth, rerr) } } func (b *Artifacts) Run(params *Params) (rerr error) { - defer rationalizeArtifactsError(&rerr, b.auth) + defer rationalizeArtifactsError(b.project, b.auth, &rerr) if b.project != nil && !params.Namespace.IsValid() { b.out.Notice(locale.Tr("operating_message", b.project.NamespaceString(), b.project.Dir())) } - bp, err := getBuildPlan( - b.project, params.Namespace, params.CommitID, params.Target, b.auth, b.out) + bp, err := buildplanner_runbit.GetBuildPlan( + params.Namespace, params.CommitID, params.Target, b.prime) if err != nil { return errs.Wrap(err, "Could not get buildplan") } @@ -148,7 +128,7 @@ func (b *Artifacts) Run(params *Params) (rerr error) { return errs.Wrap(err, "Could not get platforms") } - hasFailedArtifacts := len(bp.Artifacts()) != len(bp.Artifacts(buildplan.FilterSuccessfulArtifacts())) + hasFailedArtifacts := len(bp.Artifacts(buildplan.FilterFailedArtifacts())) > 0 out := &StructuredOutput{HasFailedArtifacts: hasFailedArtifacts, BuildComplete: bp.IsBuildReady()} for _, platformUUID := range bp.Platforms() { @@ -225,8 +205,8 @@ func (b *Artifacts) outputPlain(out *StructuredOutput, fullID bool) error { switch { case len(artifact.Errors) > 0: b.out.Print(fmt.Sprintf(" • %s ([ERROR]%s[/RESET])", artifact.Name, locale.T("artifact_status_failed"))) - b.out.Print(fmt.Sprintf(" ├─ %s: [ERROR]%s[/RESET]", locale.T("artifact_status_failed_message"), strings.Join(artifact.Errors, ": "))) - b.out.Print(fmt.Sprintf(" └─ %s: [ACTIONABLE]%s[/RESET]", locale.T("artifact_status_failed_log"), artifact.LogURL)) + b.out.Print(fmt.Sprintf(" %s %s: [ERROR]%s[/RESET]", output.TreeMid, locale.T("artifact_status_failed_message"), strings.Join(artifact.Errors, ": "))) + b.out.Print(fmt.Sprintf(" %s %s: [ACTIONABLE]%s[/RESET]", output.TreeEnd, locale.T("artifact_status_failed_log"), artifact.LogURL)) continue case artifact.status == types.ArtifactSkipped: b.out.Print(fmt.Sprintf(" • %s ([NOTICE]%s[/RESET])", artifact.Name, locale.T("artifact_status_skipped"))) @@ -249,8 +229,8 @@ func (b *Artifacts) outputPlain(out *StructuredOutput, fullID bool) error { switch { case len(artifact.Errors) > 0: b.out.Print(fmt.Sprintf(" • %s ([ERROR]%s[/RESET])", artifact.Name, locale.T("artifact_status_failed"))) - b.out.Print(fmt.Sprintf(" ├─ %s: [ERROR]%s[/RESET]", locale.T("artifact_status_failed_message"), strings.Join(artifact.Errors, ": "))) - b.out.Print(fmt.Sprintf(" └─ %s: [ACTIONABLE]%s[/RESET]", locale.T("artifact_status_failed_log"), artifact.LogURL)) + b.out.Print(fmt.Sprintf(" %s %s: [ERROR]%s[/RESET]", output.TreeMid, locale.T("artifact_status_failed_message"), strings.Join(artifact.Errors, ": "))) + b.out.Print(fmt.Sprintf(" %s %s: [ACTIONABLE]%s[/RESET]", output.TreeEnd, locale.T("artifact_status_failed_log"), artifact.LogURL)) continue case artifact.status == types.ArtifactSkipped: b.out.Print(fmt.Sprintf(" • %s ([NOTICE]%s[/RESET])", artifact.Name, locale.T("artifact_status_skipped"))) @@ -284,125 +264,3 @@ func (b *Artifacts) outputPlain(out *StructuredOutput, fullID bool) error { b.out.Print("\nTo download artifacts run '[ACTIONABLE]state artifacts dl [/RESET]'.") return nil } - -// getBuildPlan returns a project's terminal artifact map, depending on the given -// arguments. By default, the map for the current project is returned, but a map for a given -// commitID for the current project can be returned, as can the map for a remote project -// (and optional commitID). -func getBuildPlan( - pj *project.Project, - namespace *project.Namespaced, - commitID string, - target string, - auth *authentication.Auth, - out output.Outputer) (bp *buildplan.BuildPlan, rerr error) { - if pj == nil && !namespace.IsValid() { - return nil, rationalize.ErrNoProject - } - - commitUUID := strfmt.UUID(commitID) - if commitUUID != "" && !strfmt.IsUUID(commitUUID.String()) { - return nil, &errInvalidCommitId{commitUUID.String()} - } - - namespaceProvided := namespace.IsValid() - commitIdProvided := commitUUID != "" - - // Show a spinner when fetching a terminal artifact map. - // Sourcing the local runtime for an artifact map has its own spinner. - pb := output.StartSpinner(out, locale.T("progress_solve"), constants.TerminalAnimationInterval) - defer func() { - message := locale.T("progress_success") - if rerr != nil { - message = locale.T("progress_fail") - } - pb.Stop(message + "\n") // extra empty line - }() - - targetPtr := ptr.To(request.TargetAll) - if target != "" { - targetPtr = &target - } - - var err error - var commit *bpModel.Commit - switch { - // Return the artifact map from this runtime. - case !namespaceProvided && !commitIdProvided: - localCommitID, err := localcommit.Get(pj.Path()) - if err != nil { - return nil, errs.Wrap(err, "Could not get local commit") - } - - bp := bpModel.NewBuildPlannerModel(auth) - commit, err = bp.FetchCommit(localCommitID, pj.Owner(), pj.Name(), targetPtr) - if err != nil { - return nil, errs.Wrap(err, "Failed to fetch commit") - } - - // Return artifact map from the given commitID for the current project. - case !namespaceProvided && commitIdProvided: - bp := bpModel.NewBuildPlannerModel(auth) - commit, err = bp.FetchCommit(commitUUID, pj.Owner(), pj.Name(), targetPtr) - if err != nil { - return nil, errs.Wrap(err, "Failed to fetch commit") - } - - // Return the artifact map for the latest commitID of the given project. - case namespaceProvided && !commitIdProvided: - pj, err := model.FetchProjectByName(namespace.Owner, namespace.Project, auth) - if err != nil { - return nil, locale.WrapExternalError(err, "err_fetch_project", "", namespace.String()) - } - - branch, err := model.DefaultBranchForProject(pj) - if err != nil { - return nil, errs.Wrap(err, "Could not grab branch for project") - } - - branchCommitUUID, err := model.BranchCommitID(namespace.Owner, namespace.Project, branch.Label) - if err != nil { - return nil, errs.Wrap(err, "Could not get commit ID for project") - } - commitUUID = *branchCommitUUID - - bp := bpModel.NewBuildPlannerModel(auth) - commit, err = bp.FetchCommit(commitUUID, namespace.Owner, namespace.Project, targetPtr) - if err != nil { - return nil, errs.Wrap(err, "Failed to fetch commit") - } - - // Return the artifact map for the given commitID of the given project. - case namespaceProvided && commitIdProvided: - bp := bpModel.NewBuildPlannerModel(auth) - commit, err = bp.FetchCommit(commitUUID, namespace.Owner, namespace.Project, targetPtr) - if err != nil { - return nil, errs.Wrap(err, "Failed to fetch commit") - } - - default: - return nil, errs.New("Unhandled case") - } - - // Note: the Platform does not raise an error when requesting a commit ID that does not exist in - // a given project, so we have verify existence client-side. See DS-1705 (yes, DS, not DX). - var owner, name, nsString string - if namespaceProvided { - owner = namespace.Owner - name = namespace.Project - nsString = namespace.String() - } else { - owner = pj.Owner() - name = pj.Name() - nsString = pj.NamespaceString() - } - _, err = model.GetCommitWithinProjectHistory(commit.CommitID, owner, name, auth) - if err != nil { - if err == model.ErrCommitNotInHistory { - return nil, errs.Pack(err, &errCommitDoesNotExistInProject{nsString, commit.CommitID.String()}) - } - return nil, errs.Wrap(err, "Unable to determine if commit exists in project") - } - - return commit.BuildPlan(), nil -} diff --git a/internal/runners/artifacts/download.go b/internal/runners/artifacts/download.go index 2c0b849c8e..86b2b4d2bb 100644 --- a/internal/runners/artifacts/download.go +++ b/internal/runners/artifacts/download.go @@ -17,12 +17,14 @@ import ( "github.com/ActiveState/cli/internal/httputil" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" + buildplanner_runbit "github.com/ActiveState/cli/internal/runbits/buildplanner" "github.com/ActiveState/cli/pkg/buildplan" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/request" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - rtProgress "github.com/ActiveState/cli/pkg/platform/runtime/setup/events/progress" "github.com/ActiveState/cli/pkg/project" + rtProgress "github.com/ActiveState/cli/pkg/runtime/events/progress" ) type DownloadParams struct { @@ -34,6 +36,7 @@ type DownloadParams struct { } type Download struct { + prime primeable out output.Outputer project *project.Project analytics analytics.Dispatcher @@ -44,6 +47,7 @@ type Download struct { func NewDownload(prime primeable) *Download { return &Download{ + prime: prime, out: prime.Output(), project: prime.Project(), analytics: prime.Analytics(), @@ -54,11 +58,14 @@ func NewDownload(prime primeable) *Download { } type errArtifactExists struct { - error Path string } -func rationalizeDownloadError(err *error, auth *authentication.Auth) { +func (e errArtifactExists) Error() string { + return "artifact exists" +} + +func rationalizeDownloadError(proj *project.Project, auth *authentication.Auth, err *error) { var artifactExistsErr *errArtifactExists switch { @@ -71,12 +78,12 @@ func rationalizeDownloadError(err *error, auth *authentication.Auth) { errs.SetInput()) default: - rationalizeCommonError(err, auth) + rationalizeCommonError(proj, auth, err) } } func (d *Download) Run(params *DownloadParams) (rerr error) { - defer rationalizeDownloadError(&rerr, d.auth) + defer rationalizeDownloadError(d.project, d.auth, &rerr) if d.project != nil && !params.Namespace.IsValid() { d.out.Notice(locale.Tr("operating_message", d.project.NamespaceString(), d.project.Dir())) @@ -87,8 +94,8 @@ func (d *Download) Run(params *DownloadParams) (rerr error) { target = params.Target } - bp, err := getBuildPlan( - d.project, params.Namespace, params.CommitID, target, d.auth, d.out) + bp, err := buildplanner_runbit.GetBuildPlan( + params.Namespace, params.CommitID, target, d.prime) if err != nil { return errs.Wrap(err, "Could not get build plan map") } @@ -121,6 +128,9 @@ func (d *Download) Run(params *DownloadParams) (rerr error) { } func (d *Download) downloadArtifact(artifact *buildplan.Artifact, targetDir string) (rerr error) { + if artifact.Status != types.ArtifactSucceeded { + return locale.NewInputError("err_artifact_dl_status", "Could not download artifact {{.V0}}, status is {{.V1}}", artifact.Name(), artifact.Status) + } artifactURL, err := url.Parse(artifact.URL) if err != nil { return errs.Wrap(err, "Could not parse artifact URL %s.", artifact.URL) @@ -136,7 +146,7 @@ func (d *Download) downloadArtifact(artifact *buildplan.Artifact, targetDir stri downloadPath := filepath.Join(targetDir, basename) if fileutils.TargetExists(downloadPath) { - return &errArtifactExists{Path: downloadPath} + return &errArtifactExists{downloadPath} } ctx, cancel := context.WithCancel(context.Background()) @@ -164,7 +174,11 @@ func (d *Download) downloadArtifact(artifact *buildplan.Artifact, targetDir stri return errs.Wrap(err, "Writing download to target file %s failed", downloadPath) } - d.out.Notice(locale.Tl("msg_download_success", "[SUCCESS]Downloaded {{.V0}} to {{.V1}}[/RESET]", artifact.Name(), downloadPath)) + if d.out.Type().IsStructured() { + d.out.Print(output.Structured(downloadPath)) + } else { + d.out.Notice(locale.Tl("msg_download_success", "[SUCCESS]Downloaded {{.V0}} to {{.V1}}[/RESET]", artifact.Name(), downloadPath)) + } return nil } diff --git a/internal/runners/artifacts/rationalize.go b/internal/runners/artifacts/rationalize.go index b2ca3c5ca7..42aac060d0 100644 --- a/internal/runners/artifacts/rationalize.go +++ b/internal/runners/artifacts/rationalize.go @@ -5,15 +5,18 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/runbits/buildplanner" "github.com/ActiveState/cli/internal/runbits/rationalize" + runtime_runbit "github.com/ActiveState/cli/internal/runbits/runtime" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/project" ) -func rationalizeCommonError(err *error, auth *authentication.Auth) { - var invalidCommitIdErr *errInvalidCommitId +func rationalizeCommonError(proj *project.Project, auth *authentication.Auth, err *error) { + var invalidCommitIdErr *buildplanner.ErrInvalidCommitId var projectNotFoundErr *model.ErrProjectNotFound - var commitIdDoesNotExistInProject *errCommitDoesNotExistInProject + var commitIdDoesNotExistInProject *buildplanner.ErrCommitDoesNotExistInProject switch { case errors.Is(*err, rationalize.ErrNoProject): @@ -23,7 +26,7 @@ func rationalizeCommonError(err *error, auth *authentication.Auth) { case errors.As(*err, &invalidCommitIdErr): *err = errs.WrapUserFacing( - *err, locale.Tr("err_commit_id_invalid_given", invalidCommitIdErr.id), + *err, locale.Tr("err_commit_id_invalid_given", invalidCommitIdErr.Id), errs.SetInput()) case errors.As(*err, &projectNotFoundErr): @@ -34,12 +37,16 @@ func rationalizeCommonError(err *error, auth *authentication.Auth) { case errors.As(*err, &commitIdDoesNotExistInProject): *err = errs.WrapUserFacing(*err, - locale.Tl("err_commit_id_not_in_history", - "The project '[ACTIONABLE]{{.V0}}[/RESET]' does not contain the provided commit: '[ACTIONABLE]{{.V1}}[/RESET]'.", + locale.Tr("err_commit_id_not_in_history", commitIdDoesNotExistInProject.Project, commitIdDoesNotExistInProject.CommitID, ), errs.SetInput()) + + default: + runtime_runbit.RationalizeSolveError(proj, auth, err) + return + } } diff --git a/internal/runners/branch/tree.go b/internal/runners/branch/tree.go index 7da0ab0c59..611401bccd 100644 --- a/internal/runners/branch/tree.go +++ b/internal/runners/branch/tree.go @@ -5,6 +5,7 @@ import ( "sort" "strings" + "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" "github.com/ActiveState/cli/pkg/platform/model" ) @@ -17,9 +18,9 @@ type branchNode struct { type tree map[branchNode]tree const ( - prefixLink string = "│" - prefixMid string = "├─" - prefixEnd string = "└─" + prefixLink string = output.TreeLink + prefixMid string = output.TreeMid + prefixEnd string = output.TreeEnd branchFormatting string = "[NOTICE]%s[/RESET]" localBranchFormatting string = "[ACTIONABLE]%s[/RESET] [DISABLED](Current)[/RESET]" diff --git a/internal/runners/checkout/checkout.go b/internal/runners/checkout/checkout.go index c11da87151..ea2105031e 100644 --- a/internal/runners/checkout/checkout.go +++ b/internal/runners/checkout/checkout.go @@ -1,8 +1,10 @@ package checkout import ( + "errors" "os" "path/filepath" + "strings" "github.com/ActiveState/cli/internal/analytics" "github.com/ActiveState/cli/internal/config" @@ -15,19 +17,22 @@ import ( "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/runbits/checkout" + "github.com/ActiveState/cli/internal/runbits/cves" "github.com/ActiveState/cli/internal/runbits/dependencies" "github.com/ActiveState/cli/internal/runbits/git" "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/subshell" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" "github.com/ActiveState/cli/pkg/project" ) type Params struct { - Namespace *project.Namespaced + Namespace string PreferredPath string Branch string RuntimePath string @@ -43,9 +48,14 @@ type primeable interface { primer.Configurer primer.SvcModeler primer.Analyticer + primer.Projecter } type Checkout struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 auth *authentication.Auth out output.Outputer checkout *checkout.Checkout @@ -57,6 +67,7 @@ type Checkout struct { func NewCheckout(prime primeable) *Checkout { return &Checkout{ + prime, prime.Auth(), prime.Output(), checkout.New(git.NewRepo(), prime), @@ -67,23 +78,59 @@ func NewCheckout(prime primeable) *Checkout { } } +func rationalizeError(rerr *error) { + if rerr == nil { + return + } + + switch { + case errors.Is(*rerr, checkout.ErrNoOrg): + *rerr = errs.WrapUserFacing(*rerr, + locale.Tl("err_no_org_name", "Your project's organization name could not be found"), + errs.SetInput()) + } +} + func (u *Checkout) Run(params *Params) (rerr error) { - logging.Debug("Checkout %v", params.Namespace) + var err error + var ns *project.Namespaced + var archive *checkout.Archive + + switch { + // Checkout from archive + case strings.HasSuffix(params.Namespace, checkout.ArchiveExt): + archive, err = checkout.NewArchive(params.Namespace) + if err != nil { + return errs.Wrap(err, "Unable to read archive") + } + defer archive.Cleanup() + ns = archive.Namespace + params.Branch = archive.Branch + + // Checkout from namespace + default: + if ns, err = project.ParseNamespace(params.Namespace); err != nil { + return errs.Wrap(err, "cannot set namespace") + } + } - logging.Debug("Checking out %s to %s", params.Namespace.String(), params.PreferredPath) + defer func() { runtime_runbit.RationalizeSolveError(u.prime.Project(), u.auth, &rerr) }() + defer rationalizeError(&rerr) - u.out.Notice(locale.Tr("checking_out", params.Namespace.String())) + logging.Debug("Checking out %s to %s", ns.String(), params.PreferredPath) - var err error - projectDir, err := u.checkout.Run(params.Namespace, params.Branch, params.RuntimePath, params.PreferredPath, params.NoClone) + u.out.Notice(locale.Tr("checking_out", ns.String())) + + projectDir, err := u.checkout.Run(ns, params.Branch, params.RuntimePath, params.PreferredPath, params.NoClone, archive != nil) if err != nil { return errs.Wrap(err, "Checkout failed") } proj, err := project.FromPath(projectDir) if err != nil { - return locale.WrapError(err, "err_project_frompath") + return errs.Wrap(err, "Could not read created project file") } + u.prime.SetProject(proj) // If an error occurs, remove the created activestate.yaml file and/or directory. if !params.Force { @@ -107,19 +154,51 @@ func (u *Checkout) Run(params *Params) (rerr error) { }() } - rti, commit, err := runtime.Solve(u.auth, u.out, u.analytics, proj, nil, target.TriggerCheckout, u.svcModel, u.config, runtime.OptNoIndent) - if err != nil { - return errs.Wrap(err, "Could not checkout project") + var buildPlan *buildplan.BuildPlan + rtOpts := []runtime_runbit.SetOpt{} + if archive == nil { + commitID, err := localcommit.Get(proj.Path()) + if err != nil { + return errs.Wrap(err, "Could not get local commit") + } + + // Solve runtime + solveSpinner := output.StartSpinner(u.out, locale.T("progress_solve"), constants.TerminalAnimationInterval) + bpm := bpModel.NewBuildPlannerModel(u.auth, u.svcModel) + commit, err := bpm.FetchCommit(commitID, proj.Owner(), proj.Name(), nil) + if err != nil { + solveSpinner.Stop(locale.T("progress_fail")) + return errs.Wrap(err, "Failed to fetch build result") + } + solveSpinner.Stop(locale.T("progress_success")) + + buildPlan = commit.BuildPlan() + rtOpts = append(rtOpts, runtime_runbit.WithCommit(commit)) + + } else { + buildPlan = archive.BuildPlan + + rtOpts = append(rtOpts, + runtime_runbit.WithArchive(archive), + runtime_runbit.WithoutBuildscriptValidation(), + ) } - dependencies.OutputSummary(u.out, commit.BuildPlan().RequestedArtifacts()) - err = runtime.UpdateByReference(rti, commit, u.auth, proj, u.out, u.config, runtime.OptNone) + + dependencies.OutputSummary(u.out, buildPlan.RequestedArtifacts()) + + if err := cves.NewCveReport(u.prime).Report(buildPlan, nil); err != nil { + return errs.Wrap(err, "Could not report CVEs") + } + + rti, err := runtime_runbit.Update(u.prime, trigger.TriggerCheckout, rtOpts...) if err != nil { return errs.Wrap(err, "Could not setup runtime") } + var execDir string var checkoutStatement string - execDir := setup.ExecDir(rti.Target().Dir()) if !u.config.GetBool(constants.AsyncRuntimeConfig) { + execDir = rti.Env(false).ExecutorsPath checkoutStatement = locale.Tr("checkout_project_statement", proj.NamespaceString(), proj.Dir(), execDir) } else { checkoutStatement = locale.Tr("checkout_project_statement_async", proj.NamespaceString(), proj.Dir()) diff --git a/internal/runners/clean/cache.go b/internal/runners/clean/cache.go index 17ad90dcb5..e4f48eb14a 100644 --- a/internal/runners/clean/cache.go +++ b/internal/runners/clean/cache.go @@ -1,7 +1,9 @@ package clean import ( + "context" "os" + "time" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" @@ -10,11 +12,12 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/svcctl" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/projectfile" + "github.com/ActiveState/cli/pkg/runtime_helpers" ) type Cache struct { + prime primeable output output.Outputer config configurable confirm promptable @@ -28,11 +31,12 @@ type CacheParams struct { } func NewCache(prime primeable) *Cache { - return newCache(prime.Output(), prime.Config(), prime.Prompt(), prime.IPComm()) + return newCache(prime, prime.Output(), prime.Config(), prime.Prompt(), prime.IPComm()) } -func newCache(output output.Outputer, cfg configurable, confirm promptable, ipComm svcctl.IPCommunicator) *Cache { +func newCache(prime primeable, output output.Outputer, cfg configurable, confirm promptable, ipComm svcctl.IPCommunicator) *Cache { return &Cache{ + prime: prime, output: output, config: cfg, confirm: confirm, @@ -76,9 +80,16 @@ func (c *Cache) removeCache(path string, force bool) error { } } - logging.Debug("Removing cache path: %s", path) - err := removeCache(c.path) + inUse, err := c.checkPathInUse(path) if err != nil { + return errs.Wrap(err, "Failed to check if path is in use") + } + if inUse { + return locale.NewInputError("err_clean_in_use") + } + + logging.Debug("Removing cache path: %s", path) + if err := removeCache(c.path); err != nil { return errs.Wrap(err, "Failed to remove cache") } @@ -97,12 +108,39 @@ func (c *Cache) removeProjectCache(projectDir, namespace string, force bool) err } } - projectInstallPath := target.ProjectDirToTargetDir(projectDir, storage.CachePath()) - logging.Debug("Remove project path: %s", projectInstallPath) - err := os.RemoveAll(projectInstallPath) + inUse, err := c.checkPathInUse(projectDir) if err != nil { + return errs.Wrap(err, "Failed to check if path is in use") + } + if inUse { + return locale.NewInputError("err_clean_in_use") + } + + projectInstallPath, err := runtime_helpers.TargetDirFromProjectDir(projectDir) + if err != nil { + return errs.Wrap(err, "Failed to determine project install path") + } + + logging.Debug("Remove project path: %s", projectInstallPath) + if err := os.RemoveAll(projectInstallPath); err != nil { return locale.WrapError(err, "err_clean_remove_artifact", "Could not remove cached runtime environment for project: {{.V0}}", namespace) } return nil } + +func (c *Cache) checkPathInUse(path string) (bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + + procs, err := c.prime.SvcModel().GetProcessesInUse(ctx, path) + if err != nil { + return false, errs.Wrap(err, "Failed to get processes in use") + } + + if len(procs) > 0 { + return true, nil + } + + return false, nil +} diff --git a/internal/runners/clean/run_lin_mac.go b/internal/runners/clean/run_lin_mac.go index 97d227c562..4e7cf319ba 100644 --- a/internal/runners/clean/run_lin_mac.go +++ b/internal/runners/clean/run_lin_mac.go @@ -205,14 +205,13 @@ func cleanInstallDir(dir string, cfg *config.Instance) error { } var asFiles = []string{ - installation.InstallDirMarker, constants.StateInstallerCmd + osutils.ExeExtension, } - // Remove all of the state tool executables and finally the - // bin directory + // Remove all of the state tool executables, bin directory, and finally the install marker. asFiles = append(asFiles, execs...) asFiles = append(asFiles, installation.BinDirName) + asFiles = append(asFiles, installation.InstallDirMarker) for _, file := range asFiles { f := filepath.Join(dir, file) diff --git a/internal/runners/clean/run_win.go b/internal/runners/clean/run_win.go index ada96c62b4..d762dc25b8 100644 --- a/internal/runners/clean/run_win.go +++ b/internal/runners/clean/run_win.go @@ -116,14 +116,19 @@ func removeInstall(logFile string, params *UninstallParams, cfg *config.Instance return locale.WrapError(err, "err_state_exec") } - // Schedule removal of the entire install directory. + // Schedule ordered removal of the entire install directory. // This is because Windows often thinks the installation.InstallDirMarker and // constants.StateInstallerCmd files are still in use. installDir, err := installation.InstallPathFromExecPath() if err != nil { return errs.Wrap(err, "Could not get installation path") } - paths := []string{stateExec, installDir} + paths := []string{ + stateExec, + filepath.Join(installDir, installation.BinDirName), + filepath.Join(installDir, installation.InstallDirMarker), // should be after bin + installDir, + } if params.All { paths = append(paths, cfg.ConfigPath()) // also remove the config directory } diff --git a/internal/runners/clean/stop.go b/internal/runners/clean/stop.go index 25c8e987ef..9945e3132b 100644 --- a/internal/runners/clean/stop.go +++ b/internal/runners/clean/stop.go @@ -26,7 +26,7 @@ func stopServices(cfg configurable, out output.Outputer, ipComm svcctl.IPCommuni if err != nil { if !ignoreErrors { return errs.AddTips( - locale.WrapError(err, "clean_stop_svc_failure", "Cleanup interrupted, because a running {{.V0}} process could not be stopped.", constants.SvcAppName), + locale.WrapError(err, "clean_stop_svc_failure", "Cleanup interrupted because a running {{.V0}} process could not be stopped.", constants.SvcAppName), cleanForceTip) } out.Error(locale.Tl("clean_stop_svc_warning", "Failed to stop running {{.V0}} process. Continuing anyway because --force flag was provided.", constants.SvcAppName)) @@ -34,7 +34,7 @@ func stopServices(cfg configurable, out output.Outputer, ipComm svcctl.IPCommuni if code != 0 { if !ignoreErrors { return errs.AddTips( - locale.WrapError(err, "clean_stop_svc_failure_code", "Cleanup interrupted, because a running {{.V0}} process could not be stopped (invalid exit code).", constants.SvcAppName), + locale.WrapError(err, "clean_stop_svc_failure_code", "Cleanup interrupted because a running {{.V0}} process could not be stopped (invalid exit code).", constants.SvcAppName), cleanForceTip) } out.Error(locale.Tl("clean_stop_svc_warning_code", "Failed to stop running {{.V0}} process (invalid exit code). Continuing anyway because --force flag was provided.", constants.SvcAppName)) @@ -43,7 +43,7 @@ func stopServices(cfg configurable, out output.Outputer, ipComm svcctl.IPCommuni if err := svcctl.StopServer(ipComm); err != nil { if !ignoreErrors { return errs.AddTips( - locale.WrapError(err, "clean_stop_svc_failure_wait", "Cleanup interrupted, because a running {{.V0}} process failed to stop due to a timeout.", constants.SvcAppName), + locale.WrapError(err, "clean_stop_svc_failure_wait", "Cleanup interrupted because a running {{.V0}} process failed to stop due to a timeout.", constants.SvcAppName), cleanForceTip) } out.Error(locale.Tl("clean_stop_svc_warning_code", "Failed to stop running {{.V0}} process due to a timeout. Continuing anyway because --force flag was provided.", constants.SvcAppName)) diff --git a/internal/runners/clean/uninstall.go b/internal/runners/clean/uninstall.go index 323d89f3aa..8b6071e1a7 100644 --- a/internal/runners/clean/uninstall.go +++ b/internal/runners/clean/uninstall.go @@ -42,6 +42,7 @@ type primeable interface { primer.Configurer primer.IPCommunicator primer.Analyticer + primer.SvcModeler } func NewUninstall(prime primeable) (*Uninstall, error) { diff --git a/internal/runners/commit/commit.go b/internal/runners/commit/commit.go index 6a4d7be631..4b7b208ccc 100644 --- a/internal/runners/commit/commit.go +++ b/internal/runners/commit/commit.go @@ -3,21 +3,18 @@ package commit import ( "errors" - "github.com/ActiveState/cli/internal/analytics" - "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/runbits/buildscript" + buildscript_runbit "github.com/ActiveState/cli/internal/runbits/buildscript" + "github.com/ActiveState/cli/internal/runbits/cves" + "github.com/ActiveState/cli/internal/runbits/dependencies" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/pkg/localcommit" bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" - "github.com/ActiveState/cli/pkg/platform/authentication" - "github.com/ActiveState/cli/pkg/platform/model" "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/project" ) type primeable interface { @@ -27,26 +24,15 @@ type primeable interface { primer.Analyticer primer.SvcModeler primer.Configurer + primer.Prompter } type Commit struct { - out output.Outputer - proj *project.Project - auth *authentication.Auth - analytics analytics.Dispatcher - svcModel *model.SvcModel - cfg *config.Instance + prime primeable } func New(p primeable) *Commit { - return &Commit{ - out: p.Output(), - proj: p.Project(), - auth: p.Auth(), - analytics: p.Analytics(), - svcModel: p.SvcModel(), - cfg: p.Config(), - } + return &Commit{p} } var ErrNoChanges = errors.New("buildscript has no changes") @@ -64,36 +50,53 @@ func rationalizeError(err *error) { "Your buildscript contains no new changes. No commit necessary.", ), errs.SetInput()) - case errs.Matches(*err, buildscript_runbit.ErrBuildscriptNotExist): + case errors.Is(*err, buildscript_runbit.ErrBuildscriptNotExist): *err = errs.WrapUserFacing(*err, locale.T("err_buildscript_not_exist")) // We communicate buildplanner errors verbatim as the intend is that these are curated by the buildplanner case errors.As(*err, &buildPlannerErr): *err = errs.WrapUserFacing(*err, - buildPlannerErr.LocalizedError(), + buildPlannerErr.LocaleError(), errs.SetIf(buildPlannerErr.InputError(), errs.SetInput())) + + case errors.As(*err, &invalidDepsValueType{}): + *err = errs.WrapUserFacing(*err, locale.T("err_commit_invalid_deps_value_type"), errs.SetInput()) + + case errors.As(*err, &invalidDepValueType{}): + *err = errs.WrapUserFacing(*err, locale.T("err_commit_invalid_dep_value_type"), errs.SetInput()) + } } func (c *Commit) Run() (rerr error) { defer rationalizeError(&rerr) - if c.proj == nil { + proj := c.prime.Project() + if proj == nil { return rationalize.ErrNoProject } + out := c.prime.Output() + out.Notice(locale.Tr("operating_message", proj.NamespaceString(), proj.Dir())) + // Get buildscript.as representation - script, err := buildscript_runbit.ScriptFromProject(c.proj) + script, err := buildscript_runbit.ScriptFromProject(proj) if err != nil { return errs.Wrap(err, "Could not get local build script") } + for _, fc := range script.FunctionCalls("ingredient") { + if err := NewIngredientCall(c.prime, script, fc).Resolve(); err != nil { + return errs.Wrap(err, "Could not resolve ingredient") + } + } + // Get equivalent build script for current state of the project - localCommitID, err := localcommit.Get(c.proj.Dir()) + localCommitID, err := localcommit.Get(proj.Dir()) if err != nil { return errs.Wrap(err, "Unable to get local commit ID") } - bp := buildplanner.NewBuildPlannerModel(c.auth) + bp := buildplanner.NewBuildPlannerModel(c.prime.Auth(), c.prime.SvcModel()) remoteScript, err := bp.GetBuildScript(localCommitID.String()) if err != nil { return errs.Wrap(err, "Could not get remote build expr and time for provided commit") @@ -109,16 +112,16 @@ func (c *Commit) Run() (rerr error) { return ErrNoChanges } - pg := output.StartSpinner(c.out, locale.T("progress_commit"), constants.TerminalAnimationInterval) + pg := output.StartSpinner(out, locale.T("progress_commit"), constants.TerminalAnimationInterval) defer func() { if pg != nil { - pg.Stop(locale.T("progress_fail") + "\n") + pg.Stop(locale.T("progress_fail")) } }() - stagedCommitID, err := bp.StageCommit(buildplanner.StageCommitParams{ - Owner: c.proj.Owner(), - Project: c.proj.Name(), + stagedCommit, err := bp.StageCommit(buildplanner.StageCommitParams{ + Owner: proj.Owner(), + Project: proj.Name(), ParentCommit: localCommitID.String(), Script: script, }) @@ -127,35 +130,66 @@ func (c *Commit) Run() (rerr error) { } // Update local commit ID - if err := localcommit.Set(c.proj.Dir(), stagedCommitID.String()); err != nil { + if err := localcommit.Set(proj.Dir(), stagedCommit.CommitID.String()); err != nil { return errs.Wrap(err, "Could not set local commit ID") } // Update our local build expression to match the committed one. This allows our API a way to ensure forward compatibility. - newScript, err := bp.GetBuildScript(stagedCommitID.String()) + newScript, err := bp.GetBuildScript(stagedCommit.CommitID.String()) if err != nil { return errs.Wrap(err, "Unable to get the remote build script") } - if err := buildscript_runbit.Update(c.proj, newScript); err != nil { + if err := buildscript_runbit.Update(proj, newScript); err != nil { return errs.Wrap(err, "Could not update local build script") } - pg.Stop(locale.T("progress_success") + "\n") + pg.Stop(locale.T("progress_success")) pg = nil - c.out.Print(output.Prepare( + pgSolve := output.StartSpinner(out, locale.T("progress_solve"), constants.TerminalAnimationInterval) + defer func() { + if pgSolve != nil { + pgSolve.Stop(locale.T("progress_fail")) + } + }() + + // Solve runtime + rtCommit, err := bp.FetchCommit(stagedCommit.CommitID, proj.Owner(), proj.Name(), nil) + if err != nil { + return errs.Wrap(err, "Could not fetch staged commit") + } + + // Get old buildplan. + oldCommit, err := bp.FetchCommitNoPoll(localCommitID, proj.Owner(), proj.Name(), nil) + if err != nil { + return errs.Wrap(err, "Failed to fetch old commit") + } + + pgSolve.Stop(locale.T("progress_success")) + pgSolve = nil + + // Output dependency list. + dependencies.OutputChangeSummary(out, rtCommit.BuildPlan(), oldCommit.BuildPlan()) + + // Report CVEs. + if err := cves.NewCveReport(c.prime).Report(rtCommit.BuildPlan(), oldCommit.BuildPlan()); err != nil { + return errs.Wrap(err, "Could not report CVEs") + } + + out.Notice("") // blank line + out.Print(output.Prepare( locale.Tl( "commit_success", - "", stagedCommitID.String(), c.proj.NamespaceString(), + "", stagedCommit.CommitID.String(), proj.NamespaceString(), ), &struct { Namespace string `json:"namespace"` Path string `json:"path"` CommitID string `json:"commit_id"` }{ - c.proj.NamespaceString(), - c.proj.Dir(), - stagedCommitID.String(), + proj.NamespaceString(), + proj.Dir(), + stagedCommit.CommitID.String(), }, )) diff --git a/internal/runners/commit/ingredientcall.go b/internal/runners/commit/ingredientcall.go new file mode 100644 index 0000000000..c9eb4a6b37 --- /dev/null +++ b/internal/runners/commit/ingredientcall.go @@ -0,0 +1,379 @@ +package commit + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "strings" + "time" + + "github.com/ActiveState/cli/internal/archiver" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/graph" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/pkg/buildscript" + "github.com/ActiveState/cli/pkg/platform/api/graphql/request" + "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/platform/model/buildplanner" + "github.com/brunoga/deep" + "github.com/cespare/xxhash" + "github.com/gowebpki/jcs" +) + +const namespaceSuffixFiles = "files" +const cacheKeyFiles = "buildscript-file-%s" + +type invalidDepsValueType struct{ error } + +type invalidDepValueType struct{ error } + +type invalidFeaturesValueType struct{ error } + +type invalidFeatureValue struct{ error } + +const keyHash = "hash_readonly" +const keyIngredientVersionID = "ingredient_version_id_readonly" +const keyRevision = "revision_readonly" + +var readonlyKeys = []string{keyHash, keyIngredientVersionID, keyRevision} + +// IngredientCall is used to evaluate ingredient() function calls and publishes the ingredient in question if it is not +// already published. +type IngredientCall struct { + prime primeable + script *buildscript.BuildScript + funcCall *buildscript.FuncCall + ns model.Namespace +} + +func NewIngredientCall( + prime primeable, + script *buildscript.BuildScript, + funcCall *buildscript.FuncCall, +) *IngredientCall { + return &IngredientCall{ + prime: prime, + script: script, + funcCall: funcCall, + ns: model.NewNamespaceOrg(prime.Project().Owner(), namespaceSuffixFiles), + } +} + +// Resolve will check if the ingredient call refers to an existing ingredient, and if not will create it and update +// the buildscript accordingly. +func (i *IngredientCall) Resolve() error { + hash, hashedFiles, err := i.calculateHash() + if err != nil { + return errs.Wrap(err, "Could not hash ingredient call") + } + + latest, err := model.FetchLatestRevisionTimeStamp(nil) + if err != nil { + return errs.Wrap(err, "Unable to determine latest revision time") + } + resolvedIngredient, err := i.getCached(hash, latest) + if err != nil { + return errs.Wrap(err, "Could not check if ingredient call is cached") + } + if resolvedIngredient == nil { + resolvedIngredient, err = i.createIngredient(hash, hashedFiles) + if err != nil { + return errs.Wrap(err, "Could not create ingredient") + } + // Bump timestamp, because otherwise the new ingredient will be unusable + i.script.SetAtTime(latest, true) + } else { + // Update atTime according to ingredient. This MAY not actually be an update if the resolvedIngredient has + // the same atTime as the stored buildscript. + i.script.SetAtTime(resolvedIngredient.AtTime, true) + } + + // Add/update arguments on the buildscript ingredient function call + // ingredient_version_id and revision are required for the server to lookup the ingredient without violating + // reproducibility. + // hash is used to uniquely identify the ingredient and is used to cache the ingredient, it is only evaluated on the client. + i.funcCall.SetArgument(keyIngredientVersionID, buildscript.Value(resolvedIngredient.VersionID)) + i.funcCall.SetArgument(keyRevision, buildscript.Value(resolvedIngredient.Revision)) + i.funcCall.SetArgument(keyHash, buildscript.Value(hash)) + i.setCached(hash, resolvedIngredient) + + return nil +} + +func (i *IngredientCall) createIngredient(hash string, hashedFiles []*graph.GlobFileResult) (*resolvedIngredientData, error) { + // Create tar.gz with all the references files for this ingredient + files := []string{} + for _, f := range hashedFiles { + files = append(files, f.Path) + } + + tmpFile := fileutils.TempFilePath("", fmt.Sprintf("bs-hash-%s.tar.gz", hash)) + if err := archiver.CreateTgz(tmpFile, i.prime.Project().Dir(), archiver.FilesWithCommonParent(files...)); err != nil { + return nil, errs.Wrap(err, "Could not create tar.gz") + } + defer os.Remove(tmpFile) + + // Parse buildscript dependencies + deps, err := i.resolveDependencies() + if err != nil { + return nil, errs.Wrap(err, "Could not resolve dependencies") + } + + // Parse buildscript features + features, err := i.resolveFeatures() + if err != nil { + return nil, errs.Wrap(err, "Could not resolve features") + } + + // Publish ingredient + bpm := buildplanner.NewBuildPlannerModel(i.prime.Auth(), i.prime.SvcModel()) + pr, err := bpm.Publish(request.PublishVariables{ + Name: hash, + Description: "buildscript ingredient", + Namespace: i.ns.String(), + Version: hash, + Dependencies: deps, + Features: features, + }, tmpFile) + if err != nil { + return nil, errs.Wrap(err, "Could not create publish request") + } + + latest, err := model.FetchLatestRevisionTimeStamp(nil) + if err != nil { + return nil, errs.Wrap(err, "Unable to determine latest revision time") + } + + return &resolvedIngredientData{ + VersionID: pr.IngredientVersionID, + Revision: pr.Revision, + AtTime: latest, + }, nil +} + +// calculateHash will calculate a hash based on the files references in the ingredient as well as the ingredient +// rule itself. The ingredient is considered dirty when either the files or the rule itself has changed. +func (i *IngredientCall) calculateHash() (string, []*graph.GlobFileResult, error) { + src := i.funcCall.Argument("src") + patterns, ok := src.([]string) + if !ok { + return "", nil, errors.New("src argument is not a []string") + } + hashed, err := i.prime.SvcModel().HashGlobs(i.prime.Project().Dir(), patterns) + if err != nil { + return "", nil, errs.Wrap(err, "Could not hash globs") + } + + hash, err := hashFuncCall(i.funcCall, hashed.Hash) + if err != nil { + return "", nil, errs.Wrap(err, "Could not hash function call") + } + + return hash, hashed.Files, nil +} + +// hashFuncCall will calculate the individual hash of the ingredient function call itself. +// The hash argument is excluded from this calculation. +func hashFuncCall(fc *buildscript.FuncCall, seed string) (string, error) { + // We clone the function call here because the (potentially old) hash itself should not be used to calculate the hash + // and unsetting it should not propagate beyond the context of this function. + fcc, err := deep.Copy(fc) + if err != nil { + return "", errs.Wrap(err, "Could not copy function call") + } + for _, k := range readonlyKeys { + fcc.UnsetArgument(k) + } + + fcb, err := json.Marshal(fcc) + if err != nil { + return "", errs.Wrap(err, "Could not marshal function call") + } + // Go's JSON implementation does not produce canonical output, so we need to utilize additional tooling to ensure + // the hash we create is based on canonical data. + if fcb, err = jcs.Transform(fcb); err != nil { + return "", errs.Wrap(err, "Could not transform json blob to canonical json") + } + hasher := xxhash.New() + hasher.Write([]byte(seed)) + hasher.Write(fcb) + hash := fmt.Sprintf("%016x", hasher.Sum64()) + return hash, nil +} + +// resolveDependencies iterates over the different dependency arguments the ingredient function supports and resolves +// them into the appropriate types used by our models. +func (i *IngredientCall) resolveDependencies() ([]request.PublishVariableDep, error) { + result := []request.PublishVariableDep{} + for key, typ := range map[string]request.DependencyType{ + "runtime_deps": request.DependencyTypeRuntime, + "build_deps": request.DependencyTypeBuild, + "test_deps": request.DependencyTypeTest, + } { + deps, err := i.resolveDependenciesByKey(key, typ) + if err != nil { + return nil, errs.Wrap(err, "Could not resolve %s", key) + } + result = append(result, deps...) + } + + return result, nil +} + +// resolveDependenciesByKey turns ingredient dependencies into the appropriate types used by our models +func (i *IngredientCall) resolveDependenciesByKey(key string, typ request.DependencyType) ([]request.PublishVariableDep, error) { + deps := []request.PublishVariableDep{} + bsDeps := i.funcCall.Argument(key) + if bsDeps == nil { + return deps, nil + } + + bsDepSlice, ok := bsDeps.([]any) + if !ok { + return nil, invalidDepsValueType{fmt.Errorf("deps argument is not a []any: %v (%T)", bsDeps, bsDeps)} + } + + for _, dep := range bsDepSlice { + req, ok := dep.(buildscript.DependencyRequirement) + if !ok { + return nil, invalidDepValueType{fmt.Errorf("dep argument is not a Req(): %v (%T)", dep, dep)} + } + deps = append(deps, request.PublishVariableDep{ + request.Dependency{ + Name: req.Name, + Namespace: req.Namespace, + VersionRequirements: model.VersionRequirementsToString(req.VersionRequirement, true), + Type: typ, + }, + []request.Dependency{}, + }) + } + + return deps, nil +} + +// resolveFeatures turns ingredient features into the appropriate types used by our models +func (i *IngredientCall) resolveFeatures() ([]request.PublishVariableFeature, error) { + features := []request.PublishVariableFeature{} + bsFeatures := i.funcCall.Argument("features") + if bsFeatures == nil { + return features, nil + } + + bsFeaturesSlice, ok := bsFeatures.([]string) + if !ok { + return nil, invalidFeaturesValueType{fmt.Errorf("features argument is not an []string: %v (%T)", bsFeatures, bsFeatures)} + } + + for _, feature := range bsFeaturesSlice { + resolvedFeature, err := parseFeature(feature) + if err != nil { + return nil, errs.Wrap(err, "Could not parse feature") + } + features = append(features, resolvedFeature) + } + + return features, nil +} + +// parseFeature will parse a feature string into a request.PublishVariableFeature +// features need to be formatted as `namespace/name@version` +func parseFeature(f string) (request.PublishVariableFeature, error) { + p := request.PublishVariableFeature{} + if !strings.Contains(f, "/") { + return p, &invalidFeatureValue{fmt.Errorf("feature '%s' is missing a namespace, it should be formatted as namespace/name@version", f)} + } + if !strings.Contains(f, "@") { + return p, &invalidFeatureValue{fmt.Errorf("feature '%s' is missing a version, it should be formatted as namespace/name@version", f)} + } + v := strings.Split(f, "@") + p.Version = strings.TrimSpace(v[1]) + v = strings.Split(v[0], "/") + p.Namespace = strings.TrimSpace(strings.Join(v[0:len(v)-1], "/")) + p.Name = strings.TrimSpace(v[len(v)-1]) + return p, nil +} + +type resolvedIngredientData struct { + VersionID string + Revision int + AtTime time.Time +} + +// MarshalJSON works around go's json.Marshal not allowing you to specify the format of time fields +func (r resolvedIngredientData) MarshalJSON() ([]byte, error) { + type Alias resolvedIngredientData + return json.Marshal(&struct { + Alias + AtTime string + }{ + Alias: Alias(r), + AtTime: r.AtTime.Format(time.RFC3339), + }) +} + +// getCached checks against our local cache to see if we've already handled this file hash, and if no local cache +// exists checks against the platform ingredient API. +func (i *IngredientCall) getCached(hash string, latest time.Time) (*resolvedIngredientData, error) { + cacheValue, err := i.prime.SvcModel().GetCache(fmt.Sprintf(cacheKeyFiles, hash)) + if err != nil { + return nil, errs.Wrap(err, "Could not get build script cache") + } + if cacheValue != "" { + resolvedIngredient := &resolvedIngredientData{} + err := json.Unmarshal([]byte(cacheValue), resolvedIngredient) + if err != nil { + return nil, errs.Wrap(err, "Could not unmarshal cached ingredient") + } + // Ingredient already exists + return resolvedIngredient, nil + } + + // Check against API to see if we've already published this file hash + ingredients, err := model.SearchIngredientsStrict(i.ns.String(), hash, true, false, i.script.AtTime(), i.prime.Auth()) + if err != nil && !errors.As(err, ptr.To(&model.ErrSearch404{})) { + return nil, errs.Wrap(err, "Could not search ingredients") + } + if len(ingredients) > 0 { + // Ingredient already exists + return &resolvedIngredientData{ + VersionID: string(*ingredients[0].LatestVersion.IngredientVersionID), + Revision: int(*ingredients[0].LatestVersion.Revision), + AtTime: ptr.From(i.script.AtTime(), latest), // Fall back to latest if script has no AtTime + }, nil + } + + // Check again if the hash exists at the latest timestamp, because even if the ingredient exists, it might not exist + // at the atTime of the buildscript. In which case the buildscript will need to bump its timestamp without touching + // the ingredient. + ingredients, err = model.SearchIngredientsStrict(i.ns.String(), hash, true, false, &latest, i.prime.Auth()) + if err != nil && !errors.As(err, ptr.To(&model.ErrSearch404{})) { + return nil, errs.Wrap(err, "Could not search ingredients") + } + if len(ingredients) > 0 { + // Ingredient already exists + return &resolvedIngredientData{ + VersionID: string(*ingredients[0].LatestVersion.IngredientVersionID), + Revision: int(*ingredients[0].LatestVersion.Revision), + AtTime: latest, + }, nil + } + + return nil, nil // If we made it this far it means we did not find any existing cache entry; so it's dirty +} + +// Update our local cache saying we've handled this hash, allowing for faster cache checks than using the platform api +func (i *IngredientCall) setCached(hash string, resolvedIngredient *resolvedIngredientData) { + b, err := json.Marshal(resolvedIngredient) + if err != nil { + // Shouldn't happen, but at least we're logging it if it does + logging.Error("Could not marshal cached ingredient: %s", errs.JoinMessage(err)) + } + err = i.prime.SvcModel().SetCache(fmt.Sprintf(cacheKeyFiles, hash), string(b), time.Hour*24*7) + if err != nil { + logging.Error("Could not set build script cache: %s", errs.JoinMessage(err)) + } +} diff --git a/internal/runners/commit/ingredientcall_test.go b/internal/runners/commit/ingredientcall_test.go new file mode 100644 index 0000000000..bf4d70bf19 --- /dev/null +++ b/internal/runners/commit/ingredientcall_test.go @@ -0,0 +1,217 @@ +package commit + +import ( + "sort" + "testing" + + "github.com/ActiveState/cli/pkg/buildscript" + "github.com/ActiveState/cli/pkg/platform/api/graphql/request" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const simpleScript = ` +main = ingredient( + src = ["*/**.py", "pyproject.toml"], + hash = "", + runtime_deps = [ + Req(name="python", namespace="language", version=Eq(value="3.7.10")) + ] +) +` + +const simpleAlteredScript = ` +main = ingredient( + src = ["*/**.py", "pyproject.toml"], + hash = "", + runtime_deps = [ + Req(name="python", namespace="language", version=Eq(value="3.7.10")), + Req(name="python-module-builder", namespace="builder", version=Gt(value="0")), + ] +) +` + +const depTypesScript = ` +main = ingredient( + src = ["*/**.py", "pyproject.toml"], + hash = "", + runtime_deps = [ + Req(name="runtimedep", namespace="language", version=Eq(value="1.0")) + ], + build_deps = [ + Req(name="builddep", namespace="language", version=Eq(value="2.0")) + ], + test_deps = [ + Req(name="testdep", namespace="language", version=Eq(value="3.0")) + ], +) +` + +const invalidDepsScript = ` +main = ingredient( + runtime_deps = "I should be a slice" +) +` + +const invalidDepScript = ` +main = ingredient( + runtime_deps = [ + Req(name="runtimedep", namespace="language", version=Eq(value="1.0")), + "I should be a Req" + ] +) +` + +func Test_hashFuncCall(t *testing.T) { + type args struct { + script string + seed string + } + tests := []struct { + name string + args args + want string + }{ + { + "Simple", + args{ + script: simpleScript, + seed: "", + }, + // If this fails you can update it to actual if you are sure your logic changes would result in the hash being different + "6395ae666f293cd2", + }, + { + "Simple Altered", + args{ + script: simpleAlteredScript, + seed: "", + }, + // If this fails you can update it to actual if you are sure your logic changes would result in the hash being different + "b9a486d874a27bd5", + }, + { + "Simple With Seed", + args{ + script: simpleScript, + seed: "seed", + }, + // If this fails you can update it to actual if you are sure your logic changes would result in the hash being different + "5cca922938bd9261", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bs, err := buildscript.Unmarshal([]byte(tt.args.script)) + require.NoError(t, err) + fc := bs.FunctionCalls("ingredient")[0] + hashBefore := fc.Argument("hash").(string) + got, err := hashFuncCall(fc, tt.args.seed) + if err != nil { + t.Errorf("hashFuncCall() error = %v", err) + return + } + hashAfter := fc.Argument("hash").(string) + if got != tt.want { + t.Errorf("hashFuncCall() got = %v, want %v", got, tt.want) + } + assert.Equal(t, hashBefore, hashAfter) // calculating the hash should not affect the hash + }) + } +} + +func TestIngredientCall_resolveDependencies(t *testing.T) { + tests := []struct { + name string + script string + want []request.PublishVariableDep + wantErr assert.ErrorAssertionFunc + }{ + { + "Simple", + simpleScript, + []request.PublishVariableDep{ + { + Dependency: request.Dependency{ + Name: "python", + Namespace: "language", + VersionRequirements: "==3.7.10", + Type: request.DependencyTypeRuntime, + }, + Conditions: []request.Dependency{}, + }, + }, + assert.NoError, + }, + { + "All Types", + depTypesScript, + []request.PublishVariableDep{ + { + Dependency: request.Dependency{ + Name: "runtimedep", + Namespace: "language", + VersionRequirements: "==1.0", + Type: request.DependencyTypeRuntime, + }, + Conditions: []request.Dependency{}, + }, + { + Dependency: request.Dependency{ + Name: "builddep", + Namespace: "language", + VersionRequirements: "==2.0", + Type: request.DependencyTypeBuild, + }, + Conditions: []request.Dependency{}, + }, + { + Dependency: request.Dependency{ + Name: "testdep", + Namespace: "language", + VersionRequirements: "==3.0", + Type: request.DependencyTypeTest, + }, + Conditions: []request.Dependency{}, + }, + }, + assert.NoError, + }, + { + "Invalid Deps", + invalidDepsScript, + nil, + func(t assert.TestingT, err error, _ ...interface{}) bool { + assert.Error(t, err) + return assert.ErrorAs(t, err, &invalidDepsValueType{}) + }, + }, + { + "Invalid Dep", + invalidDepScript, + nil, + func(t assert.TestingT, err error, _ ...interface{}) bool { + return assert.ErrorAs(t, err, &invalidDepValueType{}) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bs, err := buildscript.Unmarshal([]byte(tt.script)) + require.NoError(t, err) + fc := bs.FunctionCalls("ingredient")[0] + i := &IngredientCall{script: bs, funcCall: fc} + got, err := i.resolveDependencies() + if !tt.wantErr(t, err, "") { + return + } + sort.Slice(tt.want, func(i, j int) bool { + return tt.want[i].Name < tt.want[j].Name + }) + sort.Slice(got, func(i, j int) bool { + return got[i].Name < got[j].Name + }) + assert.Equalf(t, tt.want, got, "resolveDependencies()") + }) + } +} diff --git a/internal/runners/config/config.go b/internal/runners/config/config.go index 9734b6553d..689b40e7ef 100644 --- a/internal/runners/config/config.go +++ b/internal/runners/config/config.go @@ -1,14 +1,19 @@ package config import ( + "fmt" + "strings" + "github.com/ActiveState/cli/internal/config" + "github.com/ActiveState/cli/internal/locale" + mediator "github.com/ActiveState/cli/internal/mediators/config" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/table" ) -type Config struct { - out output.Outputer - cfg *config.Instance +type List struct { + prime primeable } type primeable interface { @@ -18,13 +23,110 @@ type primeable interface { primer.Analyticer } -func NewConfig(prime primeable) (*Config, error) { - return &Config{ - out: prime.Output(), - cfg: prime.Config(), +func NewList(prime primeable) (*List, error) { + return &List{ + prime: prime, }, nil } -func (c *Config) Run(usageFunc func() error) error { - return usageFunc() +type structuredConfigData struct { + Key string `json:"key"` + Value interface{} `json:"value"` + Default interface{} `json:"default"` + opt mediator.Option +} + +func (c *List) Run() error { + registered := mediator.Registered() + + cfg := c.prime.Config() + out := c.prime.Output() + + var data []structuredConfigData + for _, opt := range registered { + configuredValue := cfg.Get(opt.Name) + data = append(data, structuredConfigData{ + Key: opt.Name, + Value: configuredValue, + Default: mediator.GetDefault(opt), + opt: opt, + }) + } + + if out.Type().IsStructured() { + out.Print(output.Structured(data)) + } else { + if err := c.renderUserFacing(data); err != nil { + return err + } + } + + return nil +} + +func (c *List) renderUserFacing(configData []structuredConfigData) error { + cfg := c.prime.Config() + out := c.prime.Output() + + tbl := table.New(locale.Ts("key", "value", "default")) + tbl.HideDash = true + for _, config := range configData { + tbl.AddRow([]string{ + fmt.Sprintf("[CYAN]%s[/RESET]", config.Key), + renderConfigValue(cfg, config.opt), + fmt.Sprintf("[DISABLED]%s[/RESET]", formatValue(config.opt, config.Default)), + }) + } + + out.Print(tbl.Render()) + out.Notice("") + out.Notice(locale.T("config_get_help")) + out.Notice(locale.T("config_set_help")) + + return nil +} + +func renderConfigValue(cfg *config.Instance, opt mediator.Option) string { + configured := cfg.Get(opt.Name) + var tags []string + if opt.Type == mediator.Bool { + if configured == true { + tags = append(tags, "[GREEN]") + } else { + tags = append(tags, "[RED]") + } + } + + value := formatValue(opt, configured) + if cfg.IsSet(opt.Name) { + tags = append(tags, "[BOLD]") + value = value + "*" + } + + if len(tags) > 0 { + return fmt.Sprintf("%s%s[/RESET]", strings.Join(tags, ""), value) + } + + return value +} + +func formatValue(opt mediator.Option, value interface{}) string { + switch opt.Type { + case mediator.Enum, mediator.String: + return formatString(fmt.Sprintf("%v", value)) + default: + return fmt.Sprintf("%v", value) + } +} + +func formatString(value string) string { + if value == "" { + return "\"\"" + } + + if len(value) > 100 { + value = value[:100] + "..." + } + + return fmt.Sprintf("\"%s\"", value) } diff --git a/internal/runners/config/get.go b/internal/runners/config/get.go index af354dc447..e6def8ebcb 100644 --- a/internal/runners/config/get.go +++ b/internal/runners/config/get.go @@ -30,7 +30,7 @@ func (g *Get) Run(params GetParams) error { value, err := configMediator.GetOption(key).GetEvent(value) if err != nil { - return locale.WrapError(err, "err_config_get_event", "Could not retrieve config value, if this continues to happen please contact support.") + return locale.WrapError(err, "err_config_get_event", "Could not retrieve config value. If this continues to happen please contact support.") } g.out.Print(output.Prepare( diff --git a/internal/runners/config/set.go b/internal/runners/config/set.go index dca1705333..9cf451d26a 100644 --- a/internal/runners/config/set.go +++ b/internal/runners/config/set.go @@ -4,6 +4,9 @@ import ( "context" "fmt" "strconv" + "strings" + + "github.com/thoas/go-funk" "github.com/ActiveState/cli/internal/analytics" "github.com/ActiveState/cli/internal/analytics/constants" @@ -52,13 +55,24 @@ func (s *Set) Run(params SetParams) error { if err != nil { return locale.WrapInputError(err, "Invalid integer value") } + case configMediator.Enum: + enums, ok := option.Default.(*configMediator.Enums) + if !ok { + return errs.New("Programming error: config key '%s' was registered as an enum, but the default was not an enum", params.Key.String()) + } + if !funk.Contains(enums.Options, params.Value) { + return locale.NewInputError( + "err_config_set_enum_invalid_value", "Invalid value '{{.V0}}': expected one of: {{.V1}}", + params.Value, strings.Join(enums.Options, ", ")) + } + value = params.Value default: value = params.Value } value, err := option.SetEvent(value) if err != nil { - return locale.WrapError(err, "err_config_set_event", "Could not store config value, if this continues to happen please contact support.") + return locale.WrapError(err, "err_config_set_event", "Could not store config value. If this continues to happen please contact support.") } key := params.Key.String() diff --git a/internal/runners/cve/cve.go b/internal/runners/cve/cve.go index 3c40344f3a..20f6e51116 100644 --- a/internal/runners/cve/cve.go +++ b/internal/runners/cve/cve.go @@ -1,6 +1,7 @@ package cve import ( + "errors" "fmt" "sort" "strconv" @@ -71,7 +72,8 @@ func (r *Cve) Run(params *Params) error { vulnerabilities, err := r.fetchVulnerabilities(*params.Namespace) if err != nil { - if errs.Matches(err, &model.ErrProjectNotFound{}) { + var errProjectNotFound *model.ErrProjectNotFound + if errors.As(err, &errProjectNotFound) { return locale.WrapExternalError(err, "cve_mediator_resp_not_found", "That project was not found") } return locale.WrapError(err, "cve_mediator_resp", "Failed to retrieve vulnerability information") @@ -192,9 +194,9 @@ func (rd *cveOutput) MarshalOutput(format output.Format) interface{} { }) for i, d := range ap.Details { - bar := "├─" + bar := output.TreeMid if i == len(ap.Details)-1 { - bar = "└─" + bar = output.TreeEnd } severity := d.Severity if severity == "CRITICAL" { diff --git a/internal/runners/deploy/deploy.go b/internal/runners/deploy/deploy.go index 01c9006687..b69ac6587b 100644 --- a/internal/runners/deploy/deploy.go +++ b/internal/runners/deploy/deploy.go @@ -7,12 +7,13 @@ import ( rt "runtime" "strings" - rtrunbit "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/pkg/runtime_helpers" "github.com/go-openapi/strfmt" "github.com/ActiveState/cli/internal/analytics" "github.com/ActiveState/cli/internal/assets" "github.com/ActiveState/cli/internal/config" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/locale" @@ -22,13 +23,14 @@ import ( "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/rtutils" + "github.com/ActiveState/cli/internal/runbits/checkout" + runtime_runbit "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/progress" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/subshell/sscommon" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" ) @@ -48,6 +50,10 @@ func RequiresAdministratorRights(step Step, userScope bool) bool { } type Deploy struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 auth *authentication.Auth output output.Outputer subshell subshell.SubShell @@ -64,10 +70,12 @@ type primeable interface { primer.Configurer primer.Analyticer primer.SvcModeler + primer.Projecter } func NewDeploy(step Step, prime primeable) *Deploy { return &Deploy{ + prime, prime.Auth(), prime.Output(), prime.Subshell(), @@ -94,31 +102,36 @@ func (d *Deploy) Run(params *Params) error { return locale.WrapError(err, "err_deploy_commitid", "Could not grab commit ID for project: {{.V0}}.", params.Namespace.String()) } - rtTarget := target.NewCustomTarget(params.Namespace.Owner, params.Namespace.Project, commitID, params.Path, target.TriggerDeploy) /* TODO: handle empty path */ + if params.Path == "" { + params.Path, err = os.Getwd() + if err != nil { + return errs.Wrap(err, "Could not get current working directory") + } + } logging.Debug("runSteps: %s", d.step.String()) if d.step == UnsetStep || d.step == InstallStep { logging.Debug("Running install step") - if err := d.install(rtTarget); err != nil { + if err := d.install(params, commitID); err != nil { return err } } if d.step == UnsetStep || d.step == ConfigureStep { logging.Debug("Running configure step") - if err := d.configure(params.Namespace, rtTarget, params.UserScope); err != nil { + if err := d.configure(params); err != nil { return err } } if d.step == UnsetStep || d.step == SymlinkStep { logging.Debug("Running symlink step") - if err := d.symlink(rtTarget, params.Force); err != nil { + if err := d.symlink(params); err != nil { return err } } if d.step == UnsetStep || d.step == ReportStep { logging.Debug("Running report step") - if err := d.report(rtTarget); err != nil { + if err := d.report(params); err != nil { return err } } @@ -137,7 +150,7 @@ func (d *Deploy) commitID(namespace project.Namespaced) (strfmt.UUID, error) { if branch.CommitID == nil { return "", locale.NewInputError( "err_deploy_no_commits", - "The project '{{.V0}}' does not have any packages configured, please add add some packages first.", namespace.String()) + "The project '{{.V0}}' does not have any packages configured. Please add add some packages first.", namespace.String()) } commitID = branch.CommitID @@ -150,37 +163,37 @@ func (d *Deploy) commitID(namespace project.Namespaced) (strfmt.UUID, error) { return *commitID, nil } -func (d *Deploy) install(rtTarget setup.Targeter) (rerr error) { +func (d *Deploy) install(params *Params, commitID strfmt.UUID) (rerr error) { d.output.Notice(output.Title(locale.T("deploy_install"))) - rti, err := runtime.New(rtTarget, d.analytics, d.svcModel, d.auth, d.cfg, d.output) - if err != nil { - return locale.WrapError(err, "deploy_runtime_err", "Could not initialize runtime") + if err := checkout.CreateProjectFiles( + params.Path, params.Path, params.Namespace.Owner, params.Namespace.Project, + constants.DefaultBranchName, commitID.String(), "", + ); err != nil { + return errs.Wrap(err, "Could not create project files") } - if !rti.NeedsUpdate() { - d.output.Notice(locale.Tl("deploy_already_installed", "Already installed")) - return nil + + proj, err := project.FromPath(params.Path) + if err != nil { + return locale.WrapError(err, "err_project_frompath") } + d.prime.SetProject(proj) - pg := rtrunbit.NewRuntimeProgressIndicator(d.output) + pg := progress.NewRuntimeProgressIndicator(d.output) defer rtutils.Closer(pg.Close, &rerr) - if err := rti.SolveAndUpdate(pg); err != nil { - return locale.WrapError(err, "deploy_install_failed", "Installation failed.") - } - // Todo Remove with https://www.pivotaltracker.com/story/show/178161240 - // call rti.Environ as this completes the runtime activation cycle: - // It ensures that the analytics event for failure / success are sent - _, _ = rti.Env(false, false) + if _, err := runtime_runbit.Update(d.prime, trigger.TriggerDeploy, runtime_runbit.WithTargetDir(params.Path), runtime_runbit.WithIgnoreAsync()); err != nil { + return locale.WrapError(err, "err_deploy_runtime_err", "Could not initialize runtime") + } if rt.GOOS == "windows" { contents, err := assets.ReadFileBytes("scripts/setenv.bat") if err != nil { return err } - err = fileutils.WriteFile(filepath.Join(rtTarget.Dir(), "setenv.bat"), contents) + err = fileutils.WriteFile(filepath.Join(params.Path, "setenv.bat"), contents) if err != nil { - return locale.WrapError(err, "err_deploy_write_setenv", "Could not create setenv batch scriptfile at path: %s", rtTarget.Dir()) + return locale.WrapError(err, "err_deploy_write_setenv", "Could not create setenv batch scriptfile at path: %s", params.Path) } } @@ -188,36 +201,39 @@ func (d *Deploy) install(rtTarget setup.Targeter) (rerr error) { return nil } -func (d *Deploy) configure(namespace project.Namespaced, rtTarget setup.Targeter, userScope bool) error { - rti, err := runtime.New(rtTarget, d.analytics, d.svcModel, d.auth, d.cfg, d.output) +func (d *Deploy) configure(params *Params) error { + proj, err := project.FromPath(params.Path) if err != nil { - return locale.WrapError(err, "deploy_runtime_err", "Could not initialize runtime") - } - if rti.NeedsUpdate() { - return locale.NewInputError("err_deploy_run_install") + return locale.WrapInputError(err, "err_deploy_run_install") } - env, err := rti.Env(false, false) + rti, err := runtime_helpers.FromProject(proj) if err != nil { - return err + return locale.WrapError(err, "deploy_runtime_err", "Could not initialize runtime") + } + + if !rti.HasCache() { + return locale.NewInputError("err_deploy_run_install") } d.output.Notice(output.Title(locale.Tr("deploy_configure_shell", d.subshell.Shell()))) + env := rti.Env(false).Variables + // Configure available shells - err = subshell.ConfigureAvailableShells(d.subshell, d.cfg, env, sscommon.DeployID, userScope) + err = subshell.ConfigureAvailableShells(d.subshell, d.cfg, env, sscommon.DeployID, params.UserScope) if err != nil { return locale.WrapError(err, "err_deploy_subshell_write", "Could not write environment information to your shell configuration.") } - binPath := filepath.Join(rtTarget.Dir(), "bin") + binPath := filepath.Join(rti.Path(), "bin") if err := fileutils.MkdirUnlessExists(binPath); err != nil { return locale.WrapError(err, "err_deploy_binpath", "Could not create bin directory.") } // Write global env file - d.output.Notice(fmt.Sprintf("Writing shell env file to %s\n", filepath.Join(rtTarget.Dir(), "bin"))) - err = d.subshell.SetupShellRcFile(binPath, env, &namespace, d.cfg) + d.output.Notice(fmt.Sprintf("Writing shell env file to %s\n", filepath.Join(rti.Path(), "bin"))) + err = d.subshell.SetupShellRcFile(binPath, env, ¶ms.Namespace, d.cfg) if err != nil { return locale.WrapError(err, "err_deploy_subshell_rc_file", "Could not create environment script.") } @@ -225,12 +241,18 @@ func (d *Deploy) configure(namespace project.Namespaced, rtTarget setup.Targeter return nil } -func (d *Deploy) symlink(rtTarget setup.Targeter, overwrite bool) error { - rti, err := runtime.New(rtTarget, d.analytics, d.svcModel, d.auth, d.cfg, d.output) +func (d *Deploy) symlink(params *Params) error { + proj, err := project.FromPath(params.Path) + if err != nil { + return locale.WrapInputError(err, "err_deploy_run_install") + } + + rti, err := runtime_helpers.FromProject(proj) if err != nil { return locale.WrapError(err, "deploy_runtime_err", "Could not initialize runtime") } - if rti.NeedsUpdate() { + + if !rti.HasCache() { return locale.NewInputError("err_deploy_run_install") } @@ -244,7 +266,7 @@ func (d *Deploy) symlink(rtTarget setup.Targeter, overwrite bool) error { } // Retrieve artifact binary directories - bins, err := rti.ExecutablePaths() + bins, err := osutils.ExecutablePaths(rti.Env(false).Variables) if err != nil { return locale.WrapError(err, "err_symlink_exes", "Could not detect executable paths") } @@ -257,12 +279,12 @@ func (d *Deploy) symlink(rtTarget setup.Targeter, overwrite bool) error { // Remove duplicate executables as per PATH and PATHEXT exes, err = osutils.UniqueExes(exes, os.Getenv("PATHEXT")) if err != nil { - return locale.WrapError(err, "err_unique_exes", "Could not detect unique executables, make sure your PATH and PATHEXT environment variables are properly configured.") + return locale.WrapError(err, "err_unique_exes", "Could not detect unique executables. Please make sure your PATH and PATHEXT environment variables are properly configured.") } if rt.GOOS != "windows" { // Symlink to PATH (eg. /usr/local/bin) - if err := symlinkWithTarget(overwrite, path, exes, d.output); err != nil { + if err := symlinkWithTarget(params.Force, path, exes, d.output); err != nil { return locale.WrapError(err, "err_symlink", "Could not create symlinks to {{.V0}}.", path) } } else { @@ -295,7 +317,7 @@ func symlinkWithTarget(overwrite bool, symlinkPath string, exePaths []string, ou if err := fileutils.MkdirUnlessExists(symlinkPath); err != nil { return locale.WrapExternalError( err, "err_deploy_mkdir", - "Could not create directory at {{.V0}}, make sure you have permissions to write to {{.V1}}.", symlinkPath, filepath.Dir(symlinkPath)) + "Could not create directory at {{.V0}}. Please make sure you have permissions to write to {{.V1}}.", symlinkPath, filepath.Dir(symlinkPath)) } for _, exePath := range exePaths { @@ -326,7 +348,7 @@ func symlinkWithTarget(overwrite bool, symlinkPath string, exePaths []string, ou if err := os.Remove(symlink); err != nil { return locale.WrapExternalError( err, "err_deploy_overwrite", - "Could not overwrite {{.V0}}, make sure you have permissions to write to this file.", symlink) + "Could not overwrite {{.V0}}. Please make sure you have permissions to write to this file.", symlink) } } @@ -343,19 +365,22 @@ type Report struct { Environment map[string]string } -func (d *Deploy) report(rtTarget setup.Targeter) error { - rti, err := runtime.New(rtTarget, d.analytics, d.svcModel, d.auth, d.cfg, d.output) +func (d *Deploy) report(params *Params) error { + proj, err := project.FromPath(params.Path) + if err != nil { + return locale.WrapInputError(err, "err_deploy_run_install") + } + + rti, err := runtime_helpers.FromProject(proj) if err != nil { return locale.WrapError(err, "deploy_runtime_err", "Could not initialize runtime") } - if rti.NeedsUpdate() { + + if !rti.HasCache() { return locale.NewInputError("err_deploy_run_install") } - env, err := rti.Env(false, false) - if err != nil { - return err - } + env := rti.Env(false).Variables var bins []string if path, ok := env["PATH"]; ok { @@ -373,7 +398,7 @@ func (d *Deploy) report(rtTarget setup.Targeter) error { d.output.Notice(output.Title(locale.T("deploy_restart"))) if rt.GOOS == "windows" { - d.output.Notice(locale.Tr("deploy_restart_cmd", filepath.Join(rtTarget.Dir(), "setenv.bat"))) + d.output.Notice(locale.Tr("deploy_restart_cmd", filepath.Join(params.Path, "setenv.bat"))) } else { d.output.Notice(locale.T("deploy_restart_shell")) } diff --git a/internal/runners/deploy/link_lin_mac.go b/internal/runners/deploy/link_lin_mac.go index b9a74c662f..9977124f86 100644 --- a/internal/runners/deploy/link_lin_mac.go +++ b/internal/runners/deploy/link_lin_mac.go @@ -38,7 +38,7 @@ func link(fpath, symlink string) error { if err != nil { return locale.WrapExternalError( err, "err_deploy_symlink", - "Cannot create symlink at {{.V0}}, ensure you have permission to write to {{.V1}}.", symlink, filepath.Dir(symlink)) + "Cannot create symlink at {{.V0}}. Please ensure you have permission to write to {{.V1}}.", symlink, filepath.Dir(symlink)) } return nil } diff --git a/internal/runners/deploy/uninstall/uninstall.go b/internal/runners/deploy/uninstall/uninstall.go index d6c1f4adba..fb158bb9cd 100644 --- a/internal/runners/deploy/uninstall/uninstall.go +++ b/internal/runners/deploy/uninstall/uninstall.go @@ -1,6 +1,7 @@ package uninstall import ( + "errors" "os" "runtime" @@ -11,16 +12,17 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/instanceid" "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/osutils" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/subshell/sscommon" - "github.com/ActiveState/cli/pkg/platform/runtime/store" - "github.com/ActiveState/cli/pkg/platform/runtime/target" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/cli/pkg/projectfile" ) type Params struct { @@ -73,12 +75,19 @@ func (u *Uninstall) Run(params *Params) error { path = cwd } - logging.Debug("Attempting to uninstall deployment at %s", path) - store := store.New(path) - if !store.HasMarker() { - return errs.AddTips( - locale.NewInputError("err_deploy_uninstall_not_deployed", "There is no deployed runtime at '{{.V0}}' to uninstall.", path), - locale.Tl("err_deploy_uninstall_not_deployed_tip", "Either change the current directory to a deployment or supply '--path ' arguments.")) + proj, err := project.FromExactPath(path) + if err != nil { + if errors.As(err, ptr.To(&projectfile.ErrorNoProject{})) { + return errs.AddTips( + locale.NewInputError("err_deploy_uninstall_not_deployed", "There is no deployed runtime at '{{.V0}}' to uninstall.", path), + locale.Tl("err_deploy_uninstall_not_deployed_tip", "Either change the current directory to a deployment or supply '--path ' arguments.")) + } + return locale.WrapError(err, "err_deploy_uninstall_cannot_read_project", "Cannot read project at '{{.V0}}'", path) + } + + commitID, err := localcommit.Get(path) + if err != nil { + return locale.WrapError(err, "err_deploy_uninstall_cannot_read_commit", "Cannot read commit ID from project at '{{.V0}}'", path) } if runtime.GOOS == "windows" && path == cwd { @@ -87,9 +96,7 @@ func (u *Uninstall) Run(params *Params) error { "Cannot remove deployment in current working directory. Please cd elsewhere and run this command again with the '--path' flag.") } - namespace, commitID := sourceAnalyticsInformation(store) - - err := u.subshell.CleanUserEnv(u.cfg, sscommon.DeployID, params.UserScope) + err = u.subshell.CleanUserEnv(u.cfg, sscommon.DeployID, params.UserScope) if err != nil { return locale.WrapError(err, "err_deploy_uninstall_env", "Failed to remove deploy directory from PATH") } @@ -100,9 +107,9 @@ func (u *Uninstall) Run(params *Params) error { } u.analytics.Event(constants.CatRuntimeUsage, constants.ActRuntimeDelete, &dimensions.Values{ - Trigger: ptr.To(target.TriggerDeploy.String()), - CommitID: ptr.To(commitID), - ProjectNameSpace: ptr.To(namespace), + Trigger: ptr.To(trigger.TriggerDeploy.String()), + CommitID: ptr.To(commitID.String()), + ProjectNameSpace: ptr.To(proj.Namespace().String()), InstanceID: ptr.To(instanceid.ID()), }) @@ -110,17 +117,3 @@ func (u *Uninstall) Run(params *Params) error { return nil } - -func sourceAnalyticsInformation(store *store.Store) (string, string) { - namespace, err := store.Namespace() - if err != nil { - logging.Error("Could not read namespace from marker file: %v", err) - } - - commitID, err := store.CommitID() - if err != nil { - logging.Error("Could not read commit ID from marker file: %v", err) - } - - return namespace, commitID -} diff --git a/internal/runners/eval/eval.go b/internal/runners/eval/eval.go index 2f45cc1448..d55d00b2c2 100644 --- a/internal/runners/eval/eval.go +++ b/internal/runners/eval/eval.go @@ -8,15 +8,14 @@ import ( "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/pkg/localcommit" - "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/project" ) type primeable interface { primer.Outputer primer.Auther primer.Projecter + primer.SvcModeler } type Params struct { @@ -24,57 +23,57 @@ type Params struct { } type Eval struct { - out output.Outputer - project *project.Project - auth *authentication.Auth + prime primeable } func New(p primeable) *Eval { return &Eval{ - out: p.Output(), - project: p.Project(), - auth: p.Auth(), + prime: p, } } func (e *Eval) Run(params *Params) (rerr error) { defer rationalizeError(&rerr) - e.out.Notice(output.Title(locale.Tl("title_eval", "Evaluating target: {{.V0}}", params.Target))) + out := e.prime.Output() + auth := e.prime.Auth() + proj := e.prime.Project() - if !e.auth.Authenticated() { + out.Notice(output.Title(locale.Tl("title_eval", "Evaluating target: {{.V0}}", params.Target))) + + if !auth.Authenticated() { return rationalize.ErrNotAuthenticated } - if e.project == nil { + if proj == nil { return rationalize.ErrNoProject } - commitID, err := localcommit.Get(e.project.Dir()) + commitID, err := localcommit.Get(proj.Dir()) if err != nil { return errs.Wrap(err, "Unable to get commit ID") } - pg := output.StartSpinner(e.out, locale.Tl("progress_eval", "Evaluating ... "), constants.TerminalAnimationInterval) + pg := output.StartSpinner(out, locale.Tl("progress_eval", "Evaluating ... "), constants.TerminalAnimationInterval) defer func() { if pg != nil { pg.Stop(locale.T("progress_fail") + "\n") } }() - bp := buildplanner.NewBuildPlannerModel(e.auth) - if err := bp.BuildTarget(e.project.Owner(), e.project.Name(), commitID.String(), params.Target); err != nil { + bp := buildplanner.NewBuildPlannerModel(auth, e.prime.SvcModel()) + if err := bp.BuildTarget(proj.Owner(), proj.Name(), commitID.String(), params.Target); err != nil { return locale.WrapError(err, "err_eval", "Failed to evaluate target '{{.V0}}'", params.Target) } - if err := bp.WaitForBuild(commitID, e.project.Owner(), e.project.Name(), ¶ms.Target); err != nil { + if err := bp.WaitForBuild(commitID, proj.Owner(), proj.Name(), ¶ms.Target); err != nil { return locale.WrapError(err, "err_eval_wait_for_build", "Failed to build target: '{{.V)}}'", params.Target) } pg.Stop("OK") pg = nil - e.out.Notice(locale.Tl("notice_eval_success", "Target successfully evaluated")) + out.Notice(locale.Tl("notice_eval_success", "Target successfully evaluated")) return nil } diff --git a/internal/runners/events/log.go b/internal/runners/events/log.go index 60d852fab5..3a6a8bccf5 100644 --- a/internal/runners/events/log.go +++ b/internal/runners/events/log.go @@ -30,7 +30,7 @@ func NewLog(prime primeable) *EventLog { func (e *EventLog) Run(params *EventLogParams) error { pid := process.ActivationPID(e.cfg) if pid == -1 { - return locale.NewInputError("err_eventlog_pid", "Could not find parent process ID, make sure you're running this command from inside an activated state (run '[ACTIONABLE]state activate[/RESET]' first).") + return locale.NewInputError("err_eventlog_pid", "Could not find parent process ID. Please make sure you're running this command from inside an activated state (run '[ACTIONABLE]state activate[/RESET]' first).") } filepath := logging.FilePathFor(logging.FileNameFor(int(pid))) @@ -41,7 +41,7 @@ func (e *EventLog) Run(params *EventLogParams) error { matcher, err := regexp.Compile(`(?:\s|^)(?:\w+-|)Event:`) if err != nil { - return locale.NewError("err_invalid_rx", "Could not create regex matcher. Please contact support, this should not happen.") + return locale.NewError("err_invalid_rx", "Could not create regex matcher. Please contact support. This should not happen.") } for line := range tailer.Lines { diff --git a/internal/runners/exec/exec.go b/internal/runners/exec/exec.go index 3cf08a5d54..e85231d863 100644 --- a/internal/runners/exec/exec.go +++ b/internal/runners/exec/exec.go @@ -3,11 +3,12 @@ package exec import ( "fmt" "os" + "os/exec" "path/filepath" "strconv" "strings" - rtrunbit "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/pkg/executors" "github.com/shirou/gopsutil/v3/process" "github.com/ActiveState/cli/internal/analytics" @@ -15,7 +16,6 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/hash" - "github.com/ActiveState/cli/internal/language" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/multilog" @@ -23,16 +23,15 @@ import ( "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/internal/scriptfile" + runtime_runbit "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/virtualenvironment" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime" - "github.com/ActiveState/cli/pkg/platform/runtime/executors" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" + rt "github.com/ActiveState/cli/pkg/runtime" ) type Configurable interface { @@ -41,6 +40,10 @@ type Configurable interface { } type Exec struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 subshell subshell.SubShell proj *project.Project auth *authentication.Auth @@ -66,6 +69,7 @@ type Params struct { func New(prime primeable) *Exec { return &Exec{ + prime, prime.Subshell(), prime.Project(), prime.Auth(), @@ -88,13 +92,13 @@ func (s *Exec) Run(params *Params, args ...string) (rerr error) { return nil } - trigger := target.NewExecTrigger(args[0]) + trigger := trigger.NewExecTrigger(args[0]) // Detect target and project dir // If the path passed resolves to a runtime dir (ie. has a runtime marker) then the project is not used var proj *project.Project var err error - if params.Path != "" && runtime.IsRuntimeDir(params.Path) { + if params.Path != "" && rt.IsRuntimeDir(params.Path) { projectDir = projectFromRuntimeDir(s.cfg, params.Path) proj, err = project.FromPath(projectDir) if err != nil { @@ -117,54 +121,43 @@ func (s *Exec) Run(params *Params, args ...string) (rerr error) { projectNamespace = proj.NamespaceString() } + s.prime.SetProject(proj) + s.out.Notice(locale.Tr("operating_message", projectNamespace, projectDir)) - rt, commit, err := rtrunbit.Solve(s.auth, s.out, s.analytics, proj, nil, trigger, s.svcModel, s.cfg, rtrunbit.OptMinimalUI) + rt, err := runtime_runbit.Update(s.prime, trigger, runtime_runbit.WithoutHeaders()) if err != nil { return errs.Wrap(err, "Could not initialize runtime") } - if !s.cfg.GetBool(constants.AsyncRuntimeConfig) { - err = rtrunbit.UpdateByReference(rt, commit, s.auth, proj, s.out, s.cfg, rtrunbit.OptMinimalUI) - if err != nil { - return errs.Wrap(err, "Could not setup runtime") - } - } - venv := virtualenvironment.New(rt) env, err := venv.GetEnv(true, false, projectDir, projectNamespace) if err != nil { return locale.WrapError(err, "err_exec_env", "Could not retrieve environment information for your runtime") } - logging.Debug("Trying to exec %s on PATH=%s", args[0], env["PATH"]) + + exeTarget := args[0] if err := handleRecursion(env, args); err != nil { return errs.Wrap(err, "Could not handle recursion") } - exeTarget := args[0] if !fileutils.TargetExists(exeTarget) { - rtDirs, err := rt.ExecutableDirs() - if err != nil { - return errs.Wrap(err, "Could not detect runtime executable paths") - } - - RTPATH := strings.Join(rtDirs, string(os.PathListSeparator)) - // Report recursive execution of executor: The path for the executable should be different from the default bin dir - exesOnPath := osutils.FilterExesOnPATH(args[0], RTPATH, func(exe string) bool { + filter := func(exe string) bool { v, err := executors.IsExecutor(exe) if err != nil { logging.Error("Could not find out if executable is an executor: %s", errs.JoinMessage(err)) return true // This usually means there's a permission issue, which means we likely don't own it } return !v - }) + } + exesOnPath := osutils.FilterExesOnPATH(exeTarget, env["PATH"], filter) if len(exesOnPath) > 0 { exeTarget = exesOnPath[0] - } else if osutils.FindExeOnPATH(exeTarget) == "" { + } else { return errs.AddTips(locale.NewInputError( "err_exec_not_found", "The executable '{{.V0}}' was not found in your PATH or in your project runtime.", @@ -187,25 +180,15 @@ func (s *Exec) Run(params *Params, args ...string) (rerr error) { } } - err = s.subshell.SetEnv(env) - if err != nil { - return locale.WrapError(err, "err_subshell_setenv") + _, _, err = osutils.ExecuteAndPipeStd(exeTarget, args[1:], osutils.EnvMapToSlice(env)) + if eerr, ok := err.(*exec.ExitError); ok { + return errs.Silence(errs.WrapExitCode(eerr, eerr.ExitCode())) } - - lang := language.Bash - scriptArgs := fmt.Sprintf(`%q "$@"`, exeTarget) - if strings.Contains(s.subshell.Binary(), "cmd") { - lang = language.Batch - scriptArgs = fmt.Sprintf("@ECHO OFF\n%q %%*", exeTarget) - } - - sf, err := scriptfile.New(lang, "state-exec", scriptArgs) if err != nil { - return locale.WrapError(err, "err_exec_create_scriptfile", "Could not generate script") + return errs.Wrap(err, "Could not execute command") } - defer sf.Clean() - return s.subshell.Run(sf.Filename(), args[1:]...) + return nil } func projectFromRuntimeDir(cfg projectfile.ConfigGetter, runtimeDir string) string { diff --git a/internal/runners/export/buildplan.go b/internal/runners/export/buildplan.go new file mode 100644 index 0000000000..07aa4c0aea --- /dev/null +++ b/internal/runners/export/buildplan.go @@ -0,0 +1,55 @@ +package export + +import ( + "encoding/json" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/runbits/buildplanner" + "github.com/ActiveState/cli/pkg/project" +) + +type BuildPlanParams struct { + Namespace *project.Namespaced + CommitID string + Target string +} + +type BuildPlan struct { + prime primeable +} + +func NewBuildPlan(p primeable) *BuildPlan { + return &BuildPlan{p} +} + +func (b *BuildPlan) Run(params *BuildPlanParams) (rerr error) { + defer rationalizeError(&rerr, b.prime.Auth()) + + proj := b.prime.Project() + out := b.prime.Output() + if proj != nil && !params.Namespace.IsValid() { + out.Notice(locale.Tr("operating_message", proj.NamespaceString(), proj.Dir())) + } + + commit, err := buildplanner.GetCommit( + params.Namespace, params.CommitID, params.Target, b.prime) + if err != nil { + return errs.Wrap(err, "Could not get commit") + } + + bytes, err := commit.BuildPlan().Marshal() + if err != nil { + return errs.Wrap(err, "Could not marshal build plan") + } + expr := make(map[string]interface{}) + err = json.Unmarshal(bytes, &expr) + if err != nil { + return errs.Wrap(err, "Could not unmarshal build plan") + } + + out.Print(output.Prepare(string(bytes), expr)) + + return nil +} diff --git a/internal/runners/export/deptree/artifacts.go b/internal/runners/export/deptree/artifacts.go new file mode 100644 index 0000000000..f750bb4eb1 --- /dev/null +++ b/internal/runners/export/deptree/artifacts.go @@ -0,0 +1,142 @@ +package deptree + +import ( + "fmt" + "strings" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/internal/sliceutils" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/platform/model/buildplanner" + "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/cli/pkg/sysinfo" + "github.com/go-openapi/strfmt" +) + +type primeable interface { + primer.Auther + primer.Outputer + primer.Configurer + primer.Projecter + primer.Analyticer + primer.SvcModeler +} + +type ArtifactParams struct { + Namespace *project.Namespaced + CommitID string + Req string + PlatformID string + LevelLimit int +} + +type DeptreeByArtifacts struct { + prime primeable +} + +func NewByArtifacts(prime primeable) *DeptreeByArtifacts { + return &DeptreeByArtifacts{ + prime: prime, + } +} + +func (d *DeptreeByArtifacts) Run(params ArtifactParams) error { + logging.Debug("Execute DepTree") + + out := d.prime.Output() + proj := d.prime.Project() + if proj == nil { + return rationalize.ErrNoProject + } + + ns, err := resolveNamespace(params.Namespace, params.CommitID, d.prime) + if err != nil { + return errs.Wrap(err, "Could not resolve namespace") + } + + bpm := buildplanner.NewBuildPlannerModel(d.prime.Auth(), d.prime.SvcModel()) + commit, err := bpm.FetchCommit(*ns.CommitID, ns.Owner, ns.Project, nil) + if err != nil { + return errs.Wrap(err, "Could not get remote build expr and time for provided commit") + } + + bp := commit.BuildPlan() + + platformID := strfmt.UUID(params.PlatformID) + if platformID == "" { + platformID, err = model.FilterCurrentPlatform(sysinfo.OS().String(), bp.Platforms(), "") + if err != nil { + return errs.Wrap(err, "Could not get platform ID") + } + } + + levelLimit := params.LevelLimit + if levelLimit == 0 { + levelLimit = 10 + } + + ingredients := bp.RequestedIngredients() + for _, ingredient := range ingredients { + if params.Req != "" && ingredient.Name != params.Req { + continue + } + out.Print(fmt.Sprintf("• [ACTIONABLE]%s/%s[/RESET] ([DISABLED]%s[/RESET])", ingredient.Namespace, ingredient.Name, ingredient.IngredientID)) + d.printArtifacts( + nil, + ingredient.Artifacts.Filter( + buildplan.FilterPlatformArtifacts(platformID), + ), + platformID, + 1, + levelLimit, + ) + } + + return nil +} + +func (d *DeptreeByArtifacts) printArtifacts( + parents []*buildplan.Artifact, + as buildplan.Artifacts, + platformID strfmt.UUID, + level int, + levelLimit int) { + indent := strings.Repeat(" ", level) + if level == levelLimit { + d.prime.Output().Print(indent + indentValue + "[ORANGE]Recursion limit reached[/RESET]") + return + } + count := 0 + for _, a := range as { + if len(sliceutils.Filter(parents, func(p *buildplan.Artifact) bool { return p.ArtifactID == a.ArtifactID })) != 0 { + d.prime.Output().Print(fmt.Sprintf("%s • Recurse to [CYAN]%s[/RESET] ([DISABLED]%s[/RESET])", indent, a.DisplayName, a.ArtifactID)) + continue + } + depTypes := []string{} + if a.IsRuntimeDependency { + depTypes = append(depTypes, "[GREEN]Runtime[/RESET]") + } + if a.IsBuildtimeDependency { + depTypes = append(depTypes, "[ORANGE]Buildtime[/RESET]") + } + mime := "" + if !buildplanner.IsStateToolArtifact(a.MimeType) { + mime = fmt.Sprintf(" ([DISABLED]%s[/RESET])", a.MimeType) + } + count = count + 1 + d.prime.Output().Print(fmt.Sprintf("%s%d. [CYAN]%s[/RESET] [%s] ([DISABLED]%s[/RESET]) %s", indent, count, a.DisplayName, strings.Join(depTypes, "|"), a.ArtifactID, mime)) + d.printArtifacts( + append(parents, a), + a.Dependencies(false, nil).Filter( + buildplan.FilterPlatformArtifacts(platformID), + ), + platformID, + level+1, + levelLimit, + ) + } +} diff --git a/internal/runners/export/deptree/common.go b/internal/runners/export/deptree/common.go new file mode 100644 index 0000000000..865bbef076 --- /dev/null +++ b/internal/runners/export/deptree/common.go @@ -0,0 +1,56 @@ +package deptree + +import ( + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/project" + "github.com/go-openapi/strfmt" +) + +func resolveNamespace(inputNs *project.Namespaced, inputCommitID string, prime primeable) (*project.Namespaced, error) { + out := prime.Output() + proj := prime.Project() + if proj == nil { + return nil, rationalize.ErrNoProject + } + + ns := inputNs + dir := "https://" + constants.PlatformURL + "/" + ns.String() + if !ns.IsValid() { + ns = proj.Namespace() + dir = proj.Dir() + } + + commitID := strfmt.UUID(inputCommitID) + if commitID == "" { + if inputNs.IsValid() { + p, err := model.FetchProjectByName(ns.Owner, ns.Project, prime.Auth()) + if err != nil { + return nil, errs.Wrap(err, "Unable to get project") + } + branch, err := model.DefaultBranchForProject(p) + if err != nil { + return nil, errs.Wrap(err, "Could not grab branch for project") + } + if branch.CommitID == nil { + return nil, errs.New("branch has not commit") + } + ns.CommitID = branch.CommitID + } else { + var err error + commitID, err = localcommit.Get(proj.Dir()) + if err != nil { + return nil, errs.Wrap(err, "Unable to get local commit ID") + } + ns.CommitID = &commitID + } + } + + out.Notice(locale.Tr("operating_message", ns.String(), dir)) + + return ns, nil +} diff --git a/internal/runners/export/deptree/ingredients.go b/internal/runners/export/deptree/ingredients.go new file mode 100644 index 0000000000..1003f25abc --- /dev/null +++ b/internal/runners/export/deptree/ingredients.go @@ -0,0 +1,126 @@ +package deptree + +import ( + "fmt" + "sort" + "strings" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/internal/sliceutils" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/platform/model/buildplanner" + "github.com/ActiveState/cli/pkg/project" + "github.com/go-openapi/strfmt" +) + +type DeptreeByIngredients struct { + prime primeable +} + +func NewByIngredients(prime primeable) *DeptreeByIngredients { + return &DeptreeByIngredients{ + prime: prime, + } +} + +type IngredientParams struct { + Namespace *project.Namespaced + CommitID string + Req string + LevelLimit int +} + +func (d *DeptreeByIngredients) Run(params IngredientParams) error { + logging.Debug("Execute DeptreeByIngredients") + + proj := d.prime.Project() + if proj == nil { + return rationalize.ErrNoProject + } + + ns, err := resolveNamespace(params.Namespace, params.CommitID, d.prime) + if err != nil { + return errs.Wrap(err, "Could not resolve namespace") + } + + bpm := buildplanner.NewBuildPlannerModel(d.prime.Auth(), d.prime.SvcModel()) + commit, err := bpm.FetchCommit(*ns.CommitID, ns.Owner, ns.Project, nil) + if err != nil { + return errs.Wrap(err, "Could not get remote build expr and time for provided commit") + } + + bp := commit.BuildPlan() + + levelLimit := params.LevelLimit + if levelLimit == 0 { + levelLimit = 10 + } + + ingredients := bp.RequestedIngredients() + common := ingredients.CommonRuntimeDependencies().ToIDMap() + + // Ensure languages are listed first, because they tend to themselves be dependencies + sort.Slice(ingredients, func(i, j int) bool { return ingredients[i].Namespace == model.NamespaceLanguage.String() }) + + if params.Req != "" { + ingredients = sliceutils.Filter(ingredients, func(i *buildplan.Ingredient) bool { + return i.Name == params.Req + }) + } + + d.printIngredients( + ingredients, + common, + 0, + levelLimit, + make(map[strfmt.UUID]struct{}), + ) + + return nil +} + +const indentValue = " " + +func (d *DeptreeByIngredients) printIngredients( + is buildplan.Ingredients, + common buildplan.IngredientIDMap, + level int, + levelLimit int, + seen map[strfmt.UUID]struct{}, +) { + indent := strings.Repeat(indentValue, level) + if level == levelLimit { + d.prime.Output().Print(indent + indentValue + "[ORANGE]Recursion limit reached[/RESET]") + return + } + count := 0 + for _, i := range is { + count = count + 1 + + color := "CYAN" + if _, ok := common[i.IngredientID]; ok { + color = "YELLOW" + } + d.prime.Output().Print(fmt.Sprintf("%s%d. [%s]%s/%s[/RESET] ([DISABLED]%s[/RESET])", + indent, count, color, i.Namespace, i.Name, i.IngredientID)) + + if _, ok := seen[i.IngredientID]; ok { + d.prime.Output().Print(fmt.Sprintf( + indent + indentValue + indentValue + "[DISABLED]Already listed[/RESET]", + )) + continue + } + seen[i.IngredientID] = struct{}{} + + d.printIngredients( + i.RuntimeDependencies(false), + common, + level+1, + levelLimit, + seen, + ) + } +} diff --git a/internal/runners/export/env.go b/internal/runners/export/env.go index 3f97b16190..73f2f073f3 100644 --- a/internal/runners/export/env.go +++ b/internal/runners/export/env.go @@ -6,13 +6,17 @@ import ( "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" ) type Env struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 out output.Outputer analytics analytics.Dispatcher svcModel *model.SvcModel @@ -23,6 +27,7 @@ type Env struct { func NewEnv(prime primeable) *Env { return &Env{ + prime, prime.Output(), prime.Analytics(), prime.SvcModel(), @@ -42,17 +47,14 @@ func (e *Env) Run() error { e.project.Dir()), ) - rt, err := runtime.SolveAndUpdate(e.auth, e.out, e.analytics, e.project, nil, target.TriggerActivate, e.svcModel, e.cfg, runtime.OptMinimalUI) + rt, err := runtime_runbit.Update(e.prime, trigger.TriggerActivate, runtime_runbit.WithoutHeaders()) if err != nil { return locale.WrapError(err, "err_export_new_runtime", "Could not initialize runtime") } - env, err := rt.Env(false, true) - if err != nil { - return locale.WrapError(err, "err_env_get_env", "Could not get runtime environment") - } + envVars := rt.Env(false).VariablesWithExecutors - e.out.Print(output.Prepare(env, env)) + e.out.Print(output.Prepare(envVars, envVars)) return nil } diff --git a/internal/runners/export/log.go b/internal/runners/export/log.go index 2085f18d63..b895cd138d 100644 --- a/internal/runners/export/log.go +++ b/internal/runners/export/log.go @@ -1,10 +1,13 @@ package export import ( + "bufio" + "os" "path/filepath" "regexp" "sort" "strconv" + "strings" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" @@ -35,7 +38,7 @@ var ErrInvalidLogPrefix = errs.New("invalid log prefix") var ErrLogNotFound = errs.New("log not found") func (l *Log) Run(params *LogParams) (rerr error) { - defer rationalizeError(&rerr) + defer rationalizeError(&rerr, nil) if params.Index < 0 { return ErrInvalidLogIndex @@ -57,12 +60,23 @@ func (l *Log) Run(params *LogParams) (rerr error) { if err != nil { return ErrInvalidLogPrefix } + for _, file := range logFiles { if regex.MatchString(file) { timestamp, err := strconv.Atoi(regex.FindStringSubmatch(file)[1]) if err != nil { continue } + + ignore, err := ignoreLogFile(file) + if err != nil { + return errs.Wrap(err, "failed to ignore log file") + } + + if ignore { + continue + } + filteredLogFiles = append(filteredLogFiles, &logFile{file, timestamp}) } } @@ -85,3 +99,35 @@ func (l *Log) Run(params *LogParams) (rerr error) { return nil } + +func ignoreLogFile(logFile string) (bool, error) { + if strings.EqualFold(filepath.Base(logFile), logging.FileName()) { + return true, nil + } + + file, err := os.Open(logFile) + if err != nil { + return false, errs.Wrap(err, "failed to open log file") + } + defer file.Close() + + regex := regexp.MustCompile(`Args: \[(.*?)\], Flags: \[.*?\]`) + scanner := bufio.NewScanner(file) + var args string + for scanner.Scan() { + logLine := scanner.Text() + if regex.MatchString(logLine) { + match := regex.FindStringSubmatch(logLine) + if len(match) > 1 { + args = match[1] + } + break + } + } + + if strings.HasPrefix(args, "export log") { + return true, nil + } + + return false, nil +} diff --git a/internal/runners/export/rationalize.go b/internal/runners/export/rationalize.go index 6b5fd35295..9f54dda3d0 100644 --- a/internal/runners/export/rationalize.go +++ b/internal/runners/export/rationalize.go @@ -5,10 +5,16 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/runbits/buildplanner" + "github.com/ActiveState/cli/pkg/platform/authentication" + "github.com/ActiveState/cli/pkg/platform/model" ) -func rationalizeError(err *error) { +func rationalizeError(err *error, auth *authentication.Auth) { var errProjectNotFound *ErrProjectNotFound + var errInvalidCommitId *buildplanner.ErrInvalidCommitId + var errModelProjectNotFound *model.ErrProjectNotFound + var errCommitIdDoesNotExistInProject *buildplanner.ErrCommitDoesNotExistInProject switch { // export log with invalid --index. @@ -39,5 +45,24 @@ func rationalizeError(err *error) { *err = errs.WrapUserFacing(*err, locale.Tl("export_runtime_project_not_found", "Could not find project file in '[ACTIONABLE]{{.V0}}[/RESET]'", errProjectNotFound.Path), errs.SetInput()) + + case errors.As(*err, &errInvalidCommitId): + *err = errs.WrapUserFacing( + *err, locale.Tr("err_commit_id_invalid_given", errInvalidCommitId.Id), + errs.SetInput()) + + case errors.As(*err, &errModelProjectNotFound): + *err = errs.WrapUserFacing(*err, + locale.Tr("err_api_project_not_found", errModelProjectNotFound.Organization, errModelProjectNotFound.Project), + errs.SetIf(!auth.Authenticated(), errs.SetTips(locale.T("tip_private_project_auth"))), + errs.SetInput()) + + case errors.As(*err, &errCommitIdDoesNotExistInProject): + *err = errs.WrapUserFacing(*err, + locale.Tr("err_commit_id_not_in_history", + errCommitIdDoesNotExistInProject.Project, + errCommitIdDoesNotExistInProject.CommitID, + ), + errs.SetInput()) } } diff --git a/internal/runners/export/runtime.go b/internal/runners/export/runtime.go index 035df78437..6fb6f0f112 100644 --- a/internal/runners/export/runtime.go +++ b/internal/runners/export/runtime.go @@ -11,15 +11,18 @@ import ( "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/internal/runbits/runtime" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/cli/pkg/runtime" + "github.com/ActiveState/cli/pkg/runtime_helpers" ) type Runtime struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 out output.Outputer analytics analytics.Dispatcher svcModel *model.SvcModel @@ -34,6 +37,7 @@ type RuntimeParams struct { func NewRuntime(prime primeable) *Runtime { return &Runtime{ + prime, prime.Output(), prime.Analytics(), prime.SvcModel(), @@ -52,7 +56,7 @@ func (e *ErrProjectNotFound) Error() string { } func (e *Runtime) Run(params *RuntimeParams) (rerr error) { - defer rationalizeError(&rerr) + defer rationalizeError(&rerr, e.auth) proj := e.project if params.Path != "" { @@ -68,19 +72,14 @@ func (e *Runtime) Run(params *RuntimeParams) (rerr error) { e.out.Notice(locale.Tr("export_runtime_statement", proj.NamespaceString(), proj.Dir())) - rt, err := runtime.SolveAndUpdate(e.auth, e.out, e.analytics, proj, nil, target.TriggerExport, e.svcModel, e.cfg, runtime.OptMinimalUI) + rt, err := runtime_helpers.FromProject(proj) if err != nil { return errs.Wrap(err, "Could not get runtime to export for") } projectDir := proj.Dir() - runtimeDir := rt.Target().Dir() - execDir := setup.ExecDir(runtimeDir) - - env, err := rt.Env(false, true) - if err != nil { - return errs.Wrap(err, "Could not get runtime environment") - } + runtimeDir := rt.Path() + execDir := runtime.ExecutorsPath(runtimeDir) contents, err := assets.ReadFileBytes("list_map.tpl") if err != nil { @@ -90,6 +89,9 @@ func (e *Runtime) Run(params *RuntimeParams) (rerr error) { if err != nil { return errs.Wrap(err, "Could not parse env template for output") } + + env := rt.Env(false).VariablesWithExecutors + var envOutput strings.Builder err = tmpl.Execute(&envOutput, env) if err != nil { diff --git a/internal/runners/fork/fork.go b/internal/runners/fork/fork.go index 60587295f2..f751900fa0 100644 --- a/internal/runners/fork/fork.go +++ b/internal/runners/fork/fork.go @@ -41,7 +41,7 @@ func New(prime primeable) *Fork { func (f *Fork) Run(params *Params) error { if !f.auth.Authenticated() { - return locale.NewInputError("err_auth_required", "Authentication is required, please authenticate by running 'state auth'") + return locale.NewInputError("err_auth_required", "Authentication is required. Please authenticate by running 'state auth'") } target := &project.Namespaced{ diff --git a/internal/runners/hello/hello_example.go b/internal/runners/hello/hello_example.go index d06551b16e..a13ee016c3 100644 --- a/internal/runners/hello/hello_example.go +++ b/internal/runners/hello/hello_example.go @@ -14,7 +14,7 @@ import ( "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/runbits" + "github.com/ActiveState/cli/internal/runbits/example" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/authentication" @@ -67,10 +67,12 @@ func New(p primeable) *Hello { // This is so that end-users always get errors that clearly relate to what they were doing, with a good sense on what // they can do to address it. func rationalizeError(err *error) { + var errNoNameProvided *example.NoNameProvidedError + switch { case err == nil: return - case errs.Matches(*err, &runbits.NoNameProvidedError{}): + case errors.As(*err, &errNoNameProvided): // Errors that we are looking for should be wrapped in a user-facing error. // Ensure we wrap the top-level error returned from the runner and not // the unpacked error that we are inspecting. @@ -100,7 +102,7 @@ func (h *Hello) Run(params *Params) (rerr error) { // Reusable runner logic is contained within the runbits package. // You should only use this if you intend to share logic between // runners. Runners should NEVER invoke other runners. - if err := runbits.SayHello(h.out, params.Name); err != nil { + if err := example.SayHello(h.out, params.Name); err != nil { // Errors should nearly always be localized. return errs.Wrap( err, "Cannot say hello.", diff --git a/internal/runners/initialize/init.go b/internal/runners/initialize/init.go index 073e558cd3..6707251202 100644 --- a/internal/runners/initialize/init.go +++ b/internal/runners/initialize/init.go @@ -7,13 +7,6 @@ import ( "regexp" "strings" - buildscript_runbit "github.com/ActiveState/cli/internal/runbits/buildscript" - "github.com/ActiveState/cli/internal/runbits/errors" - "github.com/ActiveState/cli/internal/runbits/runtime" - "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/sysinfo" - "github.com/go-openapi/strfmt" - "github.com/ActiveState/cli/internal/analytics" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" @@ -25,15 +18,20 @@ import ( "github.com/ActiveState/cli/internal/osutils" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/runbits/buildscript" "github.com/ActiveState/cli/internal/runbits/dependencies" + "github.com/ActiveState/cli/internal/runbits/org" "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" + "github.com/ActiveState/cli/pkg/sysinfo" + "github.com/go-openapi/strfmt" ) // RunParams stores run func parameters. @@ -48,6 +46,10 @@ type RunParams struct { // Initialize stores scope-related dependencies. type Initialize struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 auth *authentication.Auth config Configurable out output.Outputer @@ -66,14 +68,16 @@ type primeable interface { primer.Outputer primer.Analyticer primer.SvcModeler + primer.Projecter } type errProjectExists struct { - error path string } -var errNoOwner = errs.New("Could not find organization") +func (e errProjectExists) Error() string { + return "project file already exists" +} var errNoLanguage = errs.New("No language specified") @@ -85,9 +89,11 @@ func (e errUnrecognizedLanguage) Error() string { return fmt.Sprintf("unrecognized language: %s", e.Name) } +var errDeleteProjectAfterError = errs.New("could not delete initialized project") + // New returns a prepared ptr to Initialize instance. func New(prime primeable) *Initialize { - return &Initialize{prime.Auth(), prime.Config(), prime.Output(), prime.Analytics(), prime.SvcModel()} + return &Initialize{prime, prime.Auth(), prime.Config(), prime.Output(), prime.Analytics(), prime.SvcModel()} } // inferLanguage tries to infer a reasonable default language from the project currently in use @@ -119,6 +125,8 @@ func inferLanguage(config projectfile.ConfigGetter, auth *authentication.Auth) ( } func (r *Initialize) Run(params *RunParams) (rerr error) { + defer func() { runtime_runbit.RationalizeSolveError(r.prime.Project(), r.auth, &rerr) }() + logging.Debug("Init: %s %v", params.Namespace, params.Private) var ( @@ -152,24 +160,20 @@ func (r *Initialize) Run(params *RunParams) (rerr error) { } if fileutils.TargetExists(filepath.Join(path, constants.ConfigFileName)) { - return &errProjectExists{ - error: errs.New("Project file already exists"), - path: path, - } + return &errProjectExists{path} } err := fileutils.MkdirUnlessExists(path) if err != nil { - return locale.WrapError(err, "err_init_preparedir", "Could not create directory at [NOTICE]{{.V0}}[/RESET]. Error: {{.V1}}", params.Path, err.Error()) + return errs.Wrap(err, "Could not create directory '%s'", params.Path) } path, err = filepath.Abs(params.Path) if err != nil { - return locale.WrapExternalError(err, "err_init_abs_path", "Could not determine absolute path to [NOTICE]{{.V0}}[/RESET]. Error: {{.V1}}", path, err.Error()) + return errs.Wrap(err, "Could not determine absolute path to '%s'", params.Path) } var languageName, languageVersion string - var inferred bool if params.Language != "" { langParts := strings.Split(params.Language, "@") languageName = langParts[0] @@ -177,7 +181,7 @@ func (r *Initialize) Run(params *RunParams) (rerr error) { languageVersion = langParts[1] } } else { - languageName, languageVersion, inferred = inferLanguage(r.config, r.auth) + languageName, languageVersion, _ = inferLanguage(r.config, r.auth) } if languageName == "" { @@ -196,14 +200,10 @@ func (r *Initialize) Run(params *RunParams) (rerr error) { version, err := deriveVersion(lang, languageVersion, r.auth) if err != nil { - if inferred || errors.IsReportableError(err) { - return locale.WrapError(err, "err_init_lang", "", languageName, languageVersion) - } else { - return locale.WrapExternalError(err, "err_init_lang", "", languageName, languageVersion) - } + return errs.Wrap(err, "Unable to get language version") } - resolvedOwner, err = r.getOwner(paramOwner) + resolvedOwner, err = org.Get(paramOwner, r.auth, r.config) if err != nil { return errs.Wrap(err, "Unable to determine owner") } @@ -222,7 +222,7 @@ func (r *Initialize) Run(params *RunParams) (rerr error) { pjfile, err := projectfile.Create(createParams) if err != nil { - return locale.WrapError(err, "err_init_pjfile", "Could not create project file") + return errs.Wrap(err, "Could not create project file") } // If an error occurs, remove the created activestate.yaml file so the user can try again. @@ -249,6 +249,7 @@ func (r *Initialize) Run(params *RunParams) (rerr error) { if err != nil { return err } + r.prime.SetProject(proj) logging.Debug("Creating Platform project") @@ -257,8 +258,8 @@ func (r *Initialize) Run(params *RunParams) (rerr error) { return errs.Wrap(err, "Unable to determine Platform ID from %s", sysinfo.OS().String()) } - bp := buildplanner.NewBuildPlannerModel(r.auth) - commitID, err := bp.CreateProject(&buildplanner.CreateProjectParams{ + bp := bpModel.NewBuildPlannerModel(r.auth, r.svcModel) + commitID, err := bp.CreateProject(&bpModel.CreateProjectParams{ Owner: namespace.Owner, Project: namespace.Project, PlatformID: strfmt.UUID(platformID), @@ -268,7 +269,7 @@ func (r *Initialize) Run(params *RunParams) (rerr error) { Description: locale.T("commit_message_add_initial"), }) if err != nil { - return locale.WrapError(err, "err_init_commit", "Could not create project") + return errs.Wrap(err, "Could not create project") } if err := localcommit.Set(proj.Dir(), commitID.String()); err != nil { @@ -276,35 +277,40 @@ func (r *Initialize) Run(params *RunParams) (rerr error) { } if r.config.GetBool(constants.OptinBuildscriptsConfig) { - if err := buildscript_runbit.Initialize(proj.Dir(), r.auth); err != nil { + if err := buildscript_runbit.Initialize(proj, r.auth, r.svcModel); err != nil { return errs.Wrap(err, "Unable to initialize buildscript") } } - rti, commit, err := runtime.Solve(r.auth, r.out, r.analytics, proj, &commitID, target.TriggerInit, r.svcModel, r.config, runtime.OptNoIndent) + // Solve runtime + solveSpinner := output.StartSpinner(r.out, locale.T("progress_solve"), constants.TerminalAnimationInterval) + bpm := bpModel.NewBuildPlannerModel(r.auth, r.svcModel) + commit, err := bpm.FetchCommit(commitID, r.prime.Project().Owner(), r.prime.Project().Name(), nil) if err != nil { + solveSpinner.Stop(locale.T("progress_fail")) logging.Debug("Deleting remotely created project due to runtime setup error") err2 := model.DeleteProject(namespace.Owner, namespace.Project, r.auth) if err2 != nil { multilog.Error("Error deleting remotely created project after runtime setup error: %v", errs.JoinMessage(err2)) - return locale.WrapError(err, "err_init_refresh_delete_project", "Could not setup runtime after init, and could not delete newly created Platform project. Please delete it manually before trying again") + return errDeleteProjectAfterError } - return errs.Wrap(err, "Could not initialize runtime") + return errs.Wrap(err, "Failed to fetch build result") } - dependencies.OutputSummary(r.out, commit.BuildPlan().RequestedArtifacts()) - err = runtime.UpdateByReference(rti, commit, r.auth, proj, r.out, r.config, runtime.OptNone) + solveSpinner.Stop(locale.T("progress_success")) + + // When running `state init` we want to show all of the dependencies that will be installed. + dependencies.OutputSummary(r.out, commit.BuildPlan().Artifacts()) + rti, err := runtime_runbit.Update(r.prime, trigger.TriggerInit, runtime_runbit.WithCommit(commit)) if err != nil { return errs.Wrap(err, "Could not setup runtime after init") } + executorsPath := rti.Env(false).ExecutorsPath projectfile.StoreProjectMapping(r.config, namespace.String(), filepath.Dir(proj.Source().Path())) - projectTarget := target.NewProjectTarget(proj, nil, "").Dir() - executables := setup.ExecDir(projectTarget) - - initSuccessMsg := locale.Tr("init_success", namespace.String(), path, executables) + initSuccessMsg := locale.Tr("init_success", namespace.String(), path, executorsPath) if !strings.EqualFold(paramOwner, resolvedOwner) { - initSuccessMsg = locale.Tr("init_success_resolved_owner", namespace.String(), path, executables) + initSuccessMsg = locale.Tr("init_success_resolved_owner", namespace.String(), path, executorsPath) } r.out.Print(output.Prepare( @@ -316,7 +322,7 @@ func (r *Initialize) Run(params *RunParams) (rerr error) { }{ namespace.String(), path, - executables, + executorsPath, }, )) @@ -391,48 +397,6 @@ func deriveVersion(lang language.Language, version string, auth *authentication. return version, nil } -func (i *Initialize) getOwner(desiredOwner string) (string, error) { - orgs, err := model.FetchOrganizations(i.auth) - if err != nil { - return "", errs.Wrap(err, "Unable to get the user's writable orgs") - } - - // Prefer the desired owner if it's valid - if desiredOwner != "" { - // Match the case of the organization. - // Otherwise the incorrect case will be written to the project file. - for _, org := range orgs { - if strings.EqualFold(org.URLname, desiredOwner) { - return org.URLname, nil - } - } - // Return desiredOwner for error reporting - return desiredOwner, errNoOwner - } - - // Use the last used namespace if it's valid - lastUsed := i.config.GetString(constants.LastUsedNamespacePrefname) - if lastUsed != "" { - ns, err := project.ParseNamespace(lastUsed) - if err != nil { - return "", errs.Wrap(err, "Unable to parse last used namespace") - } - - for _, org := range orgs { - if strings.EqualFold(org.URLname, ns.Owner) { - return org.URLname, nil - } - } - } - - // Use the first org if there is one - if len(orgs) > 0 { - return orgs[0].URLname, nil - } - - return "", errNoOwner -} - func (i *Initialize) getProjectName(desiredProject string, lang string) string { if desiredProject != "" { return desiredProject diff --git a/internal/runners/initialize/rationalize.go b/internal/runners/initialize/rationalize.go index 80a49de44f..540e350060 100644 --- a/internal/runners/initialize/rationalize.go +++ b/internal/runners/initialize/rationalize.go @@ -4,21 +4,20 @@ import ( "errors" "strings" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/language" "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/runbits/org" "github.com/ActiveState/cli/internal/runbits/rationalize" bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" ) func rationalizeError(owner, project string, rerr *error) { var pcErr *bpResp.ProjectCreatedError - var errArtifactSetup *setup.ArtifactSetupErrors var projectExistsErr *errProjectExists var unrecognizedLanguageErr *errUnrecognizedLanguage + var ownerNotFoundErr *org.ErrOwnerNotFound switch { case rerr == nil: @@ -43,9 +42,15 @@ func rationalizeError(owner, project string, rerr *error) { errs.SetInput(), ) - case errors.Is(*rerr, errNoOwner): + case errors.As(*rerr, &ownerNotFoundErr): *rerr = errs.WrapUserFacing(*rerr, - locale.Tr("err_init_invalid_org", owner), + locale.Tr("err_init_invalid_org", ownerNotFoundErr.DesiredOwner), + errs.SetInput(), + ) + + case errors.Is(*rerr, org.ErrNoOwner): + *rerr = errs.WrapUserFacing(*rerr, + locale.Tl("err_init_cannot_find_org", "Please specify an owner for the project to initialize."), errs.SetInput(), ) @@ -78,20 +83,10 @@ func rationalizeError(owner, project string, rerr *error) { errs.SetTips(locale.T("err_init_authenticated"))) } - // If there was an artifact download error, say so, rather than reporting a generic "could not - // update runtime" error. - case errors.As(*rerr, &errArtifactSetup): - for _, serr := range errArtifactSetup.Errors() { - if !errs.Matches(serr, &setup.ArtifactDownloadError{}) { - continue - } - *rerr = errs.WrapUserFacing(*rerr, - locale.Tl("err_init_download", "Your project could not be created because one or more artifacts failed to download."), - errs.SetInput(), - errs.SetTips(locale.Tr("err_user_network_solution", constants.ForumsURL)), - ) - break // it only takes one download failure to report the runtime failure as due to download error - } + case errors.Is(*rerr, errDeleteProjectAfterError): + *rerr = errs.WrapUserFacing(*rerr, + locale.Tl("err_init_refresh_delete_project", "Could not setup runtime after init, and could not delete newly created Platform project. Please delete it manually before trying again"), + ) } } diff --git a/internal/runners/install/install.go b/internal/runners/install/install.go new file mode 100644 index 0000000000..5724c7b580 --- /dev/null +++ b/internal/runners/install/install.go @@ -0,0 +1,367 @@ +package install + +import ( + "errors" + "fmt" + "regexp" + "strings" + "time" + + "github.com/ActiveState/cli/internal/captain" + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/runbits/commits_runbit" + "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/internal/runbits/reqop_runbit" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" + "github.com/ActiveState/cli/internal/sliceutils" + "github.com/ActiveState/cli/pkg/buildscript" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/ActiveState/cli/pkg/platform/model" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" +) + +type primeable interface { + primer.Outputer + primer.Prompter + primer.Projecter + primer.Auther + primer.Configurer + primer.Analyticer + primer.SvcModeler +} + +// Params tracks the info required for running Install. +type Params struct { + Packages captain.PackagesValue + Timestamp captain.TimeValue +} + +type resolvedRequirement struct { + types.Requirement + VersionLocale string `json:"version"` // VersionLocale represents the version as we want to show it to the user + ingredient *model.IngredientAndVersion +} + +type requirement struct { + Requested *captain.PackageValue `json:"requested"` + Resolved resolvedRequirement `json:"resolved"` + + // Remainder are for display purposes only + Type model.NamespaceType `json:"type"` + Operation types.Operation `json:"operation"` +} + +type requirements []*requirement + +func (r requirements) String() string { + result := []string{} + for _, req := range r { + if req.Resolved.Namespace != "" { + result = append(result, fmt.Sprintf("%s/%s", req.Resolved.Namespace, req.Requested.Name)) + } else { + result = append(result, req.Requested.Name) + } + } + return strings.Join(result, ", ") +} + +// Install manages the installing execution context. +type Install struct { + prime primeable + nsType model.NamespaceType +} + +// New prepares an installation execution context for use. +func New(prime primeable, nsType model.NamespaceType) *Install { + return &Install{prime, nsType} +} + +// Run executes the install behavior. +func (i *Install) Run(params Params) (rerr error) { + defer i.rationalizeError(&rerr) + + logging.Debug("ExecuteInstall") + + pj := i.prime.Project() + out := i.prime.Output() + bp := bpModel.NewBuildPlannerModel(i.prime.Auth(), i.prime.SvcModel()) + + // Verify input + if pj == nil { + return rationalize.ErrNoProject + } + if pj.IsHeadless() { + return rationalize.ErrHeadless + } + + out.Notice(locale.Tr("operating_message", pj.NamespaceString(), pj.Dir())) + + var pg *output.Spinner + defer func() { + if pg != nil { + pg.Stop(locale.T("progress_fail")) + } + }() + + // Start process of resolving requirements + var oldCommit *bpModel.Commit + var reqs requirements + var ts time.Time + { + pg = output.StartSpinner(out, locale.T("progress_search"), constants.TerminalAnimationInterval) + + // Grab local commit info + localCommitID, err := localcommit.Get(i.prime.Project().Dir()) + if err != nil { + return errs.Wrap(err, "Unable to get local commit") + } + oldCommit, err = bp.FetchCommit(localCommitID, pj.Owner(), pj.Name(), nil) + if err != nil { + return errs.Wrap(err, "Failed to fetch old build result") + } + + // Resolve timestamp, commit and languages used for current project. + // This will be used to resolve the requirements. + ts, err = commits_runbit.ExpandTimeForBuildScript(¶ms.Timestamp, i.prime.Auth(), oldCommit.BuildScript()) + if err != nil { + return errs.Wrap(err, "Unable to get timestamp from params") + } + + // Get languages used in current project + languages, err := model.FetchLanguagesForBuildScript(oldCommit.BuildScript()) + if err != nil { + logging.Debug("Could not get language from project: %v", err) + } + + // Resolve requirements + reqs, err = i.resolveRequirements(params.Packages, ts, languages) + if err != nil { + return errs.Wrap(err, "Unable to resolve requirements") + } + + // Done resolving requirements + pg.Stop(locale.T("progress_found")) + pg = nil + } + + // Prepare updated buildscript + script := oldCommit.BuildScript() + if err := prepareBuildScript(script, reqs, ts); err != nil { + return errs.Wrap(err, "Could not prepare build script") + } + + // Update local checkout and source runtime changes + if err := reqop_runbit.UpdateAndReload(i.prime, script, oldCommit, locale.Tr("commit_message_added", reqs.String()), trigger.TriggerInstall); err != nil { + return errs.Wrap(err, "Failed to update local checkout") + } + + if out.Type().IsStructured() { + out.Print(output.Structured(reqs)) + } else { + i.renderUserFacing(reqs) + } + + // All done + out.Notice(locale.T("operation_success_local")) + + return nil +} + +type errNoMatches struct { + error + requirements []*requirement + languages []model.Language +} + +// resolveRequirements will attempt to resolve the ingredient and namespace for each requested package +func (i *Install) resolveRequirements(packages captain.PackagesValue, ts time.Time, languages []model.Language) (requirements, error) { + failed := []*requirement{} + reqs := []*requirement{} + for _, pkg := range packages { + req := &requirement{Requested: pkg} + if pkg.Namespace != "" { + req.Resolved.Name = pkg.Name + req.Resolved.Namespace = pkg.Namespace + } + + // Find ingredients that match the pkg query + ingredients, err := model.SearchIngredientsStrict(pkg.Namespace, pkg.Name, false, false, &ts, i.prime.Auth()) + if err != nil { + return nil, locale.WrapError(err, "err_pkgop_search_err", "Failed to check for ingredients.") + } + + // Filter out ingredients that don't target one of the supported languages + if pkg.Namespace == "" { + ingredients = sliceutils.Filter(ingredients, func(iv *model.IngredientAndVersion) bool { + // Ensure namespace type matches + if !model.NamespaceMatch(*iv.Ingredient.PrimaryNamespace, i.nsType.Matchable()) { + return false + } + + // Ensure that this is namespace covers one of the languages in our project + // But only if we're aiming to install a package or bundle, because otherwise the namespace is not + // guaranteed to hold the language. + if i.nsType == model.NamespacePackage || i.nsType == model.NamespaceBundle { + il := model.LanguageFromNamespace(*iv.Ingredient.PrimaryNamespace) + for _, l := range languages { + if l.Name == il { + return true + } + } + return false + } + return true + }) + } + + // Resolve matched ingredients + var ingredient *model.IngredientAndVersion + if len(ingredients) == 1 { + ingredient = ingredients[0] + } else if len(ingredients) > 1 { // This wouldn't ever trigger if namespace was provided as that should guarantee a single result + var err error + ingredient, err = i.promptForMatchingIngredient(req, ingredients) + if err != nil { + return nil, errs.Wrap(err, "Prompting for namespace failed") + } + } + if ingredient == nil { + failed = append(failed, req) + } else { + req.Resolved.Name = ingredient.Ingredient.NormalizedName + req.Resolved.Namespace = *ingredient.Ingredient.PrimaryNamespace + req.Resolved.ingredient = ingredient + } + + reqs = append(reqs, req) + } + + // Fail if not all requirements could be resolved + if len(failed) > 0 { + return nil, errNoMatches{error: errs.New("Failed to resolve requirements"), requirements: failed, languages: languages} + } + + // Now that we have the ingredient resolved we can also resolve the version requirement. + // We can also set the type and operation, which are used for conveying what happened to the user. + for _, req := range reqs { + // Set requirement type + req.Type = model.ParseNamespace(req.Resolved.Namespace).Type() + + if err := resolveVersion(req); err != nil { + return nil, errs.Wrap(err, "Could not resolve version") + } + } + + return reqs, nil +} + +var versionRe = regexp.MustCompile(`^\d(\.\d+)*$`) + +func resolveVersion(req *requirement) error { + version := req.Requested.Version + + // An empty version means "Auto" + if req.Requested.Version == "" { + req.Resolved.VersionLocale = locale.T("constraint_auto") + return nil + } + + // Verify that the version provided can be resolved + if versionRe.MatchString(version) { + match := false + for _, knownVersion := range req.Resolved.ingredient.Versions { + if knownVersion.Version == version { + match = true + break + } + } + if !match { + for _, knownVersion := range req.Resolved.ingredient.Versions { + if strings.HasPrefix(knownVersion.Version, version) { + version = version + ".x" // The user supplied a partial version, resolve it as a wildcard + } + } + } + } + + var err error + req.Resolved.VersionLocale = version + req.Resolved.VersionRequirement, err = bpModel.VersionStringToRequirements(version) + if err != nil { + return errs.Wrap(err, "Could not process version string into requirements") + } + + return nil +} + +func (i *Install) promptForMatchingIngredient(req *requirement, ingredients []*model.IngredientAndVersion) (*model.IngredientAndVersion, error) { + if len(ingredients) <= 1 { + return nil, errs.New("promptForNamespace should never be called if there are no multiple ingredient matches") + } + + choices := []string{} + values := map[string]*model.IngredientAndVersion{} + for _, i := range ingredients { + // Generate ingredient choices to present to the user + name := fmt.Sprintf("%s (%s)", *i.Ingredient.Name, *i.Ingredient.PrimaryNamespace) + choices = append(choices, name) + values[name] = i + } + + // Prompt the user with the ingredient choices + choice, err := i.prime.Prompt().Select( + locale.T("prompt_pkgop_ingredient"), + locale.Tr("prompt_pkgop_ingredient_msg", req.Requested.String()), + choices, &choices[0], + ) + if err != nil { + return nil, errs.Wrap(err, "prompting failed") + } + + // Return the user selected ingredient + return values[choice], nil +} + +func (i *Install) renderUserFacing(reqs requirements) { + for _, req := range reqs { + l := "install_report_added" + if req.Operation == types.OperationUpdated { + l = "install_report_updated" + } + i.prime.Output().Notice(locale.Tr(l, fmt.Sprintf("%s/%s@%s", req.Resolved.Namespace, req.Resolved.Name, req.Resolved.VersionLocale))) + } + i.prime.Output().Notice("") +} + +func prepareBuildScript(script *buildscript.BuildScript, requirements requirements, ts time.Time) error { + script.SetAtTime(ts, true) + for _, req := range requirements { + requirement := types.Requirement{ + Namespace: req.Resolved.Namespace, + Name: req.Requested.Name, + VersionRequirement: req.Resolved.VersionRequirement, + } + + req.Operation = types.OperationUpdated + if err := script.RemoveRequirement(requirement); err != nil { + if !errors.As(err, ptr.To(&buildscript.RequirementNotFoundError{})) { + return errs.Wrap(err, "Could not remove requirement") + } + req.Operation = types.OperationAdded // If req could not be found it means this is an addition + } + + err := script.AddRequirement(requirement) + if err != nil { + return errs.Wrap(err, "Failed to update build expression with requirement") + } + } + + return nil +} diff --git a/internal/runners/install/rationalize.go b/internal/runners/install/rationalize.go new file mode 100644 index 0000000000..be4a6d3a5d --- /dev/null +++ b/internal/runners/install/rationalize.go @@ -0,0 +1,97 @@ +package install + +import ( + "errors" + "fmt" + "strings" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/multilog" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/runbits/rationalizers" + "github.com/ActiveState/cli/internal/sliceutils" + bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" + "github.com/ActiveState/cli/pkg/platform/model" +) + +func (i *Install) rationalizeError(rerr *error) { + var noMatchErr errNoMatches + + switch { + case rerr == nil: + return + + // No matches found + case errors.As(*rerr, &noMatchErr): + names := []string{} + for _, r := range noMatchErr.requirements { + names = append(names, fmt.Sprintf(`[ACTIONABLE]%s[/RESET]`, r.Requested.Name)) + } + if len(noMatchErr.requirements) > 1 { + *rerr = errs.WrapUserFacing( + *rerr, + locale.Tr("package_requirements_no_match", strings.Join(names, ", ")), + errs.SetInput()) + return + } + suggestions, err := i.getSuggestions(noMatchErr.requirements[0], noMatchErr.languages) + if err != nil { + multilog.Error("Failed to retrieve suggestions: %v", err) + } + + if len(suggestions) == 0 { + *rerr = errs.WrapUserFacing( + *rerr, + locale.Tr("package_ingredient_alternatives_nosuggest", strings.Join(names, ", ")), + errs.SetInput()) + return + } + + *rerr = errs.WrapUserFacing( + *rerr, + locale.Tr("package_ingredient_alternatives", strings.Join(names, ", "), strings.Join(suggestions, "\n")), + errs.SetInput()) + + // Error staging a commit during install. + case errors.As(*rerr, ptr.To(&bpResp.CommitError{})): + rationalizers.HandleCommitErrors(rerr) + + } +} + +func (i *Install) getSuggestions(req *requirement, languages []model.Language) ([]string, error) { + ingredients, err := model.SearchIngredients(req.Requested.Namespace, req.Requested.Name, false, nil, i.prime.Auth()) + if err != nil { + return []string{}, locale.WrapError(err, "err_package_ingredient_search", "Failed to resolve ingredient named: {{.V0}}", req.Requested.Name) + } + + // Filter out irrelevant ingredients + if req.Requested.Namespace == "" { + // Filter out ingredients that don't target one of the supported languages + ingredients = sliceutils.Filter(ingredients, func(iv *model.IngredientAndVersion) bool { + if !model.NamespaceMatch(*iv.Ingredient.PrimaryNamespace, i.nsType.Matchable()) { + return false + } + il := model.LanguageFromNamespace(*iv.Ingredient.PrimaryNamespace) + for _, l := range languages { + if l.Name == il { + return true + } + } + return false + }) + } + + suggestions := []string{} + for _, ing := range ingredients { + suggestions = append(suggestions, fmt.Sprintf(" - %s/%s", *ing.Ingredient.PrimaryNamespace, *ing.Ingredient.Name)) + } + + maxResults := 5 + if len(suggestions) > maxResults { + suggestions = suggestions[:maxResults] + } + + return suggestions, nil +} diff --git a/internal/runners/invite/role.go b/internal/runners/invite/role.go index be4bc58237..f90d16f7de 100644 --- a/internal/runners/invite/role.go +++ b/internal/runners/invite/role.go @@ -46,7 +46,7 @@ func (r *Role) Set(v string) error { *r = Member default: *r = Unknown - return locale.NewInputError("err_invite_invalid_role", "Invalid role: {{.V0}}, should be one of: {{.V1}}", v, strings.Join(roleNames(), ", ")) + return locale.NewInputError("err_invite_invalid_role", "Invalid role: '{{.V0}}'. Should be one of: {{.V1}}", v, strings.Join(roleNames(), ", ")) } return nil } diff --git a/internal/runners/languages/install.go b/internal/runners/languages/install.go deleted file mode 100644 index 21e20f09df..0000000000 --- a/internal/runners/languages/install.go +++ /dev/null @@ -1,101 +0,0 @@ -package languages - -import ( - "strings" - - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/internal/runbits/requirements" - "github.com/ActiveState/cli/pkg/platform/authentication" - "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/project" -) - -type Update struct { - prime primeable -} - -type primeable interface { - primer.Outputer - primer.Prompter - primer.Projecter - primer.Auther - primer.Configurer - primer.Analyticer - primer.SvcModeler -} - -func NewUpdate(prime primeable) *Update { - return &Update{ - prime: prime, - } -} - -type UpdateParams struct { - Language string -} - -func (u *Update) Run(params *UpdateParams) error { - lang, err := parseLanguage(params.Language) - if err != nil { - return err - } - - if u.prime.Project() == nil { - return rationalize.ErrNoProject - } - - err = ensureLanguageProject(lang, u.prime.Project(), u.prime.Auth()) - if err != nil { - return err - } - - op := requirements.NewRequirementOperation(u.prime) - return op.ExecuteRequirementOperation(nil, &requirements.Requirement{ - Name: lang.Name, - Version: lang.Version, - NamespaceType: &model.NamespaceLanguage, - Operation: types.OperationAdded, - }) -} - -func parseLanguage(langName string) (*model.Language, error) { - if !strings.Contains(langName, "@") { - return &model.Language{ - Name: langName, - Version: "", - }, nil - } - - split := strings.Split(langName, "@") - if len(split) != 2 { - return nil, locale.NewError("err_language_format") - } - name := split[0] - version := split[1] - - return &model.Language{ - Name: name, - Version: version, - }, nil -} - -func ensureLanguageProject(language *model.Language, project *project.Project, auth *authentication.Auth) error { - targetCommitID, err := model.BranchCommitID(project.Owner(), project.Name(), project.BranchName()) - if err != nil { - return err - } - - platformLanguage, err := model.FetchLanguageForCommit(*targetCommitID, auth) - if err != nil { - return err - } - - if platformLanguage.Name != language.Name { - return locale.NewInputError("err_language_mismatch") - } - return nil -} diff --git a/internal/runners/languages/install_test.go b/internal/runners/languages/install_test.go deleted file mode 100644 index b41d0f6aaa..0000000000 --- a/internal/runners/languages/install_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package languages - -import ( - "reflect" - "testing" - - "github.com/ActiveState/cli/pkg/platform/model" -) - -func Test_parseLanguage(t *testing.T) { - type args struct { - langName string - } - tests := []struct { - name string - args args - want *model.Language - wantErr bool - }{ - { - "Language with version", - args{"Python@2"}, - &model.Language{Name: "Python", Version: "2"}, - false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := parseLanguage(tt.args.langName) - if (err != nil) != tt.wantErr { - t.Errorf("parseLanguage() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("parseLanguage() got = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/internal/runners/languages/languages.go b/internal/runners/languages/languages.go index 6056cf8363..5e9658f04f 100644 --- a/internal/runners/languages/languages.go +++ b/internal/runners/languages/languages.go @@ -7,6 +7,7 @@ import ( "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/pkg/buildplan" "github.com/ActiveState/cli/pkg/localcommit" @@ -16,6 +17,16 @@ import ( "github.com/ActiveState/cli/pkg/project" ) +type primeable interface { + primer.Outputer + primer.Prompter + primer.Projecter + primer.Auther + primer.Configurer + primer.Analyticer + primer.SvcModeler +} + // Languages manages the listing execution context. type Languages struct { out output.Outputer @@ -63,7 +74,7 @@ func (l *Languages) Run() error { locale.WrapError( err, "err_languages_no_commitid", - "Your project runtime does not have a commit defined, you may need to run '[ACTIONABLE]state pull[/RESET]' first.", + "Your project runtime does not have a commit defined. You may need to run '[ACTIONABLE]state pull[/RESET]' first.", ), locale.Tl( "languages_no_commitid_help", @@ -78,7 +89,7 @@ func (l *Languages) Run() error { } // Fetch commit and buildplan, which will give us access to ingredients, and ingredients can be languages.. - bpm := bpModel.NewBuildPlannerModel(l.auth) + bpm := bpModel.NewBuildPlannerModel(l.auth, l.svcModel) commit, err := bpm.FetchCommit(commitID, l.project.Owner(), l.project.Name(), nil) if err != nil { return errs.Wrap(err, "could not fetch commit") diff --git a/internal/runners/manifest/manifest.go b/internal/runners/manifest/manifest.go index fd0d1d55e7..19765d7257 100644 --- a/internal/runners/manifest/manifest.go +++ b/internal/runners/manifest/manifest.go @@ -1,38 +1,43 @@ package manifest import ( - "os" - "strings" - "github.com/ActiveState/cli/internal/analytics" "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" + buildscript_runbit "github.com/ActiveState/cli/internal/runbits/buildscript" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/buildscript" "github.com/ActiveState/cli/pkg/localcommit" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" "github.com/ActiveState/cli/pkg/platform/api/vulnerabilities/request" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/platform/runtime" - "github.com/ActiveState/cli/pkg/platform/runtime/target" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" "github.com/ActiveState/cli/pkg/project" ) type primeable interface { - Output() output.Outputer - Project() *project.Project - Auth() *authentication.Auth - Analytics() analytics.Dispatcher - SvcModel() *model.SvcModel - Config() *config.Instance + primer.Outputer + primer.Projecter + primer.Auther + primer.Analyticer + primer.SvcModeler + primer.Configurer +} + +type Params struct { + Expand bool } type Manifest struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 out output.Outputer project *project.Project auth *authentication.Auth @@ -43,17 +48,18 @@ type Manifest struct { func NewManifest(prime primeable) *Manifest { return &Manifest{ - out: prime.Output(), - project: prime.Project(), - auth: prime.Auth(), - analytics: prime.Analytics(), - svcModel: prime.SvcModel(), - cfg: prime.Config(), + prime, + prime.Output(), + prime.Project(), + prime.Auth(), + prime.Analytics(), + prime.SvcModel(), + prime.Config(), } } -func (m *Manifest) Run() (rerr error) { - defer rationalizeError(&rerr) +func (m *Manifest) Run(params Params) (rerr error) { + defer rationalizeError(m.project, m.auth, &rerr) if m.project == nil { return rationalize.ErrNoProject @@ -71,12 +77,17 @@ func (m *Manifest) Run() (rerr error) { return errs.Wrap(err, "Could not fetch artifacts") } - vulns, err := m.fetchVulnerabilities(reqs) + vulns, err := m.fetchVulnerabilities(reqs, bpReqs) if err != nil { return errs.Wrap(err, "Could not fetch vulnerabilities") } - m.out.Print(newRequirements(reqs, bpReqs, vulns)) + reqOut := newRequirements(reqs, bpReqs, vulns, !m.out.Type().IsStructured(), params.Expand) + if m.out.Type().IsStructured() { + m.out.Print(reqOut) + } else { + reqOut.Print(m.out) + } if len(vulns) > 0 { m.out.Notice(locale.Tl("manifest_vulnerabilities_info", "\nFor CVE info run '[ACTIONABLE]state security[/RESET]'")) @@ -85,16 +96,25 @@ func (m *Manifest) Run() (rerr error) { return nil } -func (m *Manifest) fetchRequirements() ([]types.Requirement, error) { - commitID, err := localcommit.Get(m.project.Dir()) - if err != nil { - return nil, errs.Wrap(err, "Could not get commit ID") - } +func (m *Manifest) fetchRequirements() ([]buildscript.Requirement, error) { + var script *buildscript.BuildScript + if m.cfg.GetBool(constants.OptinBuildscriptsConfig) { + var err error + script, err = buildscript_runbit.ScriptFromProject(m.project) + if err != nil { + return nil, errs.Wrap(err, "Could not get buildscript") + } + } else { + commitID, err := localcommit.Get(m.project.Dir()) + if err != nil { + return nil, errs.Wrap(err, "Could not get commit ID") + } - bp := buildplanner.NewBuildPlannerModel(m.auth) - script, err := bp.GetBuildScript(commitID.String()) - if err != nil { - return nil, errs.Wrap(err, "Could not get remote build expr and time") + bp := bpModel.NewBuildPlannerModel(m.auth, m.svcModel) + script, err = bp.GetBuildScript(commitID.String()) + if err != nil { + return nil, errs.Wrap(err, "Could not get remote build expr and time") + } } reqs, err := script.Requirements() @@ -106,34 +126,34 @@ func (m *Manifest) fetchRequirements() ([]types.Requirement, error) { } func (m *Manifest) fetchBuildplanRequirements() (buildplan.Ingredients, error) { - if strings.EqualFold(os.Getenv(constants.DisableRuntime), "true") { - return nil, nil - } - - target := target.NewProjectTarget(m.project, nil, target.TriggerManifest) - rt, err := runtime.New(target, m.analytics, m.svcModel, m.auth, m.cfg, m.out) + commitID, err := localcommit.Get(m.project.Dir()) if err != nil { - return nil, locale.WrapError(err, "err_packages_update_runtime_init", "Could not initialize runtime.") - } - - if rt.NeedsUpdate() { - m.out.Notice(locale.T("manifest_runtime_needs_update")) + return nil, errs.Wrap(err, "Failed to get local commit") } - bp, err := rt.BuildPlan() + // Solve runtime + solveSpinner := output.StartSpinner(m.out, locale.T("progress_solve"), constants.TerminalAnimationInterval) + bpm := bpModel.NewBuildPlannerModel(m.auth, m.svcModel) + commit, err := bpm.FetchCommit(commitID, m.project.Owner(), m.project.Name(), nil) if err != nil { - return nil, errs.Wrap(err, "could not get build plan") + solveSpinner.Stop(locale.T("progress_fail")) + return nil, errs.Wrap(err, "Failed to fetch build result") } + solveSpinner.Stop(locale.T("progress_success")) - return bp.RequestedIngredients(), nil + return commit.BuildPlan().RequestedIngredients(), nil } -func (m *Manifest) fetchVulnerabilities(reqs []types.Requirement) (vulnerabilities, error) { +func (m *Manifest) fetchVulnerabilities(reqs []buildscript.Requirement, bpReqs buildplan.Ingredients) (vulnerabilities, error) { vulns := make(vulnerabilities) if !m.auth.Authenticated() { for _, req := range reqs { - vulns.addVulnerability(req.Name, req.Namespace, &requirementVulnerabilities{ + r, ok := req.(buildscript.DependencyRequirement) + if !ok { + continue + } + vulns.add(r.Name, r.Namespace, &requirementVulnerabilities{ authenticated: false, }) } @@ -143,13 +163,22 @@ func (m *Manifest) fetchVulnerabilities(reqs []types.Requirement) (vulnerabiliti var ingredients []*request.Ingredient for _, req := range reqs { var version string - if req.VersionRequirement != nil { - version = model.BuildPlannerVersionConstraintsToString(req.VersionRequirement) + r, ok := req.(buildscript.DependencyRequirement) + if !ok { + // We can't report vulnerabilities on revisions because they don't supply a namespace. + // https://activestatef.atlassian.net/browse/PB-5165 + continue + } + resolvedVersion := resolveVersion(r.Requirement, bpReqs) + if resolvedVersion.Resolved == "" { + version = resolvedVersion.Requested + } else { + version = resolvedVersion.Resolved } ingredients = append(ingredients, &request.Ingredient{ - Name: req.Name, - Namespace: req.Namespace, + Name: r.Name, + Namespace: r.Namespace, Version: version, }) } @@ -160,7 +189,7 @@ func (m *Manifest) fetchVulnerabilities(reqs []types.Requirement) (vulnerabiliti } for _, vuln := range ingredientVulnerabilities { - vulns.addVulnerability(vuln.Name, vuln.PrimaryNamespace, &requirementVulnerabilities{ + vulns.add(vuln.Name, vuln.PrimaryNamespace, &requirementVulnerabilities{ Count: vuln.Vulnerabilities.Count(), authenticated: true, }) diff --git a/internal/runners/manifest/rationalize.go b/internal/runners/manifest/rationalize.go index f50c5950cf..ffe042aabd 100644 --- a/internal/runners/manifest/rationalize.go +++ b/internal/runners/manifest/rationalize.go @@ -1,32 +1,17 @@ package manifest import ( - "errors" - - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/pkg/platform/runtime/store" + runtime_runbit "github.com/ActiveState/cli/internal/runbits/runtime" + auth "github.com/ActiveState/cli/pkg/platform/authentication" + "github.com/ActiveState/cli/pkg/project" ) -func rationalizeError(rerr *error) { +func rationalizeError(proj *project.Project, auth *auth.Auth, rerr *error) { switch { case rerr == nil: return - - // No activestate.yaml. - case errors.Is(*rerr, rationalize.ErrNoProject): - *rerr = errs.WrapUserFacing(*rerr, - locale.T("err_no_project"), - errs.SetInput(), - ) - case errors.Is(*rerr, store.ErrNoBuildPlanFile): - *rerr = errs.WrapUserFacing(*rerr, - locale.Tl( - "err_manifest_no_build_plan_file", - "Could not source runtime. Please ensure your runtime is up to date by running '[ACTIONABLE]state refresh[/RESET]'.", - ), - errs.SetInput(), - ) + default: + runtime_runbit.RationalizeSolveError(proj, auth, rerr) + return } } diff --git a/internal/runners/manifest/requirements.go b/internal/runners/manifest/requirements.go index bba04b8136..c85cd6b1a1 100644 --- a/internal/runners/manifest/requirements.go +++ b/internal/runners/manifest/requirements.go @@ -1,10 +1,12 @@ package manifest import ( + "fmt" + "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/pkg/buildplan" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/ActiveState/cli/pkg/buildscript" platformModel "github.com/ActiveState/cli/pkg/platform/model" ) @@ -16,24 +18,45 @@ type requirement struct { } type requirements struct { - Requirements []*requirement `json:"requirements"` + Requirements []requirement `json:"requirements"` + UnknownRequirements []buildscript.UnknownRequirement `json:"unknown_requirements,omitempty"` + expand bool // Whether to show requirements by their full namespace } -func newRequirements(reqs []types.Requirement, bpReqs buildplan.Ingredients, vulns vulnerabilities) requirements { - var result []*requirement +func newRequirements(reqs []buildscript.Requirement, bpReqs buildplan.Ingredients, vulns vulnerabilities, shortRevIDs bool, expand bool) requirements { + var knownReqs []requirement + var unknownReqs []buildscript.UnknownRequirement for _, req := range reqs { - result = append(result, &requirement{ - Name: req.Name, - Namespace: processNamespace(req.Namespace), - ResolvedVersion: resolveVersion(req, bpReqs), - Vulnerabilities: vulns.getVulnerability(req.Name, req.Namespace), - }) + switch r := req.(type) { + case buildscript.DependencyRequirement: + knownReqs = append(knownReqs, requirement{ + Name: r.Name, + Namespace: r.Namespace, + ResolvedVersion: resolveVersion(r.Requirement, bpReqs), + Vulnerabilities: vulns.get(r.Name, r.Namespace), + }) + case buildscript.RevisionRequirement: + revID := r.RevisionID.String() + if shortRevIDs && len(revID) > 8 { + revID = revID[0:8] + } + knownReqs = append(knownReqs, requirement{ + Name: r.Name, + ResolvedVersion: &resolvedVersion{Requested: revID}, + }) + case buildscript.UnknownRequirement: + unknownReqs = append(unknownReqs, r) + } } - return requirements{Requirements: result} + return requirements{ + Requirements: knownReqs, + UnknownRequirements: unknownReqs, + expand: expand, + } } -func (o requirements) MarshalOutput(_ output.Format) interface{} { +func (o requirements) Print(out output.Outputer) { type requirementOutput struct { Name string `locale:"manifest_name,Name"` Version string `locale:"manifest_version,Version"` @@ -44,24 +67,41 @@ func (o requirements) MarshalOutput(_ output.Format) interface{} { var requirementsOutput []*requirementOutput for _, req := range o.Requirements { + name := req.Name + if o.expand && req.Namespace != "" { + name = req.Namespace + "/" + req.Name + } requirementOutput := &requirementOutput{ - Name: locale.Tl("manifest_name", "[ACTIONABLE]{{.V0}}[/RESET]", req.Name), + Name: fmt.Sprintf("[ACTIONABLE]%s[/RESET]", name), Version: req.ResolvedVersion.String(), Vulnerabilities: req.Vulnerabilities.String(), } - if req.Namespace != "" { - requirementOutput.Namespace = locale.Tl("manifest_namespace", " └─ [DISABLED]namespace:[/RESET] [CYAN]{{.V0}}[/RESET]", req.Namespace) + if isCustomNamespace(req.Namespace) { + requirementOutput.Namespace = locale.Tr("namespace_row", output.TreeEnd, req.Namespace) } requirementsOutput = append(requirementsOutput, requirementOutput) } - return struct { - Requirements []*requirementOutput `locale:"," opts:"hideDash"` + out.Print("") // blank line + out.Print(struct { + Requirements []*requirementOutput `locale:"," opts:"hideDash,omitKey"` }{ Requirements: requirementsOutput, + }) + + if len(o.UnknownRequirements) > 0 { + out.Notice("") + out.Notice(locale.Tt("warn_additional_requirements")) + out.Notice("") + out.Print(struct { + Requirements []buildscript.UnknownRequirement `locale:"," opts:"hideDash,omitKey"` + }{ + Requirements: o.UnknownRequirements, + }) } + } func (o requirements) MarshalStructured(f output.Format) interface{} { @@ -76,14 +116,6 @@ func (o requirements) MarshalStructured(f output.Format) interface{} { return o } -func processNamespace(namespace string) string { - if !isCustomNamespace(namespace) { - return "" - } - - return namespace -} - func isCustomNamespace(ns string) bool { supportedNamespaces := []platformModel.NamespaceType{ platformModel.NamespacePackage, diff --git a/internal/runners/manifest/version.go b/internal/runners/manifest/version.go index 6fc6a56458..ee15f52eea 100644 --- a/internal/runners/manifest/version.go +++ b/internal/runners/manifest/version.go @@ -37,14 +37,14 @@ func resolveVersion(req types.Requirement, bpReqs buildplan.Ingredients) *resolv var resolved string if req.VersionRequirement != nil { - requested = platformModel.BuildPlannerVersionConstraintsToString(req.VersionRequirement) + requested = platformModel.VersionRequirementsToString(req.VersionRequirement, true) } else { requested = locale.Tl("manifest_version_auto", "auto") - for _, bpr := range bpReqs { - if bpr.Namespace == req.Namespace && bpr.Name == req.Name { - resolved = bpr.Version - break - } + } + for _, bpr := range bpReqs { + if bpr.Namespace == req.Namespace && bpr.Name == req.Name { + resolved = bpr.Version + break } } diff --git a/internal/runners/manifest/vulnerabilities.go b/internal/runners/manifest/vulnerabilities.go index 259e8e57b9..df03e1d007 100644 --- a/internal/runners/manifest/vulnerabilities.go +++ b/internal/runners/manifest/vulnerabilities.go @@ -48,10 +48,10 @@ func (v *requirementVulnerabilities) String() string { type vulnerabilities map[string]*requirementVulnerabilities -func (v vulnerabilities) getVulnerability(name, namespace string) *requirementVulnerabilities { +func (v vulnerabilities) get(name, namespace string) *requirementVulnerabilities { return v[fmt.Sprintf("%s/%s", namespace, name)] } -func (v vulnerabilities) addVulnerability(name, namespace string, vulns *requirementVulnerabilities) { +func (v vulnerabilities) add(name, namespace string, vulns *requirementVulnerabilities) { v[fmt.Sprintf("%s/%s", namespace, name)] = vulns } diff --git a/internal/runners/packages/import.go b/internal/runners/packages/import.go index 4cbb6230a5..ef7f4436ea 100644 --- a/internal/runners/packages/import.go +++ b/internal/runners/packages/import.go @@ -1,38 +1,34 @@ package packages import ( + "fmt" "os" - "github.com/ActiveState/cli/internal/analytics" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/keypairs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/prompt" + "github.com/ActiveState/cli/internal/runbits/cves" + "github.com/ActiveState/cli/internal/runbits/dependencies" + "github.com/ActiveState/cli/internal/runbits/org" "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/internal/runbits/runtime" + runtime_runbit "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/pkg/buildscript" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/api" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" "github.com/ActiveState/cli/pkg/platform/api/reqsimport" - "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/platform/runtime/target" - "github.com/ActiveState/cli/pkg/project" ) const ( defaultImportFile = "requirements.txt" ) -type configurable interface { - keypairs.Configurable -} - // Confirmer describes the behavior required to prompt a user for confirmation. type Confirmer interface { Confirm(title, msg string, defaultOpt *bool) (bool, error) @@ -61,13 +57,7 @@ func NewImportRunParams() *ImportRunParams { // Import manages the importing execution context. type Import struct { - auth *authentication.Auth - out output.Outputer - prompt.Prompter - proj *project.Project - cfg configurable - analytics analytics.Dispatcher - svcModel *model.SvcModel + prime primeable } type primeable interface { @@ -82,79 +72,102 @@ type primeable interface { // NewImport prepares an importation execution context for use. func NewImport(prime primeable) *Import { - return &Import{ - prime.Auth(), - prime.Output(), - prime.Prompt(), - prime.Project(), - prime.Config(), - prime.Analytics(), - prime.SvcModel(), - } + return &Import{prime} } // Run executes the import behavior. -func (i *Import) Run(params *ImportRunParams) error { +func (i *Import) Run(params *ImportRunParams) (rerr error) { + defer rationalizeError(i.prime.Auth(), &rerr) logging.Debug("ExecuteImport") - if i.proj == nil { + proj := i.prime.Project() + if proj == nil { return rationalize.ErrNoProject } - i.out.Notice(locale.Tr("operating_message", i.proj.NamespaceString(), i.proj.Dir())) + out := i.prime.Output() + out.Notice(locale.Tr("operating_message", proj.NamespaceString(), proj.Dir())) if params.FileName == "" { params.FileName = defaultImportFile } - latestCommit, err := localcommit.Get(i.proj.Dir()) + localCommitId, err := localcommit.Get(proj.Dir()) if err != nil { return locale.WrapError(err, "package_err_cannot_obtain_commit") } - reqs, err := fetchCheckpoint(&latestCommit, i.auth) + auth := i.prime.Auth() + language, err := model.LanguageByCommit(localCommitId, auth) if err != nil { - return locale.WrapError(err, "package_err_cannot_fetch_checkpoint") + return locale.WrapError(err, "err_import_language", "Unable to get language from project") } - lang, err := model.CheckpointToLanguage(reqs, i.auth) - if err != nil { - return locale.WrapExternalError(err, "err_import_language", "Your project does not have a language associated with it, please add a language first.") - } + pg := output.StartSpinner(i.prime.Output(), locale.T("progress_solve_preruntime"), constants.TerminalAnimationInterval) + defer func() { + if pg != nil { + pg.Stop(locale.T("progress_fail")) + } + }() - changeset, err := fetchImportChangeset(reqsimport.Init(), params.FileName, lang.Name) + changeset, err := fetchImportChangeset(reqsimport.Init(), params.FileName, language.Name) if err != nil { return errs.Wrap(err, "Could not import changeset") } - bp := buildplanner.NewBuildPlannerModel(i.auth) - bs, err := bp.GetBuildScript(latestCommit.String()) + bp := buildplanner.NewBuildPlannerModel(auth, i.prime.SvcModel()) + bs, err := bp.GetBuildScript(localCommitId.String()) if err != nil { return locale.WrapError(err, "err_cannot_get_build_expression", "Could not get build expression") } - if err := applyChangeset(changeset, bs); err != nil { + if err := i.applyChangeset(changeset, bs); err != nil { return locale.WrapError(err, "err_cannot_apply_changeset", "Could not apply changeset") } msg := locale.T("commit_reqstext_message") - commitID, err := bp.StageCommit(buildplanner.StageCommitParams{ - Owner: i.proj.Owner(), - Project: i.proj.Name(), - ParentCommit: latestCommit.String(), + stagedCommit, err := bp.StageCommit(buildplanner.StageCommitParams{ + Owner: proj.Owner(), + Project: proj.Name(), + ParentCommit: localCommitId.String(), Description: msg, Script: bs, }) + // Always update the local commit ID even if the commit fails to build + if stagedCommit != nil && stagedCommit.Commit != nil && stagedCommit.Commit.CommitID != "" { + if err := localcommit.Set(proj.Dir(), stagedCommit.CommitID.String()); err != nil { + return locale.WrapError(err, "err_package_update_commit_id") + } + } if err != nil { return locale.WrapError(err, "err_commit_changeset", "Could not commit import changes") } - if err := localcommit.Set(i.proj.Dir(), commitID.String()); err != nil { - return locale.WrapError(err, "err_package_update_commit_id") + // Output change summary. + previousCommit, err := bp.FetchCommit(localCommitId, proj.Owner(), proj.Name(), nil) + if err != nil { + return errs.Wrap(err, "Failed to fetch build result for previous commit") + } + + pg.Stop(locale.T("progress_success")) + pg = nil + + dependencies.OutputChangeSummary(i.prime.Output(), stagedCommit.BuildPlan(), previousCommit.BuildPlan()) + + // Report CVEs. + if err := cves.NewCveReport(i.prime).Report(stagedCommit.BuildPlan(), previousCommit.BuildPlan()); err != nil { + return errs.Wrap(err, "Could not report CVEs") + } + + out.Notice("") // blank line + _, err = runtime_runbit.Update(i.prime, trigger.TriggerImport, runtime_runbit.WithCommitID(stagedCommit.CommitID)) + if err != nil { + return errs.Wrap(err, "Runtime update failed") } - _, err = runtime.SolveAndUpdate(i.auth, i.out, i.analytics, i.proj, &commitID, target.TriggerImport, i.svcModel, i.cfg, runtime.OptOrderChanged) - return err + out.Notice(locale.Tl("import_finished", "Import Finished")) + + return nil } func fetchImportChangeset(cp ChangesetProvider, file string, lang string) (model.Changeset, error) { @@ -171,7 +184,7 @@ func fetchImportChangeset(cp ChangesetProvider, file string, lang string) (model return changeset, err } -func applyChangeset(changeset model.Changeset, bs *buildscript.BuildScript) error { +func (i *Import) applyChangeset(changeset model.Changeset, bs *buildscript.BuildScript) error { for _, change := range changeset { var expressionOperation types.Operation switch change.Operation { @@ -183,9 +196,21 @@ func applyChangeset(changeset model.Changeset, bs *buildscript.BuildScript) erro expressionOperation = types.OperationUpdated } + namespace := change.Namespace + if namespace == "" { + if !i.prime.Auth().Authenticated() { + return rationalize.ErrNotAuthenticated + } + name, err := org.Get("", i.prime.Auth(), i.prime.Config()) + if err != nil { + return errs.Wrap(err, "Unable to get an org for the user") + } + namespace = fmt.Sprintf("%s/%s", constants.PlatformPrivateNamespace, name) + } + req := types.Requirement{ Name: change.Requirement, - Namespace: change.Namespace, + Namespace: namespace, } for _, constraint := range change.VersionConstraints { diff --git a/internal/runners/packages/info.go b/internal/runners/packages/info.go index f81a4f63e1..2366cae3ff 100644 --- a/internal/runners/packages/info.go +++ b/internal/runners/packages/info.go @@ -12,6 +12,7 @@ import ( "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/runbits/commits_runbit" "github.com/ActiveState/cli/pkg/platform/api/inventory/inventory_models" "github.com/ActiveState/cli/pkg/platform/api/vulnerabilities/request" "github.com/ActiveState/cli/pkg/platform/authentication" @@ -51,7 +52,7 @@ func (i *Info) Run(params InfoRunParams, nstype model.NamespaceType) error { var ns *model.Namespace if params.Package.Namespace != "" { - ns = ptr.To(model.NewRawNamespace(params.Package.Namespace)) + ns = ptr.To(model.NewNamespaceRaw(params.Package.Namespace)) } else { nsTypeV = &nstype } @@ -70,12 +71,12 @@ func (i *Info) Run(params InfoRunParams, nstype model.NamespaceType) error { normalized = params.Package.Name } - ts, err := getTime(¶ms.Timestamp, i.auth, i.proj) + ts, err := commits_runbit.ExpandTimeForProject(¶ms.Timestamp, i.auth, i.proj) if err != nil { return errs.Wrap(err, "Unable to get timestamp from params") } - packages, err := model.SearchIngredientsStrict(ns.String(), normalized, false, false, ts, i.auth) // ideally case-sensitive would be true (PB-4371) + packages, err := model.SearchIngredientsStrict(ns.String(), normalized, false, false, &ts, i.auth) // ideally case-sensitive would be true (PB-4371) if err != nil { return locale.WrapError(err, "package_err_cannot_obtain_search_results") } diff --git a/internal/runners/packages/install.go b/internal/runners/packages/install.go deleted file mode 100644 index 520f759ea1..0000000000 --- a/internal/runners/packages/install.go +++ /dev/null @@ -1,60 +0,0 @@ -package packages - -import ( - "github.com/ActiveState/cli/internal/captain" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/ActiveState/cli/internal/runbits/requirements" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/ActiveState/cli/pkg/platform/model" -) - -// InstallRunParams tracks the info required for running Install. -type InstallRunParams struct { - Packages captain.PackagesValue - Timestamp captain.TimeValue - Revision captain.IntValue -} - -// Install manages the installing execution context. -type Install struct { - prime primeable -} - -// NewInstall prepares an installation execution context for use. -func NewInstall(prime primeable) *Install { - return &Install{prime} -} - -// Run executes the install behavior. -func (a *Install) Run(params InstallRunParams, nsType model.NamespaceType) (rerr error) { - defer rationalizeError(a.prime.Auth(), &rerr) - - logging.Debug("ExecuteInstall") - var reqs []*requirements.Requirement - for _, p := range params.Packages { - req := &requirements.Requirement{ - Name: p.Name, - Version: p.Version, - Operation: types.OperationAdded, - } - - if p.Namespace != "" { - req.Namespace = ptr.To(model.NewRawNamespace(p.Namespace)) - } else { - req.NamespaceType = &nsType - } - - req.Revision = params.Revision.Int - - reqs = append(reqs, req) - } - - ts, err := getTime(¶ms.Timestamp, a.prime.Auth(), a.prime.Project()) - if err != nil { - return errs.Wrap(err, "Unable to get timestamp from params") - } - - return requirements.NewRequirementOperation(a.prime).ExecuteRequirementOperation(ts, reqs...) -} diff --git a/internal/runners/packages/list.go b/internal/runners/packages/list.go index 993858cb64..30aaea006a 100644 --- a/internal/runners/packages/list.go +++ b/internal/runners/packages/list.go @@ -112,7 +112,7 @@ func (l *List) Run(params ListRunParams, nstype model.NamespaceType) error { // Fetch resolved artifacts list for showing full version numbers, if possible. var artifacts buildplan.Artifacts if l.project != nil && params.Project == "" { - bpm := bpModel.NewBuildPlannerModel(l.auth) + bpm := bpModel.NewBuildPlannerModel(l.auth, l.svcModel) commit, err := bpm.FetchCommit(*commitID, l.project.Owner(), l.project.Name(), nil) if err != nil { return errs.Wrap(err, "could not fetch commit") @@ -139,7 +139,7 @@ func (l *List) Run(params ListRunParams, nstype model.NamespaceType) error { version := req.VersionConstraint if version == "" { - version = model.GqlReqVersionConstraintsString(req) + version = model.GqlReqVersionConstraintsString(req, false) if version == "" { version = locale.T("constraint_auto") } diff --git a/internal/runners/packages/rationalize.go b/internal/runners/packages/rationalize.go index b1ed74ad38..ccf6503943 100644 --- a/internal/runners/packages/rationalize.go +++ b/internal/runners/packages/rationalize.go @@ -6,9 +6,9 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/internal/runbits/rationalizers" "github.com/ActiveState/cli/pkg/buildscript" bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" "github.com/ActiveState/cli/pkg/platform/authentication" ) @@ -29,35 +29,7 @@ func rationalizeError(auth *authentication.Auth, err *error) { // Error staging a commit during install. case errors.As(*err, &commitError): - switch commitError.Type { - case types.NotFoundErrorType: - *err = errs.WrapUserFacing(*err, - locale.Tl("err_packages_not_found", "Could not make runtime changes because your project was not found."), - errs.SetInput(), - errs.SetTips(locale.T("tip_private_project_auth")), - ) - case types.ForbiddenErrorType: - *err = errs.WrapUserFacing(*err, - locale.Tl("err_packages_forbidden", "Could not make runtime changes because you do not have permission to do so."), - errs.SetInput(), - errs.SetTips(locale.T("tip_private_project_auth")), - ) - case types.HeadOnBranchMovedErrorType: - *err = errs.WrapUserFacing(*err, - locale.T("err_buildplanner_head_on_branch_moved"), - errs.SetInput(), - ) - case types.NoChangeSinceLastCommitErrorType: - *err = errs.WrapUserFacing(*err, - locale.Tl("err_packages_exists", "That package is already installed."), - errs.SetInput(), - ) - default: - *err = errs.WrapUserFacing(*err, - locale.Tl("err_packages_buildplanner_error", "Could not make runtime changes due to the following error: {{.V0}}", commitError.Message), - errs.SetInput(), - ) - } + rationalizers.HandleCommitErrors(err) // Requirement not found for uninstall. case errors.As(*err, &requirementNotFoundErr): @@ -65,5 +37,11 @@ func rationalizeError(auth *authentication.Auth, err *error) { locale.Tr("err_remove_requirement_not_found", requirementNotFoundErr.Name), errs.SetInput(), ) + + case errors.Is(*err, rationalize.ErrNotAuthenticated): + *err = errs.WrapUserFacing(*err, + locale.Tl("err_import_unauthenticated", "Could not import requirements into a private namespace because you are not authenticated. Please authenticate using '[ACTIONABLE]state auth[/RESET]' and try again."), + errs.SetInput(), + ) } } diff --git a/internal/runners/packages/search.go b/internal/runners/packages/search.go index ce077506a2..6af93400cf 100644 --- a/internal/runners/packages/search.go +++ b/internal/runners/packages/search.go @@ -8,6 +8,7 @@ import ( "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/runbits/commits_runbit" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/api/vulnerabilities/request" "github.com/ActiveState/cli/pkg/platform/authentication" @@ -55,19 +56,19 @@ func (s *Search) Run(params SearchRunParams, nstype model.NamespaceType) error { ns = model.NewNamespacePkgOrBundle(language, nstype) } else { - ns = model.NewRawNamespace(params.Ingredient.Namespace) + ns = model.NewNamespaceRaw(params.Ingredient.Namespace) } - ts, err := getTime(¶ms.Timestamp, s.auth, s.proj) + ts, err := commits_runbit.ExpandTimeForProject(¶ms.Timestamp, s.auth, s.proj) if err != nil { return errs.Wrap(err, "Unable to get timestamp from params") } var packages []*model.IngredientAndVersion if params.ExactTerm { - packages, err = model.SearchIngredientsLatestStrict(ns.String(), params.Ingredient.Name, true, true, ts, s.auth) + packages, err = model.SearchIngredientsLatestStrict(ns.String(), params.Ingredient.Name, true, true, &ts, s.auth) } else { - packages, err = model.SearchIngredientsLatest(ns.String(), params.Ingredient.Name, true, ts, s.auth) + packages, err = model.SearchIngredientsLatest(ns.String(), params.Ingredient.Name, true, &ts, s.auth) } if err != nil { return locale.WrapError(err, "package_err_cannot_obtain_search_results") diff --git a/internal/runners/packages/searchView.go b/internal/runners/packages/searchView.go index 1719ac95a0..040bb71ec7 100644 --- a/internal/runners/packages/searchView.go +++ b/internal/runners/packages/searchView.go @@ -203,7 +203,7 @@ func (v *view) processContent() string { func (v *view) footerView() string { var footerText string scrollValue := v.viewport.ScrollPercent() * 100 - footerText += locale.Tl("search_more_matches", "... {{.V0}}% scrolled, use arrow and page keys to scroll. Press Q to quit.", strconv.Itoa(int(scrollValue))) + footerText += locale.Tl("search_more_matches", "... {{.V0}}% scrolled. Use arrow and page keys to scroll. Press Q to quit.", strconv.Itoa(int(scrollValue))) footerText += fmt.Sprintf("\n\n%s '%s'", colorize.StyleBold.Render(locale.Tl("search_more_info", "For more info run")), colorize.StyleActionable.Render(locale.Tl("search_more_info_command", "state info "))) return lipgloss.NewStyle().Render(footerText) } diff --git a/internal/runners/packages/time.go b/internal/runners/packages/time.go deleted file mode 100644 index 65923fda24..0000000000 --- a/internal/runners/packages/time.go +++ /dev/null @@ -1,51 +0,0 @@ -package packages - -import ( - "time" - - "github.com/ActiveState/cli/internal/captain" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/pkg/localcommit" - "github.com/ActiveState/cli/pkg/platform/authentication" - "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/project" -) - -// getTime returns a timestamp based on the given "--ts" value. -// If "now" was given, returns "now" according to the platform. -// If no timestamp was given but the current project's commit time is after the latest inventory -// timestamp, returns that commit time. -// Otherwise, returns the specified timestamp or nil (which falls back on the default Platform -// timestamp for a given operation) -func getTime(ts *captain.TimeValue, auth *authentication.Auth, proj *project.Project) (*time.Time, error) { - if ts.Now() { - latest, err := model.FetchLatestRevisionTimeStamp(auth) - if err != nil { - return nil, errs.Wrap(err, "Unable to determine latest revision time") - } - return &latest, nil - } - - if ts.Time == nil && proj != nil { - latest, err := model.FetchLatestTimeStamp(auth) - if err != nil { - return nil, errs.Wrap(err, "Unable to fetch latest Platform timestamp") - } - - commitID, err := localcommit.Get(proj.Dir()) - if err != nil { - return nil, errs.Wrap(err, "Unable to get commit ID") - } - - atTime, err := model.FetchTimeStampForCommit(commitID, auth) - if err != nil { - return nil, errs.Wrap(err, "Unable to get commit time") - } - - if atTime.After(latest) { - return atTime, nil - } - } - - return ts.Time, nil -} diff --git a/internal/runners/packages/uninstall.go b/internal/runners/packages/uninstall.go deleted file mode 100644 index 67f5dacdda..0000000000 --- a/internal/runners/packages/uninstall.go +++ /dev/null @@ -1,59 +0,0 @@ -package packages - -import ( - "github.com/ActiveState/cli/internal/captain" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/internal/runbits/requirements" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/ActiveState/cli/pkg/platform/model" -) - -// UninstallRunParams tracks the info required for running Uninstall. -type UninstallRunParams struct { - Packages captain.PackagesValueNoVersion -} - -// Uninstall manages the uninstalling execution context. -type Uninstall struct { - prime primeable -} - -// NewUninstall prepares an uninstallation execution context for use. -func NewUninstall(prime primeable) *Uninstall { - return &Uninstall{prime} -} - -// Run executes the uninstall behavior. -func (u *Uninstall) Run(params UninstallRunParams, nsType model.NamespaceType) (rerr error) { - defer rationalizeError(u.prime.Auth(), &rerr) - logging.Debug("ExecuteUninstall") - if u.prime.Project() == nil { - return rationalize.ErrNoProject - } - - var reqs []*requirements.Requirement - for _, p := range params.Packages { - req := &requirements.Requirement{ - Name: p.Name, - Operation: types.OperationRemoved, - } - - if p.Namespace != "" { - req.Namespace = ptr.To(model.NewRawNamespace(p.Namespace)) - } else { - req.NamespaceType = &nsType - } - - reqs = append(reqs, req) - } - - ts, err := getTime(&captain.TimeValue{}, u.prime.Auth(), u.prime.Project()) - if err != nil { - return errs.Wrap(err, "Unable to get timestamp from params") - } - - return requirements.NewRequirementOperation(u.prime).ExecuteRequirementOperation(ts, reqs...) -} diff --git a/internal/runners/platforms/add.go b/internal/runners/platforms/add.go index f3d741e946..3c194ff96f 100644 --- a/internal/runners/platforms/add.go +++ b/internal/runners/platforms/add.go @@ -1,13 +1,24 @@ package platforms import ( + "errors" + + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/runbits/commits_runbit" "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/internal/runbits/requirements" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/ActiveState/cli/internal/runbits/rationalizers" + "github.com/ActiveState/cli/internal/runbits/reqop_runbit" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" + "github.com/ActiveState/cli/pkg/localcommit" + bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" "github.com/ActiveState/cli/pkg/platform/model" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" ) // AddRunParams tracks the info required for running Add. @@ -38,32 +49,88 @@ func NewAdd(prime primeable) *Add { } // Run executes the add behavior. -func (a *Add) Run(ps AddRunParams) error { +func (a *Add) Run(params AddRunParams) (rerr error) { + defer rationalizeAddPlatformError(&rerr) + logging.Debug("Execute platforms add") - params, err := prepareParams(ps.Params) + if a.prime.Project() == nil { + return rationalize.ErrNoProject + } + + pj := a.prime.Project() + out := a.prime.Output() + bp := bpModel.NewBuildPlannerModel(a.prime.Auth(), a.prime.SvcModel()) + + var pg *output.Spinner + defer func() { + if pg != nil { + pg.Stop(locale.T("progress_fail")) + } + }() + + pg = output.StartSpinner(out, locale.T("progress_platform_search"), constants.TerminalAnimationInterval) + + // Grab local commit info + localCommitID, err := localcommit.Get(pj.Dir()) + if err != nil { + return errs.Wrap(err, "Unable to get local commit") + } + oldCommit, err := bp.FetchCommit(localCommitID, pj.Owner(), pj.Name(), nil) if err != nil { - return err + return errs.Wrap(err, "Failed to fetch old build result") } - if a.prime.Project() == nil { - return rationalize.ErrNoProject + // Resolve platform + platform, err := model.FetchPlatformByDetails(params.Platform.Name(), params.Platform.Version(), params.BitWidth) + if err != nil { + return errs.Wrap(err, "Could not fetch platform") } - if err := requirements.NewRequirementOperation(a.prime).ExecuteRequirementOperation( - nil, - &requirements.Requirement{ - Name: params.name, - Version: params.version, - Operation: types.OperationAdded, - BitWidth: params.BitWidth, - NamespaceType: &model.NamespacePlatform, - }, - ); err != nil { - return locale.WrapError(err, "err_add_platform", "Could not add platform.") + pg.Stop(locale.T("progress_found")) + pg = nil + + // Resolve timestamp, commit and languages used for current project. + ts, err := commits_runbit.ExpandTimeForProject(nil, a.prime.Auth(), pj) + if err != nil { + return errs.Wrap(err, "Unable to get timestamp from params") } - a.prime.Output().Notice(locale.Tr("platform_added", params.name, params.version)) + // Prepare updated buildscript + script := oldCommit.BuildScript() + script.SetAtTime(ts, true) + script.AddPlatform(*platform.PlatformID) + + // Update local checkout and source runtime changes + if err := reqop_runbit.UpdateAndReload(a.prime, script, oldCommit, locale.Tr("commit_message_added", *platform.DisplayName), trigger.TriggerPlatform); err != nil { + return errs.Wrap(err, "Failed to update local checkout") + } + + out.Notice(locale.Tr("platform_added", *platform.DisplayName)) + + if out.Type().IsStructured() { + out.Print(output.Structured(platform)) + } return nil } + +func rationalizeAddPlatformError(rerr *error) { + switch { + case rerr == nil: + return + + // No matches found + case errors.Is(*rerr, model.ErrPlatformNotFound): + *rerr = errs.WrapUserFacing( + *rerr, + locale.Tr("platform_add_not_found"), + errs.SetInput(), + ) + + // Error staging a commit during install. + case errors.As(*rerr, ptr.To(&bpResp.CommitError{})): + rationalizers.HandleCommitErrors(rerr) + + } +} diff --git a/internal/runners/platforms/platforms.go b/internal/runners/platforms/platforms.go index ac91209322..5cd12af476 100644 --- a/internal/runners/platforms/platforms.go +++ b/internal/runners/platforms/platforms.go @@ -21,7 +21,7 @@ type PlatformVersion struct { func (pv *PlatformVersion) Set(arg string) error { err := pv.NameVersionValue.Set(arg) if err != nil { - return locale.WrapInputError(err, "err_platform_format", "The platform and version provided is not formatting correctly, must be in the form of @") + return locale.WrapInputError(err, "err_platform_format", "The platform and version provided is not formatting correctly. It must be in the form of @") } return nil } @@ -66,19 +66,19 @@ func makePlatformsFromModelPlatforms(platforms []*model.Platform) []*Platform { // Params represents the minimal defining details of a platform. type Params struct { - Platform PlatformVersion - BitWidth int - name string - version string + Platform PlatformVersion + BitWidth int + resolvedName string // Holds the provided platforn name, or defaults to curernt platform name if not provided + resolvedVersion string // Holds the provided platform version, or defaults to latest version if not provided } func prepareParams(ps Params) (Params, error) { - ps.name = ps.Platform.Name() - if ps.name == "" { - ps.name = sysinfo.OS().String() + ps.resolvedName = ps.Platform.Name() + if ps.resolvedName == "" { + ps.resolvedName = sysinfo.OS().String() } - ps.version = ps.Platform.Version() - if ps.version == "" { + ps.resolvedVersion = ps.Platform.Version() + if ps.resolvedVersion == "" { return prepareLatestVersion(ps) } @@ -99,8 +99,8 @@ func prepareLatestVersion(params Params) (Params, error) { if err != nil { return params, locale.WrapError(err, "err_fetch_platform", "Could not get platform details") } - params.name = *platform.Kernel.Name - params.version = *platform.KernelVersion.Version + params.resolvedName = *platform.Kernel.Name + params.resolvedVersion = *platform.KernelVersion.Version bitWidth, err := strconv.Atoi(*platform.CPUArchitecture.BitWidth) if err != nil { diff --git a/internal/runners/platforms/remove.go b/internal/runners/platforms/remove.go index 5f98aa3f72..33019cadbf 100644 --- a/internal/runners/platforms/remove.go +++ b/internal/runners/platforms/remove.go @@ -1,59 +1,141 @@ package platforms import ( + "errors" + + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/rtutils/ptr" "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/internal/runbits/requirements" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/ActiveState/cli/internal/runbits/rationalizers" + "github.com/ActiveState/cli/internal/runbits/reqop_runbit" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" + "github.com/ActiveState/cli/pkg/localcommit" + bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" "github.com/ActiveState/cli/pkg/platform/model" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" ) -// RemoveRunParams tracks the info required for running Remove. type RemoveRunParams struct { Params } -// Remove manages the removeing execution context. type Remove struct { prime primeable } -// NewRemove prepares a remove execution context for use. func NewRemove(prime primeable) *Remove { return &Remove{ prime: prime, } } -// Run executes the remove behavior. -func (r *Remove) Run(ps RemoveRunParams) error { +var errNoMatch = errors.New("no platform matched the search criteria") +var errMultiMatch = errors.New("multiple platforms matched the search criteria") + +func (a *Remove) Run(params RemoveRunParams) (rerr error) { + defer rationalizeRemovePlatformError(&rerr) + logging.Debug("Execute platforms remove") - if r.prime.Project() == nil { + if a.prime.Project() == nil { return rationalize.ErrNoProject } - params, err := prepareParams(ps.Params) + pj := a.prime.Project() + out := a.prime.Output() + bp := bpModel.NewBuildPlannerModel(a.prime.Auth(), a.prime.SvcModel()) + + var pg *output.Spinner + defer func() { + if pg != nil { + pg.Stop(locale.T("progress_fail")) + } + }() + + pg = output.StartSpinner(out, locale.T("progress_platforms"), constants.TerminalAnimationInterval) + + // Grab local commit info + localCommitID, err := localcommit.Get(pj.Dir()) if err != nil { - return errs.Wrap(err, "Could not prepare parameters.") + return errs.Wrap(err, "Unable to get local commit") + } + oldCommit, err := bp.FetchCommit(localCommitID, pj.Owner(), pj.Name(), nil) + if err != nil { + return errs.Wrap(err, "Failed to fetch old build result") + } + + pg.Stop(locale.T("progress_found")) + pg = nil + + // Prepare updated buildscript + script := oldCommit.BuildScript() + platforms, err := script.Platforms() + if err != nil { + return errs.Wrap(err, "Failed to get platforms") + } + toRemove := []*model.Platform{} + for _, uid := range platforms { + platform, err := model.FetchPlatformByUID(uid) + if err != nil { + return errs.Wrap(err, "Failed to get platform") + } + if model.IsPlatformMatch(platform, params.Platform.Name(), params.Platform.Version(), params.BitWidth) { + toRemove = append(toRemove, platform) + } + } + if len(toRemove) == 0 { + return errNoMatch + } + if len(toRemove) > 1 { + return errMultiMatch + } + + if err := script.RemovePlatform(*toRemove[0].PlatformID); err != nil { + return errs.Wrap(err, "Failed to remove platform") } - if err := requirements.NewRequirementOperation(r.prime).ExecuteRequirementOperation( - nil, - &requirements.Requirement{ - Name: params.name, - Version: params.version, - Operation: types.OperationRemoved, - BitWidth: params.BitWidth, - NamespaceType: &model.NamespacePlatform, - }, - ); err != nil { - return locale.WrapError(err, "err_remove_platform", "Could not remove platform.") + // Update local checkout and source runtime changes + if err := reqop_runbit.UpdateAndReload(a.prime, script, oldCommit, locale.Tr("commit_message_removed", params.Platform.String()), trigger.TriggerPlatform); err != nil { + return errs.Wrap(err, "Failed to update local checkout") } - r.prime.Output().Notice(locale.Tr("platform_removed", params.name, params.version)) + out.Notice(locale.Tr("platform_added", params.Platform.String())) + + if out.Type().IsStructured() { + out.Print(output.Structured(toRemove[0])) + } return nil } + +func rationalizeRemovePlatformError(rerr *error) { + switch { + case rerr == nil: + return + + // No matches found + case errors.Is(*rerr, errNoMatch): + *rerr = errs.WrapUserFacing( + *rerr, + locale.Tr("err_uninstall_platform_nomatch"), + errs.SetInput(), + ) + + // Multiple matches found + case errors.Is(*rerr, errMultiMatch): + *rerr = errs.WrapUserFacing( + *rerr, + locale.Tr("err_uninstall_platform_multimatch"), + errs.SetInput(), + ) + + // Error staging a commit during install. + case errors.As(*rerr, ptr.To(&bpResp.CommitError{})): + rationalizers.HandleCommitErrors(rerr) + + } +} diff --git a/internal/runners/prepare/completions.go b/internal/runners/prepare/completions.go index 25ee66717b..a760f2e0da 100644 --- a/internal/runners/prepare/completions.go +++ b/internal/runners/prepare/completions.go @@ -35,7 +35,7 @@ func (c *Completions) Run(cmd *captain.Command) error { return locale.WrapError(err, "err_prepare_completions", "Could not prepare completions") } - c.out.Notice(locale.Tl("completions_success", "Completions have been written, please reload your shell.")) + c.out.Notice(locale.Tl("completions_success", "Completions have been written. Please reload your shell.")) return nil } diff --git a/internal/runners/prepare/prepare.go b/internal/runners/prepare/prepare.go index d0eb8f8aee..4c097fba10 100644 --- a/internal/runners/prepare/prepare.go +++ b/internal/runners/prepare/prepare.go @@ -1,6 +1,7 @@ package prepare import ( + "errors" "fmt" "os" "runtime" @@ -15,7 +16,6 @@ import ( "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/globaldefault" "github.com/ActiveState/cli/internal/installation" - "github.com/ActiveState/cli/internal/installation/storage" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/multilog" @@ -23,11 +23,9 @@ import ( "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/subshell" - "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/model" - rt "github.com/ActiveState/cli/pkg/platform/runtime" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/cli/pkg/runtime_helpers" "github.com/thoas/go-funk" ) @@ -69,28 +67,26 @@ func (r *Prepare) resetExecutors() error { } logging.Debug("Reset default project at %s", defaultProjectDir) - defaultTargetDir := target.ProjectDirToTargetDir(defaultProjectDir, storage.CachePath()) - proj, err := project.FromPath(defaultProjectDir) if err != nil { return errs.Wrap(err, "Could not get project from its directory") } - commitID, err := localcommit.Get(proj.Dir()) + rt, err := runtime_helpers.FromProject(proj) if err != nil { - return errs.Wrap(err, "Unable to get local commit") + return errs.Wrap(err, "Could not initialize runtime for project.") } - run, err := rt.New(target.NewCustomTarget(proj.Owner(), proj.Name(), commitID, defaultTargetDir, target.TriggerResetExec), r.analytics, r.svcModel, nil, r.cfg, r.out) + rtHash, err := runtime_helpers.Hash(proj, nil) if err != nil { - return errs.Wrap(err, "Could not initialize runtime for project.") + return errs.Wrap(err, "Could not get runtime hash") } - if !run.NeedsUpdate() { - return nil // project was never set up, so no executors to reset + if rtHash == rt.Hash() || !rt.HasCache() { + return nil } - if err := globaldefault.SetupDefaultActivation(r.subshell, r.cfg, run, proj); err != nil { + if err := globaldefault.SetupDefaultActivation(r.subshell, r.cfg, rt, proj); err != nil { return errs.Wrap(err, "Failed to rewrite the executors.") } @@ -110,14 +106,15 @@ func (r *Prepare) Run(cmd *captain.Command) error { } if err := prepareCompletions(cmd, r.subshell); err != nil { - if !errs.Matches(err, &ErrorNotSupported{}) && !os.IsPermission(err) { - r.reportError(locale.Tl("err_prepare_generate_completions", "Could not generate completions script, error received: {{.V0}}.", err.Error()), err) + var errNotSupported *ErrorNotSupported + if !errors.As(err, &errNotSupported) && !os.IsPermission(err) { + r.reportError(locale.Tl("err_prepare_generate_completions", "Could not generate completions script. Error received: {{.V0}}.", err.Error()), err) } } logging.Debug("Reset global executors") if err := r.resetExecutors(); err != nil { - r.reportError(locale.Tl("err_reset_executor", "Could not reset global executors, error received: {{.V0}}", errs.JoinMessage(err)), err) + r.reportError(locale.Tl("err_reset_executor", "Could not reset global executors. Error received: {{.V0}}", errs.JoinMessage(err)), err) } // OS specific preparations @@ -130,7 +127,7 @@ func (r *Prepare) Run(cmd *captain.Command) error { } if err := updateConfigKey(r.cfg, oldGlobalDefaultPrefname, constants.GlobalDefaultPrefname); err != nil { - r.reportError(locale.Tl("err_prepare_config", "Could not update stale config keys, error recieved: {{.V0}}", errs.JoinMessage(err)), err) + r.reportError(locale.Tl("err_prepare_config", "Could not update stale config keys. Error recieved: {{.V0}}", errs.JoinMessage(err)), err) } return nil @@ -180,6 +177,8 @@ func InstalledPreparedFiles() ([]string, error) { files = append(files, path) } + files = append(files, extraInstalledPreparedFiles()...) + return files, nil } diff --git a/internal/runners/prepare/prepare_darwin.go b/internal/runners/prepare/prepare_darwin.go index c31d070ae8..a858b050ed 100644 --- a/internal/runners/prepare/prepare_darwin.go +++ b/internal/runners/prepare/prepare_darwin.go @@ -21,6 +21,10 @@ func (r *Prepare) prepareOS() error { return nil } +func extraInstalledPreparedFiles() []string { + return nil +} + func cleanOS() error { return nil } diff --git a/internal/runners/prepare/prepare_linux.go b/internal/runners/prepare/prepare_linux.go index abd0276cf5..5e9a57937d 100644 --- a/internal/runners/prepare/prepare_linux.go +++ b/internal/runners/prepare/prepare_linux.go @@ -24,6 +24,10 @@ func (r *Prepare) prepareOS() error { return nil } +func extraInstalledPreparedFiles() []string { + return nil +} + func cleanOS() error { svcApp, err := svcApp.New() if err != nil { diff --git a/internal/runners/prepare/prepare_windows.go b/internal/runners/prepare/prepare_windows.go index 840424e1c3..5f90775c87 100644 --- a/internal/runners/prepare/prepare_windows.go +++ b/internal/runners/prepare/prepare_windows.go @@ -8,15 +8,18 @@ import ( svcApp "github.com/ActiveState/cli/cmd/state-svc/app" svcAutostart "github.com/ActiveState/cli/cmd/state-svc/autostart" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/osutils" "github.com/ActiveState/cli/internal/osutils/autostart" "github.com/ActiveState/cli/internal/osutils/shortcut" + userhome "github.com/ActiveState/cli/internal/osutils/user" ) -var shortcutDir = filepath.Join(os.Getenv("USERPROFILE"), "AppData", "Roaming", "Microsoft", "Windows", "Start Menu", "Programs", "ActiveState") +// shortcutPathRelative is relative to USERHOME +var shortcutPathRelative = filepath.Join("AppData", "Roaming", "Microsoft", "Windows", "Start Menu", "Programs", "ActiveState") func (r *Prepare) prepareOS() error { err := setStateProtocol() @@ -25,7 +28,7 @@ func (r *Prepare) prepareOS() error { } if err := r.prepareStartShortcut(); err != nil { - r.reportError(locale.Tl("err_prepare_shortcut", "Could not create start menu shortcut, error received: {{.V0}}.", err.Error()), err) + r.reportError(locale.Tl("err_prepare_shortcut", "Could not create start menu shortcut. Error received: {{.V0}}.", err.Error()), err) } a, err := svcApp.New() @@ -34,19 +37,26 @@ func (r *Prepare) prepareOS() error { } if err = autostart.Enable(a.Path(), svcAutostart.Options); err != nil { - r.reportError(locale.Tl("err_prepare_service_autostart", "Could not setup service autostart, error recieved: {{.V0}}", err.Error()), err) + r.reportError(locale.Tl("err_prepare_service_autostart", "Could not setup service autostart. Error recieved: {{.V0}}", err.Error()), err) } return nil } func (r *Prepare) prepareStartShortcut() error { + home, err := userhome.HomeDir() + if err != nil { + return errs.Wrap(err, "Unable to get home directory") + } + + shortcutDir := filepath.Join(home, shortcutPathRelative) + if err := fileutils.MkdirUnlessExists(shortcutDir); err != nil { return locale.WrapInputError(err, "err_preparestart_mkdir", "Could not create start menu entry: %s", shortcutDir) } sc := shortcut.New(shortcutDir, "Uninstall State Tool", r.subshell.Binary(), "/C \"state clean uninstall --prompt\"") - err := sc.Enable() + err = sc.Enable() if err != nil { return locale.WrapError(err, "err_preparestart_shortcut", "", sc.Path()) } @@ -109,6 +119,16 @@ func setStateProtocol() error { return nil } +func extraInstalledPreparedFiles() []string { + home, err := userhome.HomeDir() + if err != nil { + multilog.Error("Unable to get home directory: %v", err) + return nil + } + + return []string{filepath.Join(home, shortcutPathRelative)} +} + func cleanOS() error { return nil } diff --git a/internal/runners/projects/projects.go b/internal/runners/projects/projects.go index fcd85476f4..91357549c3 100644 --- a/internal/runners/projects/projects.go +++ b/internal/runners/projects/projects.go @@ -9,10 +9,9 @@ import ( "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/pkg/platform/authentication" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" + "github.com/ActiveState/cli/pkg/runtime_helpers" ) // Holds a union of project and organization parameters. @@ -23,13 +22,12 @@ type projectWithOrg struct { Executables []string `json:"executables,omitempty"` } -func newProjectWithOrg(name, org string, checkouts []string) projectWithOrg { +func newProjectWithOrg(prime primeable, name, org string, checkouts []string) projectWithOrg { p := projectWithOrg{Name: name, Organization: org, LocalCheckouts: checkouts} for _, checkout := range checkouts { var execDir string if proj, err := project.FromPath(checkout); err == nil { - projectTarget := target.NewProjectTarget(proj, nil, "") - execDir = setup.ExecDir(projectTarget.Dir()) + execDir = runtime_helpers.ExecutorPathFromProject(proj) } else { multilog.Error("Unable to get project %s from checkout: %v", checkout, err) } @@ -64,16 +62,16 @@ func (o *projectsOutput) MarshalOutput(f output.Format) interface{} { } execDir := v.Executables[i] if execDir != "" { - checkouts = append(checkouts, locale.Tl("projects_local_checkout_exec", " ├─ Local Checkout → {{.V0}}", checkout)) + checkouts = append(checkouts, locale.Tl("projects_local_checkout_exec", " {{.V0}} Local Checkout → {{.V1}}", output.TreeMid, checkout)) if f == output.PlainFormatName { // Show executable path below checkout path for plain text output. - checkouts = append(checkouts, locale.Tl("projects_executables", " └─ Executables → {{.V0}}", execDir)) + checkouts = append(checkouts, locale.Tl("projects_executables", " {{.V0}} Executables → {{.V1}}", output.TreeEnd, execDir)) } else { // Show executables in a separate table. executables = append(executables, execDir) } } else { - checkouts = append(checkouts, locale.Tl("projects_local_checkout", " └─ Local Checkout → {{.V0}}", checkout)) + checkouts = append(checkouts, locale.Tl("projects_local_checkout", " {{.V0}} Local Checkout → {{.V1}}", output.TreeEnd, checkout)) } } r = append(r, projectOutputPlain{v.Name, v.Organization, strings.Join(checkouts, "\n"), strings.Join(executables, "\n")}) @@ -95,6 +93,10 @@ type Params struct { } type Projects struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 auth *authentication.Auth out output.Outputer config configGetter @@ -112,14 +114,11 @@ func NewParams() *Params { } func NewProjects(prime primeable) *Projects { - return newProjects(prime.Auth(), prime.Output(), prime.Config()) -} - -func newProjects(auth *authentication.Auth, out output.Outputer, config configGetter) *Projects { return &Projects{ - auth, - out, - config, + prime, + prime.Auth(), + prime.Output(), + prime.Config(), } } @@ -133,7 +132,7 @@ func (r *Projects) Run(params *Params) error { multilog.Error("Invalid project namespace stored to config mapping: %s", namespace) continue } - projects = append(projects, newProjectWithOrg(ns.Project, ns.Owner, checkouts)) + projects = append(projects, newProjectWithOrg(r.prime, ns.Project, ns.Owner, checkouts)) } sort.SliceStable(projects, func(i, j int) bool { diff --git a/internal/runners/protocol/protocol.go b/internal/runners/protocol/protocol.go index 401ca6f449..2f3dd484ce 100644 --- a/internal/runners/protocol/protocol.go +++ b/internal/runners/protocol/protocol.go @@ -58,7 +58,7 @@ func (p *Protocol) Run(params Params) error { } if parsed.Fragment != "" && parsed.Fragment != "replace" { - return locale.NewError("err_protocol_flag", "Invalid URL fragment, the only supported URL fragment is 'replace'") + return locale.NewError("err_protocol_flag", "Invalid URL fragment. The only supported URL fragment is 'replace'") } // Execute state command diff --git a/internal/runners/publish/publish.go b/internal/runners/publish/publish.go index 6d87384d4d..6964d1c98b 100644 --- a/internal/runners/publish/publish.go +++ b/internal/runners/publish/publish.go @@ -2,7 +2,6 @@ package publish import ( "errors" - "net/http" "path/filepath" "regexp" "strconv" @@ -12,7 +11,6 @@ import ( "github.com/ActiveState/cli/internal/captain" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/gqlclient" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/osutils" @@ -20,15 +18,13 @@ import ( "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/ActiveState/cli/pkg/platform/api" - graphModel "github.com/ActiveState/cli/pkg/platform/api/graphql/model" "github.com/ActiveState/cli/pkg/platform/api/graphql/request" "github.com/ActiveState/cli/pkg/platform/api/inventory/inventory_client/inventory_operations" "github.com/ActiveState/cli/pkg/platform/api/inventory/inventory_models" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/platform/model/buildplanner" "github.com/ActiveState/cli/pkg/project" - "github.com/ActiveState/graphql" "github.com/go-openapi/strfmt" "gopkg.in/yaml.v3" ) @@ -56,7 +52,7 @@ type Runner struct { out output.Outputer prompt prompt.Prompter project *project.Project - client *gqlclient.Client + bp *buildplanner.BuildPlanner } type primeable interface { @@ -64,17 +60,17 @@ type primeable interface { primer.Auther primer.Projecter primer.Prompter + primer.SvcModeler } func New(prime primeable) *Runner { - client := gqlclient.NewWithOpts( - api.GetServiceURL(api.ServiceBuildPlanner).String(), 0, - graphql.WithHTTPClient(http.DefaultClient), - graphql.UseMultipartForm(), - ) - client.SetTokenProvider(prime.Auth()) - client.EnableDebugLog() - return &Runner{auth: prime.Auth(), out: prime.Output(), prompt: prime.Prompt(), project: prime.Project(), client: client} + return &Runner{ + auth: prime.Auth(), + out: prime.Output(), + prompt: prime.Prompt(), + project: prime.Project(), + bp: buildplanner.NewBuildPlannerModel(prime.Auth(), prime.SvcModel()), + } } type ParentIngredient struct { @@ -117,7 +113,7 @@ func (r *Runner) Run(params *Params) error { } if err := yaml.Unmarshal(b, &reqVars); err != nil { - return locale.WrapExternalError(err, "err_uploadingredient_file_read", "Failed to unmarshal meta file, error received: {{.V0}}", err.Error()) + return locale.WrapExternalError(err, "err_uploadingredient_file_read", "Failed to unmarshal meta file. Error received: {{.V0}}", err.Error()) } } @@ -125,7 +121,7 @@ func (r *Runner) Run(params *Params) error { if params.Namespace != "" { reqVars.Namespace = params.Namespace } else if reqVars.Namespace == "" && r.project != nil && r.project.Owner() != "" { - reqVars.Namespace = model.NewOrgNamespace(r.project.Owner()).String() + reqVars.Namespace = model.NewNamespaceOrg(r.project.Owner(), "").String() } // Name @@ -169,7 +165,8 @@ func (r *Runner) Run(params *Params) error { if ingredient == nil { // Attempt to find the existing ingredient, if we didn't already get it from the version specific call above ingredients, err := model.SearchIngredientsStrict(reqVars.Namespace, reqVars.Name, true, false, &latestRevisionTime, r.auth) - if err != nil && !errs.Matches(err, &model.ErrSearch404{}) { // 404 means either the ingredient or the namespace was not found, which is fine + var errSearch404 *model.ErrSearch404 + if err != nil && !errors.As(err, &errSearch404) { // 404 means either the ingredient or the namespace was not found, which is fine return locale.WrapError(err, "err_uploadingredient_search", "Could not search for ingredient") } if len(ingredients) > 0 { @@ -241,30 +238,25 @@ Do you want to publish this ingredient? r.out.Notice(locale.Tl("uploadingredient_uploading", "Publishing ingredient...")) - pr, err := request.Publish(reqVars, params.Filepath) + publishResult, err := r.bp.Publish(reqVars, params.Filepath) if err != nil { return locale.WrapError(err, "err_uploadingredient_publish", "Could not create publish request") } - result := graphModel.PublishResult{} - - if err := r.client.Run(pr, &result); err != nil { - return locale.WrapError(err, "err_uploadingredient_publish", "", err.Error()) - } - if result.Publish.Error != "" { - return locale.NewError("err_uploadingredient_publish_api", "API responded with error: {{.V0}}", result.Publish.Error) + if publishResult.Error != "" { + return locale.NewError("err_uploadingredient_publish_api", "API responded with error: {{.V0}}", publishResult.Error) } - logging.Debug("Published ingredient ID: %s", result.Publish.IngredientID) - logging.Debug("Published ingredient version ID: %s", result.Publish.IngredientVersionID) - logging.Debug("Published ingredient revision: %d", result.Publish.Revision) + logging.Debug("Published ingredient ID: %s", publishResult.IngredientID) + logging.Debug("Published ingredient version ID: %s", publishResult.IngredientVersionID) + logging.Debug("Published ingredient revision: %d", publishResult.Revision) - ingredientID := strfmt.UUID(result.Publish.IngredientID) + ingredientID := strfmt.UUID(publishResult.IngredientID) publishedIngredient, err := model.FetchIngredient(&ingredientID, r.auth) if err != nil { return locale.WrapError(err, "err_uploadingredient_fetch", "Unable to fetch newly published ingredient") } - versionID := strfmt.UUID(result.Publish.IngredientVersionID) + versionID := strfmt.UUID(publishResult.IngredientVersionID) latestTime, err := model.FetchLatestRevisionTimeStamp(r.auth) if err != nil { @@ -293,7 +285,7 @@ Do you want to publish this ingredient? strconv.Itoa(int(*publishedVersion.Revision)), ingTime.Format(time.RFC3339), ), - result.Publish, + publishResult, )) return nil @@ -426,7 +418,7 @@ func prepareEditRequest(ingredient *ParentIngredient, r *request.PublishVariable request.PublishVariableDep{request.Dependency{ Name: ptr.From(dep.Feature, ""), Namespace: ptr.From(dep.Namespace, ""), - VersionRequirements: model.InventoryRequirementsToString(dep.Requirements), + VersionRequirements: model.InventoryRequirementsToString(dep.Requirements, true), }, []request.Dependency{}}, ) } diff --git a/internal/runners/pull/pull.go b/internal/runners/pull/pull.go index 8553bd48a2..0e9ea15c92 100644 --- a/internal/runners/pull/pull.go +++ b/internal/runners/pull/pull.go @@ -20,17 +20,21 @@ import ( "github.com/ActiveState/cli/internal/runbits/commit" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/go-openapi/strfmt" ) type Pull struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 prompt prompt.Prompter project *project.Project auth *authentication.Auth @@ -41,11 +45,14 @@ type Pull struct { } type errNoCommonParent struct { - error localCommitID strfmt.UUID remoteCommitID strfmt.UUID } +func (e errNoCommonParent) Error() string { + return "no common parent" +} + type PullParams struct { Force bool } @@ -62,6 +69,7 @@ type primeable interface { func New(prime primeable) *Pull { return &Pull{ + prime, prime.Prompt(), prime.Project(), prime.Auth(), @@ -135,7 +143,6 @@ func (p *Pull) Run(params *PullParams) (rerr error) { if commonParent == nil { return &errNoCommonParent{ - errs.New("no common parent"), *localCommit, *remoteCommit, } @@ -148,7 +155,7 @@ func (p *Pull) Run(params *PullParams) (rerr error) { // If this call fails then we will try a recursive merge. strategy := types.MergeCommitStrategyFastForward - bp := buildplanner.NewBuildPlannerModel(p.auth) + bp := buildplanner.NewBuildPlannerModel(p.auth, p.svcModel) params := &buildplanner.MergeCommitParams{ Owner: remoteProject.Owner, Project: remoteProject.Project, @@ -184,7 +191,8 @@ func (p *Pull) Run(params *PullParams) (rerr error) { if p.cfg.GetBool(constants.OptinBuildscriptsConfig) { err := p.mergeBuildScript(*remoteCommit, *localCommit) if err != nil { - if errs.Matches(err, &ErrBuildScriptMergeConflict{}) { + var errBuildScriptMergeConflict *ErrBuildScriptMergeConflict + if errors.As(err, &errBuildScriptMergeConflict) { err2 := localcommit.Set(p.project.Dir(), remoteCommit.String()) if err2 != nil { err = errs.Pack(err, errs.Wrap(err2, "Could not set local commit to remote commit after build script merge conflict")) @@ -210,7 +218,7 @@ func (p *Pull) Run(params *PullParams) (rerr error) { }) } - _, err = runtime.SolveAndUpdate(p.auth, p.out, p.analytics, p.project, resultingCommit, target.TriggerPull, p.svcModel, p.cfg, runtime.OptOrderChanged) + _, err = runtime_runbit.Update(p.prime, trigger.TriggerPull) if err != nil { return locale.WrapError(err, "err_pull_refresh", "Could not refresh runtime after pull") } @@ -225,7 +233,7 @@ func (p *Pull) performMerge(remoteCommit, localCommit strfmt.UUID, namespace *pr namespace.String(), branchName, localCommit.String(), remoteCommit.String()), ) - bp := buildplanner.NewBuildPlannerModel(p.auth) + bp := buildplanner.NewBuildPlannerModel(p.auth, p.svcModel) params := &buildplanner.MergeCommitParams{ Owner: namespace.Owner, Project: namespace.Project, @@ -261,7 +269,7 @@ func (p *Pull) mergeBuildScript(remoteCommit, localCommit strfmt.UUID) error { } // Get the local and remote build expressions to merge. - bp := buildplanner.NewBuildPlannerModel(p.auth) + bp := buildplanner.NewBuildPlannerModel(p.auth, p.svcModel) scriptB, err := bp.GetBuildScript(remoteCommit.String()) if err != nil { return errs.Wrap(err, "Unable to get buildexpression and time for remote commit") @@ -279,7 +287,7 @@ func (p *Pull) mergeBuildScript(remoteCommit, localCommit strfmt.UUID) error { } // Attempt the merge. - mergedScript, err := scriptA.Merge(scriptB, strategies) + err = scriptA.Merge(scriptB, strategies) if err != nil { err := buildscript_runbit.GenerateAndWriteDiff(p.project, scriptA, scriptB) if err != nil { @@ -289,7 +297,7 @@ func (p *Pull) mergeBuildScript(remoteCommit, localCommit strfmt.UUID) error { } // Write the merged build expression as a local build script. - return buildscript_runbit.Update(p.project, mergedScript) + return buildscript_runbit.Update(p.project, scriptA) } func resolveRemoteProject(prj *project.Project) (*project.Namespaced, error) { diff --git a/internal/runners/pull/rationalize.go b/internal/runners/pull/rationalize.go index c41611d1a6..6bcdea0a11 100644 --- a/internal/runners/pull/rationalize.go +++ b/internal/runners/pull/rationalize.go @@ -27,7 +27,7 @@ func rationalizeError(err *error) { case types.NoCommonBaseFoundType: *err = errs.WrapUserFacing(*err, locale.Tl("err_pull_no_common_base", - "Could not merge, no common base found between local and remote commits", + "Could not merge. No common base found between local and remote commits", ), errs.SetInput(), ) @@ -44,7 +44,7 @@ func rationalizeError(err *error) { default: *err = errs.WrapUserFacing(*err, locale.Tl("err_pull_no_common_base", - "Could not merge, recieved error message: {{.V0}}", + "Could not merge. Recieved error message: {{.V0}}", mergeCommitErr.Error(), ), ) diff --git a/internal/runners/push/push.go b/internal/runners/push/push.go index bd1c976785..df61f99e2f 100644 --- a/internal/runners/push/push.go +++ b/internal/runners/push/push.go @@ -29,6 +29,7 @@ type configGetter interface { } type Push struct { + prime primeable config configGetter out output.Outputer project *project.Project @@ -46,10 +47,11 @@ type primeable interface { primer.Configurer primer.Prompter primer.Auther + primer.SvcModeler } func NewPush(prime primeable) *Push { - return &Push{prime.Config(), prime.Output(), prime.Project(), prime.Prompt(), prime.Auth()} + return &Push{prime, prime.Config(), prime.Output(), prime.Project(), prime.Prompt(), prime.Auth()} } type intention uint16 @@ -68,15 +70,21 @@ var ( ) type errProjectNameInUse struct { - error Namespace *project.Namespaced } +func (e errProjectNameInUse) Error() string { + return "project name in use" +} + type errHeadless struct { - error ProjectURL string } +func (e errHeadless) Error() string { + return "headless project" +} + func (r *Push) Run(params PushParams) (rerr error) { defer rationalizeError(&rerr) @@ -97,7 +105,7 @@ func (r *Push) Run(params PushParams) (rerr error) { var err error targetNamespace, err = r.namespaceFromProject() if err != nil { - return errs.Wrap(err, "Could not get a valid namespace, is your activestate.yaml malformed?") + return errs.Wrap(err, "Could not get a valid namespace. Is your activestate.yaml malformed?") } } @@ -106,7 +114,7 @@ func (r *Push) Run(params PushParams) (rerr error) { } if r.project.IsHeadless() { - return &errHeadless{err, r.project.URL()} + return &errHeadless{r.project.URL()} } // Capture the primary intend of the user @@ -141,26 +149,27 @@ func (r *Push) Run(params PushParams) (rerr error) { var targetPjm *mono_models.Project targetPjm, err = model.LegacyFetchProjectByName(targetNamespace.Owner, targetNamespace.Project) if err != nil { - if !errs.Matches(err, &model.ErrProjectNotFound{}) { + var errProjectNotFound *model.ErrProjectNotFound + if !errors.As(err, &errProjectNotFound) { return errs.Wrap(err, "Failed to check for existence of project") } } - bp := buildplanner.NewBuildPlannerModel(r.auth) + bp := buildplanner.NewBuildPlannerModel(r.auth, r.prime.SvcModel()) var branch *mono_models.Branch // the branch to write to as.yaml if it changed // Create remote project var projectCreated bool if intend&intendCreateProject > 0 || targetPjm == nil { if targetPjm != nil { - return &errProjectNameInUse{errs.New("project name in use"), targetNamespace} + return &errProjectNameInUse{targetNamespace} } // If the user didn't necessarily intend to create the project we should ask them for confirmation if intend&intendCreateProject == 0 { createProject, err := r.prompt.Confirm( locale.Tl("create_project", "Create Project"), - locale.Tl("push_confirm_create_project", "You are about to create the project [NOTICE]{{.V0}}[/RESET], continue?", targetNamespace.String()), + locale.Tl("push_confirm_create_project", "You are about to create the project [NOTICE]{{.V0}}[/RESET]. Continue?", targetNamespace.String()), ptr.To(true)) if err != nil { return errs.Wrap(err, "Confirmation failed") diff --git a/internal/runners/refresh/refresh.go b/internal/runners/refresh/refresh.go index 1f748bcec1..41a3e3c352 100644 --- a/internal/runners/refresh/refresh.go +++ b/internal/runners/refresh/refresh.go @@ -1,23 +1,27 @@ package refresh import ( + "errors" + "github.com/ActiveState/cli/internal/analytics" "github.com/ActiveState/cli/internal/config" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/prompt" + "github.com/ActiveState/cli/internal/runbits/buildscript" "github.com/ActiveState/cli/internal/runbits/findproject" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" + "github.com/ActiveState/cli/pkg/runtime_helpers" ) type Params struct { @@ -31,9 +35,14 @@ type primeable interface { primer.Configurer primer.SvcModeler primer.Analyticer + primer.Projecter } type Refresh struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 auth *authentication.Auth prompt prompt.Prompter out output.Outputer @@ -44,6 +53,7 @@ type Refresh struct { func New(prime primeable) *Refresh { return &Refresh{ + prime, prime.Auth(), prime.Prompt(), prime.Output(), @@ -58,18 +68,40 @@ func (r *Refresh) Run(params *Params) error { proj, err := findproject.FromInputByPriority("", params.Namespace, r.config, r.prompt) if err != nil { - if errs.Matches(err, &projectfile.ErrorNoDefaultProject{}) { + var errNoDefaultProject *projectfile.ErrorNoDefaultProject + if errors.As(err, &errNoDefaultProject) { return locale.WrapError(err, "err_use_default_project_does_not_exist") } return rationalize.ErrNoProject } - rti, err := runtime.SolveAndUpdate(r.auth, r.out, r.analytics, proj, nil, target.TriggerRefresh, r.svcModel, r.config, runtime.OptMinimalUI) + r.prime.SetProject(proj) + + r.out.Notice(locale.Tr("operating_message", proj.NamespaceString(), proj.Dir())) + + needsUpdate, err := runtime_helpers.NeedsUpdate(proj, nil) + if err != nil { + return errs.Wrap(err, "could not determine if runtime needs update") + } + + if r.config.GetBool(constants.OptinBuildscriptsConfig) { + _, err := buildscript_runbit.ScriptFromProject(proj) + if errors.Is(err, buildscript_runbit.ErrBuildscriptNotExist) { + return locale.WrapInputError(err, locale.T("notice_needs_buildscript_reset")) + } + } + + if !needsUpdate { + r.out.Notice(locale.T("refresh_runtime_uptodate")) + return nil + } + + rti, err := runtime_runbit.Update(r.prime, trigger.TriggerRefresh, runtime_runbit.WithoutHeaders(), runtime_runbit.WithIgnoreAsync()) if err != nil { return locale.WrapError(err, "err_refresh_runtime_new", "Could not update runtime for this project.") } - execDir := setup.ExecDir(rti.Target().Dir()) + execDir := rti.Env(false).ExecutorsPath r.out.Print(output.Prepare( locale.Tr("refresh_project_statement", proj.NamespaceString(), proj.Dir(), execDir), &struct { diff --git a/internal/runners/reset/reset.go b/internal/runners/reset/reset.go index 986aa253de..c046635e63 100644 --- a/internal/runners/reset/reset.go +++ b/internal/runners/reset/reset.go @@ -1,6 +1,7 @@ package reset import ( + "errors" "strings" "github.com/ActiveState/cli/internal/analytics" @@ -14,10 +15,10 @@ import ( "github.com/ActiveState/cli/internal/runbits/buildscript" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/go-openapi/strfmt" ) @@ -30,6 +31,10 @@ type Params struct { } type Reset struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 out output.Outputer auth *authentication.Auth prompt prompt.Prompter @@ -51,6 +56,7 @@ type primeable interface { func New(prime primeable) *Reset { return &Reset{ + prime, prime.Output(), prime.Auth(), prime.Prompt(), @@ -75,7 +81,8 @@ func (r *Reset) Run(params *Params) error { return locale.WrapError(err, "err_reset_latest_commit", "Could not get latest commit ID") } localCommitID, err := localcommit.Get(r.project.Dir()) - if err != nil && !errs.Matches(err, &localcommit.ErrInvalidCommitID{}) { + var errInvalidCommitID *localcommit.ErrInvalidCommitID + if err != nil && !errors.As(err, &errInvalidCommitID) { return errs.Wrap(err, "Unable to get local commit") } if *latestCommit == localCommitID { @@ -103,13 +110,14 @@ func (r *Reset) Run(params *Params) error { } localCommitID, err := localcommit.Get(r.project.Dir()) - if err != nil && !errs.Matches(err, &localcommit.ErrInvalidCommitID{}) { + var errInvalidCommitID *localcommit.ErrInvalidCommitID + if err != nil && !errors.As(err, &errInvalidCommitID) { return errs.Wrap(err, "Unable to get local commit") } r.out.Notice(locale.Tl("reset_commit", "Your project will be reset to [ACTIONABLE]{{.V0}}[/RESET]\n", commitID.String())) if commitID != localCommitID { defaultChoice := params.Force || !r.out.Config().Interactive - confirm, err := r.prompt.Confirm("", locale.Tl("reset_confim", "Resetting is destructive, you will lose any changes that were not pushed. Are you sure you want to do this?"), &defaultChoice) + confirm, err := r.prompt.Confirm("", locale.Tl("reset_confim", "Resetting is destructive. You will lose any changes that were not pushed. Are you sure you want to do this?"), &defaultChoice) if err != nil { return locale.WrapError(err, "err_reset_confirm", "Could not confirm reset choice") } @@ -126,12 +134,12 @@ func (r *Reset) Run(params *Params) error { // Ensure the buildscript exists. Normally we should never do this, but reset is used for resetting from a corrupted // state, so it is appropriate. if r.cfg.GetBool(constants.OptinBuildscriptsConfig) { - if err := buildscript_runbit.Initialize(r.project.Dir(), r.auth); err != nil { + if err := buildscript_runbit.Initialize(r.project, r.auth, r.svcModel); err != nil { return errs.Wrap(err, "Unable to initialize buildscript") } } - _, err = runtime.SolveAndUpdate(r.auth, r.out, r.analytics, r.project, &commitID, target.TriggerReset, r.svcModel, r.cfg, runtime.OptOrderChanged) + _, err = runtime_runbit.Update(r.prime, trigger.TriggerReset, runtime_runbit.WithoutBuildscriptValidation()) if err != nil { return locale.WrapError(err, "err_refresh_runtime") } diff --git a/internal/runners/revert/rationalize.go b/internal/runners/revert/rationalize.go index a346b9201c..a7e5d2feb6 100644 --- a/internal/runners/revert/rationalize.go +++ b/internal/runners/revert/rationalize.go @@ -32,14 +32,14 @@ func rationalizeError(err *error) { case types.NoChangeSinceLastCommitErrorType: *err = errs.WrapUserFacing(*err, locale.Tl("err_revert_no_change", - "Could not revert commit, no changes since last commit", + "Could not revert commit. No changes since last commit", ), errs.SetInput(), ) default: *err = errs.WrapUserFacing(*err, locale.Tl("err_revert_not_found", - "Could not revert commit, recieved error message: {{.V0}}", + "Could not revert commit. Received error message: {{.V0}}", revertCommitError.Error(), ), ) diff --git a/internal/runners/revert/revert.go b/internal/runners/revert/revert.go index f1c648b08b..60da9a2441 100644 --- a/internal/runners/revert/revert.go +++ b/internal/runners/revert/revert.go @@ -12,18 +12,22 @@ import ( "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/runbits/commit" "github.com/ActiveState/cli/internal/runbits/rationalize" - "github.com/ActiveState/cli/internal/runbits/runtime" + runtime_runbit "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/pkg/localcommit" gqlmodel "github.com/ActiveState/cli/pkg/platform/api/graphql/model" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/go-openapi/strfmt" ) type Revert struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 out output.Outputer prompt prompt.Prompter project *project.Project @@ -51,6 +55,7 @@ type primeable interface { func New(prime primeable) *Revert { return &Revert{ + prime, prime.Output(), prime.Prompt(), prime.Project(), @@ -92,7 +97,7 @@ func (r *Revert) Run(params *Params) (rerr error) { } r.out.Notice(locale.Tr("operating_message", r.project.NamespaceString(), r.project.Dir())) - bp := buildplanner.NewBuildPlannerModel(r.auth) + bp := buildplanner.NewBuildPlannerModel(r.auth, r.prime.SvcModel()) targetCommitID := commitID // the commit to revert the contents of, or the commit to revert to revertParams := revertParams{ organization: r.project.Owner(), @@ -156,7 +161,7 @@ func (r *Revert) Run(params *Params) (rerr error) { return errs.Wrap(err, "Unable to set local commit") } - _, err = runtime.SolveAndUpdate(r.auth, r.out, r.analytics, r.project, &revertCommit, target.TriggerRevert, r.svcModel, r.cfg, runtime.OptOrderChanged) + _, err = runtime_runbit.Update(r.prime, trigger.TriggerRevert) if err != nil { return locale.WrapError(err, "err_refresh_runtime") } @@ -203,10 +208,10 @@ func (r *Revert) revertToCommit(params revertParams, bp *buildplanner.BuildPlann Script: bs, } - newCommitID, err := bp.StageCommit(stageCommitParams) + newCommit, err := bp.StageCommit(stageCommitParams) if err != nil { return "", errs.Wrap(err, "Could not stage commit") } - return newCommitID, nil + return newCommit.CommitID, nil } diff --git a/internal/runners/run/run.go b/internal/runners/run/run.go index 5444b1824b..4b3908b999 100644 --- a/internal/runners/run/run.go +++ b/internal/runners/run/run.go @@ -22,6 +22,10 @@ import ( // Run contains the run execution context. type Run struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 auth *authentication.Auth out output.Outputer proj *project.Project @@ -44,6 +48,7 @@ type primeable interface { // New constructs a new instance of Run. func New(prime primeable) *Run { return &Run{ + prime, prime.Auth(), prime.Output(), prime.Project(), @@ -82,7 +87,7 @@ func (r *Run) Run(name string, args []string) error { return locale.NewInputError("error_state_run_unknown_name", "", name) } - scriptrunner := scriptrun.New(r.auth, r.out, r.subshell, r.proj, r.cfg, r.analytics, r.svcModel) + scriptrunner := scriptrun.New(r.prime) if !script.Standalone() && scriptrunner.NeedsActivation() { if err := scriptrunner.PrepareVirtualEnv(); err != nil { return locale.WrapError(err, "err_script_run_preparevenv", "Could not prepare virtual environment.") diff --git a/internal/runners/shell/shell.go b/internal/runners/shell/shell.go index c8d4d2c70a..43cc179806 100644 --- a/internal/runners/shell/shell.go +++ b/internal/runners/shell/shell.go @@ -1,6 +1,7 @@ package shell import ( + "errors" "os" "github.com/ActiveState/cli/internal/analytics" @@ -16,13 +17,12 @@ import ( "github.com/ActiveState/cli/internal/runbits/activation" "github.com/ActiveState/cli/internal/runbits/findproject" "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/virtualenvironment" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" ) @@ -40,9 +40,14 @@ type primeable interface { primer.Configurer primer.SvcModeler primer.Analyticer + primer.Projecter } type Shell struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 auth *authentication.Auth prompt prompt.Prompter out output.Outputer @@ -54,6 +59,7 @@ type Shell struct { func New(prime primeable) *Shell { return &Shell{ + prime, prime.Auth(), prime.Prompt(), prime.Output(), @@ -69,12 +75,15 @@ func (u *Shell) Run(params *Params) error { proj, err := findproject.FromInputByPriority("", params.Namespace, u.config, u.prompt) if err != nil { - if errs.Matches(err, &projectfile.ErrorNoDefaultProject{}) { + var errNoDefaultProject *projectfile.ErrorNoDefaultProject + if errors.As(err, &errNoDefaultProject) { return locale.WrapError(err, "err_use_default_project_does_not_exist") } return locale.WrapError(err, "err_shell_cannot_load_project") } + u.prime.SetProject(proj) + commitID, err := localcommit.Get(proj.Dir()) if err != nil { return errs.Wrap(err, "Unable to get local commit") @@ -84,7 +93,7 @@ func (u *Shell) Run(params *Params) error { return locale.NewInputError("err_shell_commit_id_mismatch") } - rti, err := runtime.SolveAndUpdate(u.auth, u.out, u.analytics, proj, nil, target.TriggerShell, u.svcModel, u.config, runtime.OptMinimalUI) + rti, err := runtime_runbit.Update(u.prime, trigger.TriggerShell, runtime_runbit.WithoutHeaders()) if err != nil { return locale.WrapExternalError(err, "err_shell_runtime_new", "Could not start a shell/prompt for this project.") } @@ -98,7 +107,7 @@ func (u *Shell) Run(params *Params) error { u.out.Notice(locale.Tr("shell_project_statement", proj.NamespaceString(), proj.Dir(), - setup.ExecDir(rti.Target().Dir()), + rti.Env(false).ExecutorsPath, )) venv := virtualenvironment.New(rti) diff --git a/internal/runners/show/show.go b/internal/runners/show/show.go index ce6f10d893..2c5387d561 100644 --- a/internal/runners/show/show.go +++ b/internal/runners/show/show.go @@ -1,10 +1,12 @@ package show import ( + "errors" "fmt" "path/filepath" "strings" + "github.com/ActiveState/cli/pkg/runtime_helpers" "github.com/go-openapi/strfmt" "github.com/ActiveState/cli/internal/constraints" @@ -21,8 +23,6 @@ import ( secretsapi "github.com/ActiveState/cli/pkg/platform/api/secrets" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" ) @@ -78,7 +78,7 @@ func formatScripts(scripts map[string]string) string { for k, v := range scripts { res = append(res, fmt.Sprintf("• %s", k)) if v != "" { - res = append(res, fmt.Sprintf(" └─ %s", v)) + res = append(res, fmt.Sprintf(" %s %s", output.TreeEnd, v)) } } return strings.Join(res, "\n") @@ -147,11 +147,10 @@ func (s *Show) Run(params Params) error { ) var projectDir string - var projectTarget string if params.Remote != "" { namespaced, err := project.ParseNamespace(params.Remote) if err != nil { - return locale.WrapError(err, "err_show_parse_namespace", "Invalid remote argument, must be of the form ") + return locale.WrapError(err, "err_show_parse_namespace", "Invalid remote argument. It must be of the form ") } owner = namespaced.Owner @@ -202,12 +201,11 @@ func (s *Show) Run(params Params) error { return locale.WrapError(err, "err_show_projectdir", "Could not resolve project directory symlink") } } - - projectTarget = target.NewProjectTarget(s.project, nil, "").Dir() } remoteProject, err := model.LegacyFetchProjectByName(owner, projectName) - if err != nil && errs.Matches(err, &model.ErrProjectNotFound{}) { + var errProjectNotFound *model.ErrProjectNotFound + if err != nil && errors.As(err, &errProjectNotFound) { return locale.WrapError(err, "err_show_project_not_found", "Please run '[ACTIONABLE]state push[/RESET]' to synchronize this project with the ActiveState Platform.") } else if err != nil { return locale.WrapError(err, "err_show_get_project", "Could not get remote project details") @@ -249,8 +247,8 @@ func (s *Show) Run(params Params) error { rd.Location = projectDir } - if projectTarget != "" { - rd.Executables = setup.ExecDir(projectTarget) + if params.Remote == "" { + rd.Executables = runtime_helpers.ExecutorPathFromProject(s.project) } outputData := outputData{ @@ -406,7 +404,7 @@ func secretsData(owner, project string, auth *authentication.Auth) (*secretOutpu sec, err := secrets.DefsByProject(client, owner, project) if err != nil { logging.Debug("Could not get secret definitions, got failure: %s", err) - return nil, locale.WrapError(err, "err_show_get_secrets", "Could not get secret definitions, you may not be authorized to view secrets on this project") + return nil, locale.WrapError(err, "err_show_get_secrets", "Could not get secret definitions. You may not be authorized to view secrets on this project") } var userSecrets []string diff --git a/internal/runners/swtch/switch.go b/internal/runners/swtch/switch.go index b267e0307e..c5c997d426 100644 --- a/internal/runners/swtch/switch.go +++ b/internal/runners/swtch/switch.go @@ -1,6 +1,8 @@ package swtch import ( + "errors" + "github.com/ActiveState/cli/internal/analytics" "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/errs" @@ -8,19 +10,22 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/rtutils/ptr" "github.com/ActiveState/cli/internal/runbits/rationalize" "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/go-openapi/strfmt" ) type Switch struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 auth *authentication.Auth out output.Outputer project *project.Project @@ -71,8 +76,18 @@ func (b branchIdentifier) Locale() string { return locale.Tl("branch_identifier_type", "branch") } +type errCommitNotOnBranch struct { + commitID string + branch string +} + +func (e errCommitNotOnBranch) Error() string { + return "commit is not on branch" +} + func New(prime primeable) *Switch { return &Switch{ + prime: prime, auth: prime.Auth(), out: prime.Output(), project: prime.Project(), @@ -82,7 +97,24 @@ func New(prime primeable) *Switch { } } -func (s *Switch) Run(params SwitchParams) error { +func rationalizeError(rerr *error) { + if rerr == nil { + return + } + + var commitNotOnBranchErr *errCommitNotOnBranch + + switch { + case errors.As(*rerr, &commitNotOnBranchErr): + *rerr = errs.WrapUserFacing(*rerr, + locale.Tl("err_identifier_branch_not_on_branch", "Commit does not belong to history for branch [ACTIONABLE]{{.V0}}[/RESET]", commitNotOnBranchErr.branch), + errs.SetInput(), + ) + } +} + +func (s *Switch) Run(params SwitchParams) (rerr error) { + defer rationalizeError(&rerr) logging.Debug("ExecuteSwitch") if s.project == nil { @@ -92,27 +124,27 @@ func (s *Switch) Run(params SwitchParams) error { project, err := model.LegacyFetchProjectByName(s.project.Owner(), s.project.Name()) if err != nil { - return locale.WrapError(err, "err_fetch_project", "", s.project.Namespace().String()) + return errs.Wrap(err, "Could not fetch project '%s'", s.project.Namespace().String()) } identifier, err := resolveIdentifier(project, params.Identifier) if err != nil { - return locale.WrapError(err, "err_resolve_identifier", "Could not resolve identifier '{{.V0}}'", params.Identifier) + return errs.Wrap(err, "Could not resolve identifier '%s'", params.Identifier) } if id, ok := identifier.(branchIdentifier); ok { err = s.project.Source().SetBranch(id.branch.Label) if err != nil { - return locale.WrapError(err, "err_switch_set_branch", "Could not update branch") + return errs.Wrap(err, "Could not update branch") } } belongs, err := model.CommitBelongsToBranch(s.project.Owner(), s.project.Name(), s.project.BranchName(), identifier.CommitID(), s.auth) if err != nil { - return locale.WrapError(err, "err_identifier_branch", "Could not determine if commit belongs to branch") + return errs.Wrap(err, "Could not determine if commit belongs to branch") } if !belongs { - return locale.NewInputError("err_identifier_branch_not_on_branch", "Commit does not belong to history for branch [ACTIONABLE]{{.V0}}[/RESET]", s.project.BranchName()) + return &errCommitNotOnBranch{identifier.CommitID().String(), s.project.BranchName()} } err = localcommit.Set(s.project.Dir(), identifier.CommitID().String()) @@ -120,9 +152,9 @@ func (s *Switch) Run(params SwitchParams) error { return errs.Wrap(err, "Unable to set local commit") } - _, err = runtime.SolveAndUpdate(s.auth, s.out, s.analytics, s.project, ptr.To(identifier.CommitID()), target.TriggerSwitch, s.svcModel, s.cfg, runtime.OptNone) + _, err = runtime_runbit.Update(s.prime, trigger.TriggerSwitch) if err != nil { - return locale.WrapError(err, "err_refresh_runtime") + return errs.Wrap(err, "Could not setup runtime") } s.out.Print(output.Prepare( @@ -144,7 +176,7 @@ func resolveIdentifier(project *mono_models.Project, idParam string) (identifier branch, err := model.BranchForProjectByName(project, idParam) if err != nil { - return nil, locale.WrapError(err, "err_identifier_branch", "Could not get branch '{{.V0}}' for current project", idParam) + return nil, errs.Wrap(err, "Could not get branch '%s'", idParam) } diff --git a/internal/runners/uninstall/rationalize.go b/internal/runners/uninstall/rationalize.go new file mode 100644 index 0000000000..387c9869a2 --- /dev/null +++ b/internal/runners/uninstall/rationalize.go @@ -0,0 +1,38 @@ +package uninstall + +import ( + "errors" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/runbits/rationalizers" + bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" +) + +func (u *Uninstall) rationalizeError(rerr *error) { + var noMatchesErr *errNoMatches + var multipleMatchesErr *errMultipleMatches + + switch { + case rerr == nil: + return + + case errors.As(*rerr, &noMatchesErr): + *rerr = errs.WrapUserFacing( + *rerr, + locale.Tr("err_uninstall_nomatch", noMatchesErr.packages.String()), + errs.SetInput()) + + case errors.As(*rerr, &multipleMatchesErr): + *rerr = errs.WrapUserFacing( + *rerr, + locale.Tr("err_uninstall_multimatch", multipleMatchesErr.packages.String()), + errs.SetInput()) + + // Error staging a commit during install. + case errors.As(*rerr, ptr.To(&bpResp.CommitError{})): + rationalizers.HandleCommitErrors(rerr) + + } +} diff --git a/internal/runners/uninstall/uninstall.go b/internal/runners/uninstall/uninstall.go new file mode 100644 index 0000000000..2de3aa2c18 --- /dev/null +++ b/internal/runners/uninstall/uninstall.go @@ -0,0 +1,218 @@ +package uninstall + +import ( + "fmt" + "strings" + + "github.com/ActiveState/cli/internal/captain" + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/internal/runbits/reqop_runbit" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" + "github.com/ActiveState/cli/internal/sliceutils" + "github.com/ActiveState/cli/pkg/buildscript" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/ActiveState/cli/pkg/platform/model" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" +) + +type primeable interface { + primer.Outputer + primer.Prompter + primer.Projecter + primer.Auther + primer.Configurer + primer.Analyticer + primer.SvcModeler +} + +// Params tracks the info required for running Uninstall. +type Params struct { + Packages captain.PackagesValue +} + +type requirement struct { + Requested *captain.PackageValue `json:"requested"` + Resolved types.Requirement `json:"resolved"` + + // Remainder are for display purposes only + Type model.NamespaceType `json:"type"` +} + +type requirements []*requirement + +func (r requirements) String() string { + result := []string{} + for _, req := range r { + if req.Resolved.Namespace != "" { + result = append(result, fmt.Sprintf("%s/%s", req.Resolved.Namespace, req.Requested.Name)) + } else { + result = append(result, req.Requested.Name) + } + } + return strings.Join(result, ", ") +} + +// Uninstall manages the installing execution context. +type Uninstall struct { + prime primeable + nsType model.NamespaceType +} + +// New prepares an installation execution context for use. +func New(prime primeable, nsType model.NamespaceType) *Uninstall { + return &Uninstall{prime, nsType} +} + +type errNoMatches struct { + error + packages captain.PackagesValue +} + +type errMultipleMatches struct { + error + packages captain.PackagesValue +} + +// Run executes the install behavior. +func (u *Uninstall) Run(params Params) (rerr error) { + defer u.rationalizeError(&rerr) + + logging.Debug("ExecuteUninstall") + + pj := u.prime.Project() + out := u.prime.Output() + bp := bpModel.NewBuildPlannerModel(u.prime.Auth(), u.prime.SvcModel()) + + // Verify input + if pj == nil { + return rationalize.ErrNoProject + } + if pj.IsHeadless() { + return rationalize.ErrHeadless + } + + out.Notice(locale.Tr("operating_message", pj.NamespaceString(), pj.Dir())) + + var pg *output.Spinner + defer func() { + if pg != nil { + pg.Stop(locale.T("progress_fail")) + } + }() + + // Start process of updating requirements + pg = output.StartSpinner(out, locale.T("progress_requirements"), constants.TerminalAnimationInterval) + + // Grab local commit info + localCommitID, err := localcommit.Get(u.prime.Project().Dir()) + if err != nil { + return errs.Wrap(err, "Unable to get local commit") + } + oldCommit, err := bp.FetchCommit(localCommitID, pj.Owner(), pj.Name(), nil) + if err != nil { + return errs.Wrap(err, "Failed to fetch old build result") + } + + // Update buildscript + script := oldCommit.BuildScript() + reqs, err := u.resolveRequirements(script, params.Packages) + if err != nil { + return errs.Wrap(err, "Failed to resolve requirements") + } + for _, req := range reqs { + if err := script.RemoveRequirement(req.Resolved); err != nil { + return errs.Wrap(err, "Unable to remove requirement") + } + } + + // Done updating requirements + pg.Stop(locale.T("progress_success")) + pg = nil + + // Update local checkout and source runtime changes + if err := reqop_runbit.UpdateAndReload(u.prime, script, oldCommit, locale.Tr("commit_message_removed", params.Packages.String()), trigger.TriggerUninstall); err != nil { + return errs.Wrap(err, "Failed to update local checkout") + } + + if out.Type().IsStructured() { + out.Print(output.Structured(reqs)) + } else { + u.renderUserFacing(reqs) + } + + // All done + out.Notice(locale.T("operation_success_local")) + + return nil +} + +func (u *Uninstall) renderUserFacing(reqs requirements) { + u.prime.Output().Notice("") + for _, req := range reqs { + l := "install_report_removed" + u.prime.Output().Notice(locale.Tr(l, fmt.Sprintf("%s/%s", req.Resolved.Namespace, req.Resolved.Name))) + } + u.prime.Output().Notice("") +} + +func (u *Uninstall) resolveRequirements(script *buildscript.BuildScript, pkgs captain.PackagesValue) (requirements, error) { + result := requirements{} + + reqs, err := script.DependencyRequirements() + if err != nil { + return nil, errs.Wrap(err, "Unable to get requirements") + } + + // Resolve requirements and check for errors + notFound := captain.PackagesValue{} + multipleMatches := captain.PackagesValue{} + for _, pkg := range pkgs { + // Filter matching requirements + matches := sliceutils.Filter(reqs, func(req types.Requirement) bool { + if pkg.Name != req.Name { + return false + } + if pkg.Namespace != "" { + return req.Namespace == pkg.Namespace + } + return model.NamespaceMatch(req.Namespace, u.nsType.Matchable()) + }) + + // Check for duplicate matches + if len(matches) > 1 { + multipleMatches = append(multipleMatches, pkg) + continue + } + + // Check for no matches + if len(matches) == 0 { + notFound = append(notFound, pkg) + continue + } + + result = append(result, &requirement{ + Requested: pkg, + Resolved: matches[0], + Type: model.ParseNamespace(matches[0].Namespace).Type(), + }) + } + + // Error out on duplicate matches + if len(multipleMatches) > 0 { + return result, &errMultipleMatches{error: errs.New("Could not find all requested packages"), packages: multipleMatches} + } + + // Error out on no matches + if len(notFound) > 0 { + return result, &errNoMatches{error: errs.New("Could not find all requested packages"), packages: notFound} + } + + return result, nil +} diff --git a/internal/runners/update/lock.go b/internal/runners/update/lock.go index aa09f74348..4be61c0b72 100644 --- a/internal/runners/update/lock.go +++ b/internal/runners/update/lock.go @@ -30,7 +30,7 @@ func (stv *StateToolChannelVersion) Set(arg string) error { return locale.WrapInputError( err, "err_channel_format", - "The State Tool channel and version provided is not formatting correctly, must be in the form of @", + "The State Tool channel and version provided is not formatting correctly. It must be in the form of @", ) } return nil @@ -146,7 +146,7 @@ func confirmLock(prom prompt.Prompter) error { func fetchExactVersion(svc *model.SvcModel, channel, version string) (string, error) { upd, err := svc.CheckUpdate(context.Background(), channel, version) if err != nil { - return "", locale.WrapExternalError(err, "err_update_fetch", "Could not retrieve update information, please verify that '{{.V0}}' is a valid channel.", channel) + return "", locale.WrapExternalError(err, "err_update_fetch", "Could not retrieve update information. Please verify that '{{.V0}}' is a valid channel.", channel) } return upd.Version, nil diff --git a/internal/runners/upgrade/upgrade.go b/internal/runners/upgrade/upgrade.go new file mode 100644 index 0000000000..eb82b499c2 --- /dev/null +++ b/internal/runners/upgrade/upgrade.go @@ -0,0 +1,343 @@ +package upgrade + +import ( + "errors" + "fmt" + "strconv" + "strings" + + "github.com/ActiveState/cli/internal/captain" + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/runbits/commits_runbit" + "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/internal/sliceutils" + "github.com/ActiveState/cli/internal/table" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/ActiveState/cli/pkg/platform/model" + bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" + "github.com/go-openapi/strfmt" +) + +type primeable interface { + primer.Outputer + primer.Auther + primer.Projecter + primer.Prompter + primer.SvcModeler +} + +type Params struct { + Timestamp captain.TimeValue + Expand bool +} + +func NewParams() *Params { + return &Params{} +} + +type Upgrade struct { + prime primeable +} + +func New(p primeable) *Upgrade { + return &Upgrade{ + prime: p, + } +} + +var ErrNoChanges = errors.New("no changes") +var ErrAbort = errors.New("aborted") + +func rationalizeError(err *error) { + switch { + case err == nil: + return + case errors.Is(*err, ErrNoChanges): + *err = errs.WrapUserFacing(*err, locale.T("upgrade_no_changes"), errs.SetInput()) + case errors.Is(*err, ErrAbort): + *err = errs.WrapUserFacing(*err, locale.T("upgrade_aborted"), errs.SetInput()) + } +} + +func (u *Upgrade) Run(params *Params) (rerr error) { + defer rationalizeError(&rerr) + + // Validate project + proj := u.prime.Project() + if proj == nil { + return rationalize.ErrNoProject + } + if proj.IsHeadless() { + return rationalize.ErrHeadless + } + + out := u.prime.Output() + out.Notice(locale.Tr("operating_message", proj.NamespaceString(), proj.Dir())) + + // Collect buildplans for before/after upgrade + pg := output.StartSpinner(out, locale.T("upgrade_solving"), constants.TerminalAnimationInterval) + defer func() { + if pg != nil { + pg.Stop(locale.T("progress_fail")) + } + }() + + // Collect "before" buildplan + localCommitID, err := localcommit.Get(proj.Dir()) + if err != nil { + return errs.Wrap(err, "Failed to get local commit") + } + + bpm := bpModel.NewBuildPlannerModel(u.prime.Auth(), u.prime.SvcModel()) + localCommit, err := bpm.FetchCommit(localCommitID, proj.Owner(), proj.Name(), nil) + if err != nil { + return errs.Wrap(err, "Failed to fetch build result") + } + + // Collect "after" buildplan + bumpedBS, err := localCommit.BuildScript().Clone() + if err != nil { + return errs.Wrap(err, "Failed to clone build script") + } + ts, err := commits_runbit.ExpandTime(¶ms.Timestamp, u.prime.Auth()) + if err != nil { + return errs.Wrap(err, "Failed to fetch latest timestamp") + } + bumpedBS.SetAtTime(ts, true) + + // Since our platform is commit based we need to create a commit for the "after" buildplan, even though we may not + // end up using it it the user doesn't confirm the upgrade. + bumpedCommit, err := bpm.StageCommit(bpModel.StageCommitParams{ + Owner: proj.Owner(), + Project: proj.Name(), + ParentCommit: localCommitID.String(), + Script: bumpedBS, + }) + if err != nil { + // The buildplanner itself can assert that there are no new changes, in which case we don't want to handle + // this as an error + var commitErr *response.CommitError + if errors.As(err, &commitErr) { + if commitErr.Type == types.NoChangeSinceLastCommitErrorType { + pg.Stop(locale.T("progress_success")) + pg = nil + return ErrNoChanges + } + } + return errs.Wrap(err, "Failed to stage bumped commit") + } + bumpedBP := bumpedCommit.BuildPlan() + + // All done collecting buildplans + pg.Stop(locale.T("progress_success")) + pg = nil + + changeset := bumpedBP.DiffArtifacts(localCommit.BuildPlan(), false) + if len(changeset.Filter(buildplan.ArtifactUpdated)) == 0 { + // In most cases we would've already reached this error due to the commit failing. But it is possible for + // the commit to be created (ie. there were changes), but without those changes being relevant to any artifacts + // that we care about. + return ErrNoChanges + } + + changes := u.calculateChanges(changeset, bumpedCommit) + if out.Type().IsStructured() { + out.Print(output.Structured(changes)) + } else { + if err := u.renderUserFacing(changes, params.Expand); err != nil { + return errs.Wrap(err, "Failed to render user facing upgrade") + } + } + + if err := localcommit.Set(u.prime.Project().Dir(), bumpedCommit.CommitID.String()); err != nil { + return errs.Wrap(err, "Failed to set local commit") + } + + out.Notice(locale.Tr("upgrade_success")) + + return nil +} + +type structuredChange struct { + Type string `json:"type"` + Name string `json:"name"` + Namespace string `json:"namespace,omitempty"` + OldVersion string `json:"old_version,omitempty"` + NewVersion string `json:"new_version"` + OldRevision int `json:"old_revision"` + NewRevision int `json:"new_revision"` + OldLicenses []string `json:"old_licenses,omitempty"` + NewLicenses []string `json:"new_licenses"` + TransitiveDeps []structuredChange `json:"transitive_dependencies,omitempty"` +} + +func (u *Upgrade) calculateChanges(changedArtifacts buildplan.ArtifactChangeset, bumpedCommit *bpModel.Commit) []structuredChange { + requested := bumpedCommit.BuildPlan().RequestedArtifacts().ToIDMap() + + relevantChanges := changedArtifacts.Filter(buildplan.ArtifactUpdated) + relevantRequestedArtifacts := buildplan.Artifacts{} + + // Calculate relevant artifacts ahead of time, as we'll need them to calculate transitive dependencies + // (we want to avoid recursing into the same artifact multiple times) + for _, change := range relevantChanges { + if _, ok := requested[change.Artifact.ArtifactID]; !ok { + continue + } + relevantRequestedArtifacts = append(relevantRequestedArtifacts, change.Artifact) + } + + changes := []structuredChange{} + for _, artifactUpdate := range changedArtifacts.Filter(buildplan.ArtifactUpdated) { + if _, ok := requested[artifactUpdate.Artifact.ArtifactID]; !ok { + continue + } + + change := structuredChange{ + Type: artifactUpdate.ChangeType.String(), + Name: artifactUpdate.Artifact.Name(), + OldVersion: artifactUpdate.Old.Version(), + NewVersion: artifactUpdate.Artifact.Version(), + OldRevision: artifactUpdate.Old.Revision(), + NewRevision: artifactUpdate.Artifact.Revision(), + OldLicenses: artifactUpdate.Old.Licenses(), + NewLicenses: artifactUpdate.Artifact.Licenses(), + } + + if len(artifactUpdate.Artifact.Ingredients) == 1 { + change.Namespace = artifactUpdate.Artifact.Ingredients[0].Namespace + } + + changedDeps := calculateChangedDeps(artifactUpdate.Artifact, relevantRequestedArtifacts, changedArtifacts) + if len(changedDeps) > 0 { + change.TransitiveDeps = make([]structuredChange, len(changedDeps)) + for n, changedDep := range changedDeps { + change.TransitiveDeps[n] = structuredChange{ + Type: changedDep.ChangeType.String(), + Name: changedDep.Artifact.Name(), + NewVersion: changedDep.Artifact.Version(), + NewRevision: changedDep.Artifact.Revision(), + NewLicenses: changedDep.Artifact.Licenses(), + } + if changedDep.Old != nil { + change.TransitiveDeps[n].OldVersion = changedDep.Old.Version() + change.TransitiveDeps[n].OldRevision = changedDep.Old.Revision() + change.TransitiveDeps[n].OldLicenses = changedDep.Old.Licenses() + } + } + } + + changes = append(changes, change) + } + + return changes +} + +func (u *Upgrade) renderUserFacing(changes []structuredChange, expand bool) error { + out := u.prime.Output() + + out.Notice("") // Empty line + + tbl := table.New(locale.Ts("name", "version", "license")) + tbl.HideDash = true + for _, change := range changes { + tbl.AddRow([]string{ + change.Name, + renderVersionChange(change), + renderLicenseChange(change), + }) + + needsDepRow := len(change.TransitiveDeps) > 0 + needsNamespaceRow := strings.HasPrefix(change.Namespace, model.NamespaceOrg.Prefix()) + + if needsNamespaceRow { + treeSymbol := output.TreeEnd + if needsDepRow { + treeSymbol = output.TreeMid + } + tbl.AddRow([]string{locale.Tr("namespace_row", treeSymbol, change.Namespace)}) + } + + if needsDepRow { + if expand { + for n, changedDep := range change.TransitiveDeps { + treeSymbol := output.TreeEnd + if n != len(change.TransitiveDeps)-1 { + treeSymbol = output.TreeMid + } + tbl.AddRow([]string{locale.Tr("dependency_detail_row", treeSymbol, changedDep.Name, renderVersionChange(changedDep))}) + } + } else { + tbl.AddRow([]string{locale.Tr("dependency_row", output.TreeEnd, strconv.Itoa(len(change.TransitiveDeps)))}) + } + } + } + + out.Print(tbl.Render()) + + out.Notice(" ") // Empty line (prompts use Notice) + confirm, err := u.prime.Prompt().Confirm("", locale.Tr("upgrade_confirm"), ptr.To(true)) + if err != nil { + return errs.Wrap(err, "confirmation failed") + } + if !confirm { + return ErrAbort + } + + return nil +} + +func calculateChangedDeps(artifact *buildplan.Artifact, dontCount buildplan.Artifacts, changeset buildplan.ArtifactChangeset) buildplan.ArtifactChangeset { + ignore := map[strfmt.UUID]struct{}{} + for _, skip := range dontCount { + if skip.ArtifactID == artifact.ArtifactID { + continue // Don't ignore the current artifact, or we won't get dependencies for it + } + ignore[skip.ArtifactID] = struct{}{} + } + + result := buildplan.ArtifactChangeset{} + + deps := artifact.Dependencies(true, &ignore) + for _, change := range changeset.Filter(buildplan.ArtifactAdded, buildplan.ArtifactUpdated) { + for _, dep := range deps { + if dep.ArtifactID == change.Artifact.ArtifactID { + result = append(result, change) + } + } + } + + return sliceutils.Unique(result) +} + +func renderVersionChange(change structuredChange) string { + if change.OldVersion == "" { + return locale.Tr("upgrade_field_same", change.NewVersion) + } + old := change.OldVersion + new := change.NewVersion + if change.OldVersion == change.NewVersion { + old = fmt.Sprintf("%s (%d)", old, change.OldRevision) + new = fmt.Sprintf("%s (%d)", new, change.NewRevision) + } + if old == new { + return locale.Tr("upgrade_field_same", change.NewVersion) + } + return locale.Tr("upgrade_field_change", change.OldVersion, change.NewVersion) +} + +func renderLicenseChange(change structuredChange) string { + from := change.OldLicenses + to := change.NewLicenses + if sliceutils.EqualValues(from, to) { + return locale.Tr("upgrade_field_same", strings.Join(from, ", ")) + } + return locale.Tr("upgrade_field_change", strings.Join(from, ", "), strings.Join(to, ", ")) +} diff --git a/internal/runners/use/show.go b/internal/runners/use/show.go index a93a26fbbd..5758be6340 100644 --- a/internal/runners/use/show.go +++ b/internal/runners/use/show.go @@ -1,15 +1,15 @@ package use import ( + "errors" + "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" + "github.com/ActiveState/cli/pkg/runtime_helpers" ) type Show struct { @@ -32,14 +32,14 @@ func (s *Show) Run() error { proj, err := project.FromPath(projectDir) if err != nil { - if errs.Matches(err, &projectfile.ErrorNoProject{}) { + var errNoProject *projectfile.ErrorNoProject + if errors.As(err, &errNoProject) { return locale.WrapError(err, "err_use_default_project_does_not_exist") } return locale.WrapError(err, "err_use_show_get_project", "Could not get your project.") } - projectTarget := target.NewProjectTarget(proj, nil, "") - executables := setup.ExecDir(projectTarget.Dir()) + executables := runtime_helpers.ExecutorPathFromProject(proj) s.out.Print(output.Prepare( locale.Tr("use_show_project_statement", diff --git a/internal/runners/use/use.go b/internal/runners/use/use.go index 13c623f322..1169a16deb 100644 --- a/internal/runners/use/use.go +++ b/internal/runners/use/use.go @@ -16,12 +16,11 @@ import ( "github.com/ActiveState/cli/internal/runbits/findproject" "github.com/ActiveState/cli/internal/runbits/git" "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" ) @@ -37,9 +36,14 @@ type primeable interface { primer.Configurer primer.SvcModeler primer.Analyticer + primer.Projecter } type Use struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 auth *authentication.Auth prompt prompt.Prompter out output.Outputer @@ -52,6 +56,7 @@ type Use struct { func NewUse(prime primeable) *Use { return &Use{ + prime, prime.Auth(), prime.Prompt(), prime.Output(), @@ -74,6 +79,8 @@ func (u *Use) Run(params *Params) error { return locale.WrapInputError(err, "err_use_cannot_find_local_project", "Local project cannot be found.") } + u.prime.SetProject(proj) + commitID, err := localcommit.Get(proj.Dir()) if err != nil { return errs.Wrap(err, "Unable to get local commit") @@ -83,7 +90,7 @@ func (u *Use) Run(params *Params) error { return locale.NewInputError("err_use_commit_id_mismatch") } - rti, err := runtime.SolveAndUpdate(u.auth, u.out, u.analytics, proj, nil, target.TriggerUse, u.svcModel, u.config, runtime.OptMinimalUI) + rti, err := runtime_runbit.Update(u.prime, trigger.TriggerUse, runtime_runbit.WithoutHeaders()) if err != nil { return locale.WrapError(err, "err_use_runtime_new", "Cannot use this project.") } @@ -92,7 +99,8 @@ func (u *Use) Run(params *Params) error { return locale.WrapError(err, "err_use_default", "Could not setup your project for use.") } - execDir := setup.ExecDir(rti.Target().Dir()) + execDir := rti.Env(false).ExecutorsPath + u.out.Print(output.Prepare( locale.Tr("use_project_statement", proj.NamespaceString(), proj.Dir(), execDir), &struct { diff --git a/internal/scriptrun/scriptrun.go b/internal/scriptrun/scriptrun.go index 4a6be0cb4f..12f94c17c9 100644 --- a/internal/scriptrun/scriptrun.go +++ b/internal/scriptrun/scriptrun.go @@ -13,19 +13,35 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/osutils" "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/process" - rtrunbit "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/scriptfile" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/virtualenvironment" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/project" ) +type primeable interface { + primer.Auther + primer.Outputer + primer.Projecter + primer.Subsheller + primer.Configurer + primer.Analyticer + primer.SvcModeler +} + // ScriptRun manages the context required to run a script. type ScriptRun struct { + prime primeable + // The remainder is redundant with the above. Refactoring this will follow in a later story so as not to blow + // up the one that necessitates adding the primer at this level. + // https://activestatef.atlassian.net/browse/DX-2869 + auth *authentication.Auth out output.Outputer sub subshell.SubShell @@ -39,15 +55,16 @@ type ScriptRun struct { } // New returns a pointer to a prepared instance of ScriptRun. -func New(auth *authentication.Auth, out output.Outputer, subs subshell.SubShell, proj *project.Project, cfg *config.Instance, analytics analytics.Dispatcher, svcModel *model.SvcModel) *ScriptRun { +func New(prime primeable) *ScriptRun { return &ScriptRun{ - auth, - out, - subs, - proj, - cfg, - analytics, - svcModel, + prime, + prime.Auth(), + prime.Output(), + prime.Subshell(), + prime.Project(), + prime.Config(), + prime.Analytics(), + prime.SvcModel(), false, @@ -65,7 +82,7 @@ func (s *ScriptRun) NeedsActivation() bool { // PrepareVirtualEnv sets up the relevant runtime and prepares the environment. func (s *ScriptRun) PrepareVirtualEnv() (rerr error) { - rt, err := rtrunbit.SolveAndUpdate(s.auth, s.out, s.analytics, s.project, nil, target.TriggerScript, s.svcModel, s.cfg, rtrunbit.OptMinimalUI) + rt, err := runtime_runbit.Update(s.prime, trigger.TriggerScript, runtime_runbit.WithoutHeaders()) if err != nil { return locale.WrapError(err, "err_activate_runtime", "Could not initialize a runtime for this project.") } diff --git a/internal/scriptrun/test/integration/scriptrun_test.go b/internal/scriptrun/test/integration/scriptrun_test.go index a9870b35a9..e7cc915608 100644 --- a/internal/scriptrun/test/integration/scriptrun_test.go +++ b/internal/scriptrun/test/integration/scriptrun_test.go @@ -9,7 +9,11 @@ import ( "testing" "github.com/ActiveState/cli/internal/analytics/client/blackhole" + "github.com/ActiveState/cli/internal/installation" + "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/scriptrun" + "github.com/ActiveState/cli/internal/svcctl" + "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/kami-zh/go-capturer" @@ -28,6 +32,7 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/osutil" "github.com/ActiveState/cli/internal/testhelpers/outputhelper" "github.com/ActiveState/cli/pkg/platform/authentication" + "github.com/ActiveState/cli/pkg/platform/model" "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" ) @@ -75,7 +80,7 @@ scripts: cfg, err := config.New() require.NoError(t, err) defer func() { require.NoError(t, cfg.Close()) }() - scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) + scriptRun := scriptrun.New(primer.New(proj, auth, outputhelper.NewCatcher(), subshell.New(cfg), cfg, blackhole.New())) script, err := proj.ScriptByName("run") require.NoError(t, err) err = scriptRun.Run(script, []string{}) @@ -85,6 +90,8 @@ scripts: func (suite *ScriptRunSuite) TestEnvIsSet() { suite.OnlyRunForTags(tagsuite.Scripts) t := suite.T() + ts := e2e.New(t, false) + defer ts.Close() if runtime.GOOS == "windows" { // For some reason this test hangs on Windows when ran via CI. I cannot reproduce the issue when manually invoking the @@ -107,18 +114,27 @@ func (suite *ScriptRunSuite) TestEnvIsSet() { require.NoError(t, err) os.Setenv("TEST_KEY_EXISTS", "true") - os.Setenv(constants.DisableRuntime, "true") defer func() { os.Unsetenv("TEST_KEY_EXISTS") - os.Unsetenv(constants.DisableRuntime) }() cfg, err := config.New() require.NoError(t, err) defer func() { require.NoError(t, cfg.Close()) }() + cfg.Set(constants.AsyncRuntimeConfig, true) + + ipcClient := svcctl.NewDefaultIPCClient() + var svcPort string + + svcExec, err := installation.ServiceExecFromDir(ts.Dirs.Bin) + suite.Require().NoError(err, errs.JoinMessage(err)) + + svcPort, err = svcctl.EnsureExecStartedAndLocateHTTP(ipcClient, svcExec, "from test", nil) + suite.Require().NoError(err, errs.JoinMessage(err)) + out := capturer.CaptureOutput(func() { - scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) + scriptRun := scriptrun.New(primer.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), model.NewSvcModel(svcPort))) script, err := proj.ScriptByName("run") require.NoError(t, err, "Error: "+errs.JoinMessage(err)) err = scriptRun.Run(script, nil) @@ -166,7 +182,7 @@ scripts: defer func() { require.NoError(t, cfg.Close()) }() out := outputhelper.NewCatcher() - scriptRun := scriptrun.New(auth, out, subshell.New(cfg), proj, cfg, blackhole.New(), nil) + scriptRun := scriptrun.New(primer.New(auth, out, subshell.New(cfg), proj, cfg, blackhole.New())) script, err := proj.ScriptByName("run") fmt.Println(script) require.NoError(t, err) @@ -198,7 +214,7 @@ scripts: require.NoError(t, err) defer func() { require.NoError(t, cfg.Close()) }() - scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) + scriptRun := scriptrun.New(primer.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New())) err = scriptRun.Run(nil, nil) assert.Error(t, err, "No error occurred") } @@ -228,7 +244,7 @@ scripts: require.NoError(t, err) defer func() { require.NoError(t, cfg.Close()) }() - scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) + scriptRun := scriptrun.New(primer.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New())) script, err := proj.ScriptByName("run") require.NoError(t, err) err = scriptRun.Run(script, nil) @@ -283,7 +299,7 @@ scripts: require.NoError(t, err) // Run the command. - scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) + scriptRun := scriptrun.New(primer.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New())) script, err := proj.ScriptByName("run") require.NoError(t, err) err = scriptRun.Run(script, nil) @@ -352,6 +368,7 @@ project: "https://platform.activestate.com/ActiveState/project" scripts: - name: %s standalone: true + language: batch value: | echo "ARGS|%%1|%%2|%%3|%%4|"`, cmdName) } @@ -362,28 +379,24 @@ scripts: } func captureExecCommand(t *testing.T, tmplCmdName, cmdName string, cmdArgs []string) (string, error) { - auth, err := authentication.LegacyGet() require.NoError(t, err) pjfile := setupProjectWithScriptsExpectingArgs(t, tmplCmdName) - proj, err := project.New(pjfile, nil) require.NoError(t, err) - cfg, err := config.New() require.NoError(t, err) defer func() { require.NoError(t, cfg.Close()) }() outStr, outErr := osutil.CaptureStdout(func() { - scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) + scriptRun := scriptrun.New(primer.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New())) var script *project.Script if script, err = proj.ScriptByName(cmdName); err == nil { err = scriptRun.Run(script, cmdArgs) } }) require.NoError(t, outErr, "error capturing stdout") - return outStr, err } diff --git a/internal/scriptrun/test/integration/testdata/printEnv/activestate.yaml b/internal/scriptrun/test/integration/testdata/printEnv/activestate.yaml index 434ce53286..1f049c3fc3 100644 --- a/internal/scriptrun/test/integration/testdata/printEnv/activestate.yaml +++ b/internal/scriptrun/test/integration/testdata/printEnv/activestate.yaml @@ -1,4 +1,4 @@ -project: https://platform.activestate.com/ActiveState/project?branch=main +project: https://platform.activestate.com/ActiveState-CLI/Empty?branch=main&commitID=6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8 scripts: - name: run value: printenv diff --git a/internal/secrets/secrets.go b/internal/secrets/secrets.go index 5abb8e445a..e4c3a3bb54 100644 --- a/internal/secrets/secrets.go +++ b/internal/secrets/secrets.go @@ -1,7 +1,8 @@ package secrets import ( - "github.com/ActiveState/cli/internal/errs" + "errors" + "github.com/ActiveState/cli/internal/keypairs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" @@ -63,7 +64,9 @@ func ShareWithOrgUsers(secretsClient *secretsapi.Client, org *mono_models.Organi if currentUserID != member.User.UserID { pubKey, err := keypairs.FetchPublicKey(secretsClient, member.User, auth) if err != nil { - if errs.Matches(err, &keypairs.ErrKeypairNotFound{}) { + var errKeypairNotFound *keypairs.ErrKeypairNotFound + + if errors.As(err, &errKeypairNotFound) { logging.Info("User `%s` has no public-key", member.User.Username) // this is okay, just do what we can continue diff --git a/internal/sliceutils/sliceutils.go b/internal/sliceutils/sliceutils.go index 511e5774a6..fb22a6366b 100644 --- a/internal/sliceutils/sliceutils.go +++ b/internal/sliceutils/sliceutils.go @@ -1,6 +1,8 @@ package sliceutils import ( + "cmp" + "github.com/ActiveState/cli/internal/errs" "github.com/go-openapi/strfmt" "golang.org/x/text/unicode/norm" @@ -17,14 +19,20 @@ func RemoveFromStrings(slice []string, indexes ...int) []string { } func GetInt(slice []int, index int) (int, bool) { - if index > len(slice)-1 { + if index < 0 { + index = len(slice) + index + } + if index > len(slice)-1 || index < 0 { return -1, false } return slice[index], true } func GetString(slice []string, index int) (string, bool) { - if index > len(slice)-1 { + if index < 0 { + index = len(slice) + index + } + if index > len(slice)-1 || index < 0 { return "", false } // return normalized string @@ -112,3 +120,36 @@ func ToLookupMapByKey[T any, K string | int | strfmt.UUID](data []T, keyCb func( } return result } + +// EqualValues checks if two slices have equal values, regardless of ordering. This does not recurse into nested slices or structs. +func EqualValues[S ~[]E, E cmp.Ordered](a, b S) bool { + if len(a) != len(b) { + return false + } + + lookup := make(map[E]struct{}, len(a)) + for _, e := range a { + lookup[e] = struct{}{} + } + + for _, e := range b { + if _, ok := lookup[e]; !ok { + return false + } + } + + return true +} + +// Cast allows casting of a slice of any type to a slice of a specific type. +func Cast[T any](slice []any) ([]T, bool) { + result := []T{} + for _, s := range slice { + v, ok := s.(T) + if !ok { + return nil, false + } + result = append(result, v) + } + return result, true +} diff --git a/internal/sliceutils/sliceutils_test.go b/internal/sliceutils/sliceutils_test.go index 4989aea6f7..dbd6b5d69c 100644 --- a/internal/sliceutils/sliceutils_test.go +++ b/internal/sliceutils/sliceutils_test.go @@ -323,3 +323,49 @@ func TestToLookupMapByKey(t *testing.T) { "Key3": v3, }, lookupMap) } + +func TestEqualValues(t *testing.T) { + tests := []struct { + name string + comparison func() bool + expected bool + }{ + { + name: "Equal int slices", + comparison: func() bool { + return EqualValues([]int{1, 2, 3}, []int{3, 2, 1}) + }, + expected: true, + }, + { + name: "Unequal int slices", + comparison: func() bool { + return EqualValues([]int{1, 2, 3}, []int{4, 5, 6}) + }, + expected: false, + }, + { + name: "Equal string slices", + comparison: func() bool { + return EqualValues([]string{"a", "b", "c"}, []string{"c", "b", "a"}) + }, + expected: true, + }, + { + name: "Unequal string slices", + comparison: func() bool { + return EqualValues([]string{"a", "b", "c"}, []string{"a", "b", "d"}) + }, + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.comparison() + if result != tt.expected { + t.Errorf("%s = %v; want %v", tt.name, result, tt.expected) + } + }) + } +} diff --git a/internal/smartlink/smartlink.go b/internal/smartlink/smartlink.go new file mode 100644 index 0000000000..c101abde5e --- /dev/null +++ b/internal/smartlink/smartlink.go @@ -0,0 +1,160 @@ +package smartlink + +import ( + "os" + "path/filepath" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/logging" +) + +// LinkContents will link the contents of src to desc +func LinkContents(src, dest string) error { + if !fileutils.DirExists(src) { + return errs.New("src dir does not exist: %s", src) + } + if err := fileutils.MkdirUnlessExists(dest); err != nil { + return errs.Wrap(err, "Could not create dir: %s", dest) + } + + var err error + src, dest, err = resolvePaths(src, dest) + if err != nil { + return errs.Wrap(err, "Could not resolve src and dest paths") + } + + entries, err := os.ReadDir(src) + if err != nil { + return errs.Wrap(err, "Reading dir %s failed", src) + } + for _, entry := range entries { + if err := Link(filepath.Join(src, entry.Name()), filepath.Join(dest, entry.Name())); err != nil { + return errs.Wrap(err, "Link failed") + } + } + + return nil +} + +// Link creates a link from src to target. MS decided to support Symlinks but only if you opt into developer mode (go figure), +// which we cannot reasonably force on our users. So on Windows we will instead create dirs and hardlinks. +func Link(src, dest string) error { + originalSrc := src + + var err error + src, dest, err = resolvePaths(src, dest) + if err != nil { + return errs.Wrap(err, "Could not resolve src and dest paths") + } + + if fileutils.IsDir(src) { + if fileutils.IsSymlink(originalSrc) { + // If the original src is a symlink, the resolved src is no longer a symlink and could point + // to a parent directory, resulting in a recursive directory structure. + // Avoid any potential problems by simply linking the original link to the target. + // Links to directories are okay on Linux and macOS, but will fail on Windows. + // If we ever get here on Windows, the artifact being deployed is bad and there's nothing we + // can do about it except receive the report from Rollbar and report it internally. + return linkFile(originalSrc, dest) + } + + if err := fileutils.Mkdir(dest); err != nil { + return errs.Wrap(err, "could not create directory %s", dest) + } + entries, err := os.ReadDir(src) + if err != nil { + return errs.Wrap(err, "could not read directory %s", src) + } + for _, entry := range entries { + if err := Link(filepath.Join(src, entry.Name()), filepath.Join(dest, entry.Name())); err != nil { + return errs.Wrap(err, "sub link failed") + } + } + return nil + } + + destDir := filepath.Dir(dest) + if err := fileutils.MkdirUnlessExists(destDir); err != nil { + return errs.Wrap(err, "could not create directory %s", destDir) + } + + // Multiple artifacts can supply the same file. We do not have a better solution for this at the moment other than + // favouring the first one encountered. + if fileutils.TargetExists(dest) { + logging.Warning("Skipping linking '%s' to '%s' as it already exists", src, dest) + return nil + } + + if err := linkFile(src, dest); err != nil { + return errs.Wrap(err, "could not link %s to %s", src, dest) + } + return nil +} + +// UnlinkContents will unlink the contents of src to dest if the links exist +// WARNING: on windows smartlinks are hard links, and relating hard links back to their source is non-trivial, so instead +// we just delete the target path. If the user modified the target in any way their changes will be lost. +func UnlinkContents(src, dest string) error { + if !fileutils.DirExists(dest) { + return errs.New("dest dir does not exist: %s", dest) + } + + var err error + src, dest, err = resolvePaths(src, dest) + if err != nil { + return errs.Wrap(err, "Could not resolve src and dest paths") + } + + entries, err := os.ReadDir(src) + if err != nil { + return errs.Wrap(err, "Reading dir %s failed", dest) + } + for _, entry := range entries { + srcPath := filepath.Join(src, entry.Name()) + destPath := filepath.Join(dest, entry.Name()) + if !fileutils.TargetExists(destPath) { + logging.Warning("Could not unlink '%s' as it does not exist, it may have already been removed by another artifact", destPath) + continue + } + + if fileutils.IsDir(destPath) { + if err := UnlinkContents(srcPath, destPath); err != nil { + return err // Not wrapping here cause it'd just repeat the same error due to the recursion + } + } else { + if err := os.Remove(destPath); err != nil { + return errs.Wrap(err, "Could not delete %s", destPath) + } + } + } + + // Clean up empty dir afterwards + isEmpty, err := fileutils.IsEmptyDir(dest) + if err != nil { + return errs.Wrap(err, "Could not check if dir %s is empty", dest) + } + if isEmpty { + if err := os.Remove(dest); err != nil { + return errs.Wrap(err, "Could not delete dir %s", dest) + } + } + + return nil +} + +// resolvePaths will resolve src and dest to absolute paths and return them. +// This is to ensure that we're always comparing apples to apples when doing string comparisons on paths. +func resolvePaths(src, dest string) (string, string, error) { + var err error + src, err = fileutils.ResolveUniquePath(src) + if err != nil { + return "", "", errs.Wrap(err, "Could not resolve src path") + } + dest, err = fileutils.ResolveUniquePath(dest) + if err != nil { + return "", "", errs.Wrap(err, "Could not resolve dest path") + } + + return src, dest, nil +} diff --git a/internal/smartlink/smartlink_lin_mac.go b/internal/smartlink/smartlink_lin_mac.go new file mode 100644 index 0000000000..edc065f280 --- /dev/null +++ b/internal/smartlink/smartlink_lin_mac.go @@ -0,0 +1,14 @@ +//go:build !windows +// +build !windows + +package smartlink + +import ( + "os" +) + +// file will create a symlink from src to dest, and falls back on a hardlink if no symlink is available. +// This is a workaround for the fact that Windows does not support symlinks without admin privileges. +func linkFile(src, dest string) error { + return os.Symlink(src, dest) +} diff --git a/internal/smartlink/smartlink_test.go b/internal/smartlink/smartlink_test.go new file mode 100644 index 0000000000..50a772254f --- /dev/null +++ b/internal/smartlink/smartlink_test.go @@ -0,0 +1,75 @@ +package smartlink + +import ( + "os" + "path/filepath" + "runtime" + "testing" + + "github.com/ActiveState/cli/internal/fileutils" + "github.com/stretchr/testify/require" +) + +func TestLinkContentsWithCircularLink(t *testing.T) { + srcDir, err := os.MkdirTemp("", "src") + require.NoError(t, err) + defer os.RemoveAll(srcDir) + + destDir, err := os.MkdirTemp("", "dest") + require.NoError(t, err) + defer os.RemoveAll(destDir) + + // Create test file structure: + // src/ + // ├── regular.txt + // └── subdir/ + // ├── circle -> subdir (circular link) + // └── subfile.txt + + testFile := filepath.Join(srcDir, "regular.txt") + err = os.WriteFile(testFile, []byte("test content"), 0644) + require.NoError(t, err) + + subDir := filepath.Join(srcDir, "subdir") + err = os.Mkdir(subDir, 0755) + require.NoError(t, err) + + subFile := filepath.Join(subDir, "subfile.txt") + err = os.WriteFile(subFile, []byte("sub content"), 0644) + require.NoError(t, err) + + circularLink := filepath.Join(subDir, "circle") + err = os.Symlink(subDir, circularLink) + require.NoError(t, err) + + err = LinkContents(srcDir, destDir) + if runtime.GOOS == "windows" { + require.Error(t, err) + return // hard links to directories are not allowed on Windows + } + require.NoError(t, err) + + // Verify file structure. + destFile := filepath.Join(destDir, "regular.txt") + require.FileExists(t, destFile) + content, err := os.ReadFile(destFile) + require.NoError(t, err) + require.Equal(t, "test content", string(content)) + + destSubFile := filepath.Join(destDir, "subdir", "subfile.txt") + require.FileExists(t, destSubFile) + subContent, err := os.ReadFile(destSubFile) + require.NoError(t, err) + require.Equal(t, "sub content", string(subContent)) + + destCircular := filepath.Join(destDir, "subdir", "circle") + require.FileExists(t, destCircular) + target, err := fileutils.ResolveUniquePath(destCircular) + require.NoError(t, err) + srcCircular := filepath.Join(srcDir, "subdir") + if runtime.GOOS == "darwin" { + srcCircular, err = fileutils.ResolveUniquePath(srcCircular) // needed for full $TMPDIR resolution + require.NoError(t, err) + } + require.Equal(t, target, srcCircular) +} diff --git a/internal/smartlink/smartlink_windows.go b/internal/smartlink/smartlink_windows.go new file mode 100644 index 0000000000..1c86110cf7 --- /dev/null +++ b/internal/smartlink/smartlink_windows.go @@ -0,0 +1,17 @@ +package smartlink + +import ( + "os" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" +) + +// linkFile will create a symlink from src to dest, and falls back on a hardlink if no symlink is available. +// This is a workaround for the fact that Windows does not support symlinks without admin privileges. +func linkFile(src, dest string) error { + if fileutils.IsDir(src) { + return errs.New("src is a directory, not a file: %s", src) + } + return os.Link(src, dest) +} diff --git a/internal/subshell/bash/bash.go b/internal/subshell/bash/bash.go index 56fe481681..e7882ce165 100644 --- a/internal/subshell/bash/bash.go +++ b/internal/subshell/bash/bash.go @@ -106,7 +106,6 @@ func (v *SubShell) WriteCompletionScript(completionScript string) error { } fpath := filepath.Join(dir, constants.CommandName) - logging.Debug("Writing to %s: %s", fpath, completionScript) err := fileutils.WriteFile(fpath, []byte(completionScript)) if err != nil { logging.Debug("Could not write completions script '%s', likely due to non-admin privileges", fpath) diff --git a/internal/subshell/pwsh/pwsh.go b/internal/subshell/pwsh/pwsh.go new file mode 100644 index 0000000000..1a1d95665d --- /dev/null +++ b/internal/subshell/pwsh/pwsh.go @@ -0,0 +1,163 @@ +package pwsh + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "runtime" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/osutils" + "github.com/ActiveState/cli/internal/osutils/user" + "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/subshell/cmd" + "github.com/ActiveState/cli/internal/subshell/sscommon" + "github.com/ActiveState/cli/pkg/project" +) + +// SubShell covers the subshell.SubShell interface, reference that for documentation +type SubShell struct { + binary string + rcFile *os.File + cmd *exec.Cmd + env map[string]string + errs chan error +} + +const Name string = "powershell" + +// Shell - see subshell.SubShell +func (v *SubShell) Shell() string { + return Name +} + +// Binary - see subshell.SubShell +func (v *SubShell) Binary() string { + return v.binary +} + +// SetBinary - see subshell.SubShell +func (v *SubShell) SetBinary(binary string) { + v.binary = binary +} + +// WriteUserEnv - see subshell.SubShell +func (v *SubShell) WriteUserEnv(cfg sscommon.Configurable, env map[string]string, envType sscommon.RcIdentification, userScope bool) error { + cmdShell := &cmd.SubShell{} + if err := cmdShell.WriteUserEnv(cfg, env, envType, userScope); err != nil { + return errs.Wrap(err, "Forwarded WriteUserEnv call failed") + } + + return nil +} + +func (v *SubShell) CleanUserEnv(cfg sscommon.Configurable, envType sscommon.RcIdentification, userScope bool) error { + cmdShell := &cmd.SubShell{} + if err := cmdShell.CleanUserEnv(cfg, envType, userScope); err != nil { + return errs.Wrap(err, "Forwarded CleanUserEnv call failed") + } + + return nil +} + +func (v *SubShell) RemoveLegacyInstallPath(_ sscommon.Configurable) error { + return nil +} + +func (v *SubShell) WriteCompletionScript(completionScript string) error { + return locale.NewError("err_writecompletions_notsupported", "{{.V0}} does not support completions.", v.Shell()) +} + +func (v *SubShell) RcFile() (string, error) { + home, err := user.HomeDir() + if err != nil { + return "", errs.Wrap(err, "Could not get home dir") + } + + return filepath.Join(home, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1"), nil +} + +func (v *SubShell) EnsureRcFileExists() error { + rcFile, err := v.RcFile() + if err != nil { + return errs.Wrap(err, "Could not determine rc file") + } + + return fileutils.TouchFileUnlessExists(rcFile) +} + +// SetupShellRcFile - subshell.SubShell +func (v *SubShell) SetupShellRcFile(targetDir string, env map[string]string, namespace *project.Namespaced, cfg sscommon.Configurable) error { + env = sscommon.EscapeEnv(env) + return sscommon.SetupShellRcFile(filepath.Join(targetDir, "shell.ps1"), "pwsh_global.ps1", env, namespace, cfg) +} + +// SetEnv - see subshell.SetEnv +func (v *SubShell) SetEnv(env map[string]string) error { + v.env = env + return nil +} + +// Quote - see subshell.Quote +func (v *SubShell) Quote(value string) string { + return value // not implemented as Quote is no longer used, can get rid of this in the refactor. +} + +// Activate - see subshell.SubShell +func (v *SubShell) Activate(prj *project.Project, cfg sscommon.Configurable, out output.Outputer) error { + var shellArgs []string + var directEnv []string + + if prj != nil { + var err error + if v.rcFile, err = sscommon.SetupProjectRcFile(prj, "pwsh.ps1", ".ps1", v.env, out, cfg, false); err != nil { + return err + } + + shellArgs = []string{"-executionpolicy", "bypass", "-NoExit", "-Command", fmt.Sprintf(". '%s'", v.rcFile.Name())} + } else { + directEnv = sscommon.EnvSlice(v.env) + } + + // powershell -NoExit -Command "& 'C:\Temp\profile.ps1'" + cmd := sscommon.NewCommand(v.binary, shellArgs, directEnv) + v.errs = sscommon.Start(cmd) + v.cmd = cmd + return nil +} + +// Errors returns a channel for receiving errors related to active behavior +func (v *SubShell) Errors() <-chan error { + return v.errs +} + +// Deactivate - see subshell.SubShell +func (v *SubShell) Deactivate() error { + if !v.IsActive() { + return nil + } + + if err := sscommon.Stop(v.cmd); err != nil { + return err + } + + v.cmd = nil + return nil +} + +// Run - see subshell.SubShell +func (v *SubShell) Run(filename string, args ...string) error { + return sscommon.RunFuncByBinary(v.Binary())(osutils.EnvMapToSlice(v.env), filename, args...) +} + +// IsActive - see subshell.SubShell +func (v *SubShell) IsActive() bool { + return v.cmd != nil && (v.cmd.ProcessState == nil || !v.cmd.ProcessState.Exited()) +} + +func (v *SubShell) IsAvailable() bool { + return runtime.GOOS == "windows" +} diff --git a/internal/subshell/sscommon/rcfile.go b/internal/subshell/sscommon/rcfile.go index 14c2c1eef0..80100c26a0 100644 --- a/internal/subshell/sscommon/rcfile.go +++ b/internal/subshell/sscommon/rcfile.go @@ -10,9 +10,10 @@ import ( "strings" "text/template" - "github.com/ActiveState/cli/internal/installation/storage" "github.com/mash/go-tempfile-suffix" + "github.com/ActiveState/cli/internal/installation/storage" + "github.com/ActiveState/cli/internal/assets" "github.com/ActiveState/cli/internal/colorize" "github.com/ActiveState/cli/internal/constants" @@ -20,7 +21,6 @@ import ( "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" - configMediator "github.com/ActiveState/cli/internal/mediators/config" "github.com/ActiveState/cli/internal/osutils" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/pkg/project" @@ -54,10 +54,6 @@ var ( } ) -func init() { - configMediator.RegisterOption(constants.PreservePs1ConfigKey, configMediator.Bool, false) -} - // Configurable defines an interface to store and get configuration data type Configurable interface { Set(string, interface{}) error @@ -106,8 +102,6 @@ func WriteRcFile(rcTemplateName string, path string, data RcIdentification, env return errs.Wrap(err, "Templating failure") } - logging.Debug("Writing to %s:\n%s", path, out.String()) - return fileutils.AppendToFile(path, []byte(fileutils.LineEnd+out.String())) } @@ -121,7 +115,6 @@ func WriteRcData(data string, path string, identification RcIdentification) erro } data = identification.Start + fileutils.LineEnd + data + fileutils.LineEnd + identification.Stop - logging.Debug("Writing to %s:\n%s", path, data) return fileutils.AppendToFile(path, []byte(fileutils.LineEnd+data)) } @@ -217,9 +210,8 @@ func SetupShellRcFile(rcFileName, templateName string, env map[string]string, na var out bytes.Buffer rcData := map[string]interface{}{ - "Env": env, - "Project": projectValue, - "PreservePs1": cfg.GetBool(constants.PreservePs1ConfigKey), + "Env": env, + "Project": projectValue, } err = t.Execute(&out, rcData) if err != nil { @@ -332,6 +324,7 @@ func SetupProjectRcFile(prj *project.Project, templateName, ext string, env map[ rcData := map[string]interface{}{ "Owner": prj.Owner(), "Name": prj.Name(), + "Project": prj.NamespaceString(), "Env": actualEnv, "WD": wd, "UserScripts": userScripts, @@ -339,7 +332,6 @@ func SetupProjectRcFile(prj *project.Project, templateName, ext string, env map[ "ExecName": constants.CommandName, "ActivatedMessage": colorize.ColorizedOrStrip(locale.Tl("project_activated", "[SUCCESS]✔ Project \"{{.V0}}\" Has Been Activated[/RESET]", prj.Namespace().String()), isConsole), - "PreservePs1": cfg.GetBool(constants.PreservePs1ConfigKey), } currExec := osutils.Executable() @@ -368,6 +360,22 @@ func SetupProjectRcFile(prj *project.Project, templateName, ext string, env map[ t := template.New("rcfile") t.Funcs(map[string]interface{}{ "splitLines": func(v string) []string { return strings.Split(v, "\n") }, + "escapePwsh": func(v string) string { + // Conver unicode characters + result := "" + for _, char := range v { + if char < 128 { + result += string(char) + } else { + result += fmt.Sprintf("$([char]0x%04x)", char) + } + } + + // Escape special characters + result = strings.ReplaceAll(result, "`", "``") + result = strings.ReplaceAll(result, "\"", "`\"") + return result + }, }) t, err = t.Parse(string(tpl)) @@ -392,8 +400,6 @@ func SetupProjectRcFile(prj *project.Project, templateName, ext string, env map[ return nil, errs.Wrap(err, "Failed to write to output buffer.") } - logging.Debug("Using project RC: (%s) %s", tmpFile.Name(), o.String()) - return tmpFile, nil } diff --git a/internal/subshell/sscommon/sscommon.go b/internal/subshell/sscommon/sscommon.go index 57edb5a9c4..21228c9923 100644 --- a/internal/subshell/sscommon/sscommon.go +++ b/internal/subshell/sscommon/sscommon.go @@ -84,8 +84,8 @@ func RunFuncByBinary(binary string) RunFunc { switch { case strings.Contains(bin, "bash"): return runWithBash - case strings.Contains(bin, "cmd"): - return runWithCmd + case strings.Contains(bin, "cmd"), strings.Contains(bin, "powershell"): + return runWindowsShell default: return runDirect } @@ -107,7 +107,7 @@ func runWithBash(env []string, name string, args ...string) error { return runDirect(env, "bash", "-c", quotedArgs) } -func runWithCmd(env []string, name string, args ...string) error { +func runWindowsShell(env []string, name string, args ...string) error { ext := filepath.Ext(name) switch ext { case ".py": diff --git a/internal/subshell/subshell.go b/internal/subshell/subshell.go index 0c76098721..8844de8e69 100644 --- a/internal/subshell/subshell.go +++ b/internal/subshell/subshell.go @@ -1,12 +1,18 @@ package subshell import ( + "errors" "os" "os/exec" + "path" "path/filepath" "runtime" "strings" + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/shirou/gopsutil/v3/process" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/logging" @@ -17,6 +23,7 @@ import ( "github.com/ActiveState/cli/internal/subshell/bash" "github.com/ActiveState/cli/internal/subshell/cmd" "github.com/ActiveState/cli/internal/subshell/fish" + "github.com/ActiveState/cli/internal/subshell/pwsh" "github.com/ActiveState/cli/internal/subshell/sscommon" "github.com/ActiveState/cli/internal/subshell/tcsh" "github.com/ActiveState/cli/internal/subshell/zsh" @@ -99,6 +106,8 @@ func New(cfg sscommon.Configurable) SubShell { subs = &fish.SubShell{} case cmd.Name: subs = &cmd.SubShell{} + case pwsh.Name: + subs = &pwsh.SubShell{} default: rollbar.Error("subshell.DetectShell did not return a known name: %s", name) switch runtime.GOOS { @@ -113,7 +122,7 @@ func New(cfg sscommon.Configurable) SubShell { logging.Debug("Using binary: %s", path) subs.SetBinary(path) - + err := subs.SetEnv(osutils.EnvSliceToMap(os.Environ())) if err != nil { // We cannot error here, but this error will resurface when activating a runtime, so we can @@ -175,20 +184,24 @@ func DetectShell(cfg sscommon.Configurable) (string, string) { } }() - binary = os.Getenv("SHELL") - if binary == "" && runtime.GOOS == "windows" { - binary = os.Getenv("ComSpec") + if os.Getenv(constants.OverrideShellEnvVarName) != "" { + binary = os.Getenv(constants.OverrideShellEnvVarName) + } + + if binary == "" { + binary = detectShellParent() } if binary == "" { binary = configured } + if binary == "" { - if runtime.GOOS == "windows" { - binary = "cmd.exe" - } else { - binary = "bash" - } + binary = os.Getenv(SHELL_ENV_VAR) + } + + if binary == "" { + binary = OS_DEFAULT } path := resolveBinaryPath(binary) @@ -204,7 +217,7 @@ func DetectShell(cfg sscommon.Configurable) (string, string) { } isKnownShell := false - for _, ssName := range []string{bash.Name, cmd.Name, fish.Name, tcsh.Name, zsh.Name} { + for _, ssName := range []string{bash.Name, cmd.Name, fish.Name, tcsh.Name, zsh.Name, pwsh.Name} { if name == ssName { isKnownShell = true break @@ -213,7 +226,7 @@ func DetectShell(cfg sscommon.Configurable) (string, string) { if !isKnownShell { logging.Debug("Unsupported shell: %s, defaulting to OS default.", name) - if !strings.EqualFold(name, "powershell") && name != "sh" { + if name != "sh" { rollbar.Error("Unsupported shell: %s", name) // we just want to know what this person is using } switch runtime.GOOS { @@ -231,3 +244,25 @@ func DetectShell(cfg sscommon.Configurable) (string, string) { return name, path } + +func detectShellParent() string { + p, err := process.NewProcess(int32(os.Getppid())) + if err != nil && !errors.As(err, ptr.To(&os.PathError{})) { + multilog.Error("Failed to get parent process: %s", errs.JoinMessage(err)) + } + + for p != nil && p.Pid != 0 { + name, err := p.Name() + if err == nil { + if strings.Contains(name, string(filepath.Separator)) { + name = path.Base(name) + } + if supportedShellName(name) { + return name + } + } + p, _ = p.Parent() + } + + return "" +} diff --git a/internal/subshell/subshell_lin_mac.go b/internal/subshell/subshell_lin_mac.go index bcf296d137..9a666e16cb 100644 --- a/internal/subshell/subshell_lin_mac.go +++ b/internal/subshell/subshell_lin_mac.go @@ -4,6 +4,8 @@ package subshell import ( + "strings" + "github.com/ActiveState/cli/internal/subshell/bash" "github.com/ActiveState/cli/internal/subshell/cmd" "github.com/ActiveState/cli/internal/subshell/fish" @@ -18,3 +20,17 @@ var supportedShells = []SubShell{ &fish.SubShell{}, &cmd.SubShell{}, } + +const ( + SHELL_ENV_VAR = "SHELL" + OS_DEFAULT = "bash" +) + +func supportedShellName(filename string) bool { + for _, subshell := range supportedShells { + if strings.EqualFold(filename, subshell.Shell()) { + return true + } + } + return false +} diff --git a/internal/subshell/subshell_win.go b/internal/subshell/subshell_win.go index 12df8f51e2..b0332a8008 100644 --- a/internal/subshell/subshell_win.go +++ b/internal/subshell/subshell_win.go @@ -3,8 +3,31 @@ package subshell -import "github.com/ActiveState/cli/internal/subshell/cmd" +import ( + "fmt" + "strings" + + "github.com/ActiveState/cli/internal/subshell/bash" + "github.com/ActiveState/cli/internal/subshell/cmd" + "github.com/ActiveState/cli/internal/subshell/pwsh" +) var supportedShells = []SubShell{ &cmd.SubShell{}, + &pwsh.SubShell{}, + &bash.SubShell{}, +} + +const ( + SHELL_ENV_VAR = "COMSPEC" + OS_DEFAULT = "cmd.exe" +) + +func supportedShellName(filename string) bool { + for _, subshell := range supportedShells { + if strings.EqualFold(filename, fmt.Sprintf("%s.exe", subshell.Shell())) { + return true + } + } + return false } diff --git a/internal/subshell/subshell_win_test.go b/internal/subshell/subshell_win_test.go index da2b2e4d11..b52a4db931 100644 --- a/internal/subshell/subshell_win_test.go +++ b/internal/subshell/subshell_win_test.go @@ -27,11 +27,12 @@ func setup(t *testing.T) { func TestBash(t *testing.T) { setup(t) - os.Setenv("SHELL", `C:\Program Files\bash.exe`) + shellPath := `C:\Program Files\Git\usr\bin\bash.exe` + os.Setenv("SHELL", shellPath) cfg, err := config.New() require.NoError(t, err) subs := New(cfg) - assert.Equal(t, `C:\Program Files\bash.exe`, subs.Binary()) + assert.Equal(t, shellPath, subs.Binary()) } @@ -39,11 +40,11 @@ func TestBashDontEscapeSpace(t *testing.T) { setup(t) // Reproduce bug in which paths are being incorrectly escaped on windows - os.Setenv("SHELL", `C:\Program\ Files\bash.exe`) + os.Setenv("SHELL", `C:\Program\ Files\Git\usr\bin\bash.exe`) cfg, err := config.New() require.NoError(t, err) subs := New(cfg) - assert.Equal(t, `C:\Program Files\bash.exe`, subs.Binary()) + assert.Equal(t, `C:\Program Files\Git\usr\bin\bash.exe`, subs.Binary()) } func TestRunCommandError(t *testing.T) { diff --git a/internal/subshell/zsh/zsh.go b/internal/subshell/zsh/zsh.go index e41f9f56aa..ccfa4f65a4 100644 --- a/internal/subshell/zsh/zsh.go +++ b/internal/subshell/zsh/zsh.go @@ -95,7 +95,6 @@ func (v *SubShell) WriteCompletionScript(completionScript string) error { } fpath := filepath.Join(dir, "_"+constants.CommandName) - logging.Debug("Writing to %s: %s", fpath, completionScript) err := fileutils.WriteFile(fpath, []byte(completionScript)) if err != nil { logging.Debug("Could not write completions script '%s', likely due to non-admin privileges", fpath) diff --git a/internal/svcctl/comm.go b/internal/svcctl/comm.go index f02938d153..0afff15001 100644 --- a/internal/svcctl/comm.go +++ b/internal/svcctl/comm.go @@ -18,9 +18,9 @@ import ( "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/rtutils/ptr" "github.com/ActiveState/cli/internal/runbits/panics" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/svcctl/svcmsg" - "github.com/ActiveState/cli/pkg/platform/runtime/executors/execmeta" - "github.com/ActiveState/cli/pkg/platform/runtime/target" + "github.com/ActiveState/cli/pkg/executors/execmeta" ) var ( @@ -112,7 +112,7 @@ func HeartbeatHandler(cfg *config.Instance, resolver Resolver, analyticsReporter } dims := &dimensions.Values{ - Trigger: ptr.To(target.TriggerExecutor.String()), + Trigger: ptr.To(trigger.TriggerExecutor.String()), Headless: ptr.To(strconv.FormatBool(metaData.Headless)), CommitID: ptr.To(metaData.CommitUUID), ProjectNameSpace: ptr.To(metaData.Namespace), diff --git a/internal/svcctl/error.go b/internal/svcctl/error.go index 025475dda2..4e1849429c 100644 --- a/internal/svcctl/error.go +++ b/internal/svcctl/error.go @@ -5,7 +5,6 @@ import ( "net" "os" - "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/ipc" ) @@ -31,7 +30,8 @@ func asTempNotUpCtlErr(err error) error { } func asNotUpCtlErr(err error) error { - if errs.Matches(err, &ipc.ServerDownError{}) { + var errServerDown *ipc.ServerDownError + if errors.As(err, &errServerDown) { return ctlErrNotUp } return err diff --git a/internal/svcctl/svcctl.go b/internal/svcctl/svcctl.go index 91e0e8d236..58933826f9 100644 --- a/internal/svcctl/svcctl.go +++ b/internal/svcctl/svcctl.go @@ -70,7 +70,8 @@ func EnsureExecStartedAndLocateHTTP(ipComm IPCommunicator, exec, argText string, if err != nil { logging.Debug("Could not locate state-svc, attempting to start it..") - if !errs.Matches(err, &ipc.ServerDownError{}) { + var errServerDown *ipc.ServerDownError + if !errors.As(err, &errServerDown) { return "", errs.Wrap(err, "Cannot locate HTTP port of service") } @@ -137,7 +138,8 @@ func StopServer(ipComm IPCommunicator) error { defer cancel() err := stopAndWait(ctx, ipComm) - if err != nil && !errs.Matches(err, &ipc.ServerDownError{}) { + var errServerDown *ipc.ServerDownError + if err != nil && !errors.As(err, &errServerDown) { return errs.Wrap(err, "Cannot stop service") } diff --git a/internal/testhelpers/e2e/env.go b/internal/testhelpers/e2e/env.go index e006852354..38cb7cb14b 100644 --- a/internal/testhelpers/e2e/env.go +++ b/internal/testhelpers/e2e/env.go @@ -33,7 +33,6 @@ func sandboxedTestEnvironment(t *testing.T, dirs *Dirs, updatePath bool, extraEn env = append(env, []string{ constants.ConfigEnvVarName + "=" + dirs.Config, constants.CacheEnvVarName + "=" + dirs.Cache, - constants.DisableRuntime + "=true", constants.ActivatedStateEnvVarName + "=", constants.E2ETestEnvVarName + "=true", constants.DisableUpdates + "=true", diff --git a/internal/testhelpers/e2e/env_windows.go b/internal/testhelpers/e2e/env_windows.go index 0c7b72aeec..c91d1efe39 100644 --- a/internal/testhelpers/e2e/env_windows.go +++ b/internal/testhelpers/e2e/env_windows.go @@ -17,7 +17,7 @@ const ( ) func platformSpecificEnv(dirs *Dirs) []string { - return []string{ + env := []string{ "SystemDrive=C:", "SystemRoot=C:\\Windows", "PROGRAMFILES=C:\\Program Files", @@ -39,6 +39,12 @@ func platformSpecificEnv(dirs *Dirs) []string { fmt.Sprintf("LOCALAPPDATA=%s", dirs.TempDir), fmt.Sprintf("%s=true", constants.DisableActivateEventsEnvVarName), } + + if condition.OnCI() { + env = append(env, fmt.Sprintf("%s=cmd.exe", constants.OverrideShellEnvVarName)) + } + + return env } func platformPath() string { diff --git a/internal/testhelpers/e2e/session.go b/internal/testhelpers/e2e/session.go index 53eeccb889..9655aae58f 100644 --- a/internal/testhelpers/e2e/session.go +++ b/internal/testhelpers/e2e/session.go @@ -7,21 +7,11 @@ import ( "path/filepath" "regexp" "runtime" + "slices" "strings" "testing" "time" - "github.com/ActiveState/termtest" - "github.com/go-openapi/strfmt" - "github.com/google/uuid" - "github.com/phayes/permbits" - "github.com/stretchr/testify/require" - - "github.com/ActiveState/cli/internal/subshell" - "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/projectfile" - "github.com/ActiveState/cli/internal/condition" "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" @@ -34,6 +24,7 @@ import ( "github.com/ActiveState/cli/internal/osutils/stacktrace" "github.com/ActiveState/cli/internal/rtutils/singlethread" "github.com/ActiveState/cli/internal/strutils" + "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/subshell/bash" "github.com/ActiveState/cli/internal/subshell/sscommon" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -42,7 +33,21 @@ import ( "github.com/ActiveState/cli/pkg/platform/api/mono/mono_client/users" "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" "github.com/ActiveState/cli/pkg/platform/authentication" + "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/platform/model/buildplanner" "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/cli/pkg/projectfile" + "github.com/ActiveState/termtest" + "github.com/go-openapi/strfmt" + "github.com/google/uuid" + "github.com/phayes/permbits" + "github.com/stretchr/testify/require" +) + +var ( + RuntimeSolvingTimeoutOpt = termtest.OptExpectTimeout(90 * time.Second) + RuntimeSourcingTimeoutOpt = termtest.OptExpectTimeout(3 * time.Minute) + RuntimeBuildSourcingTimeoutOpt = termtest.OptExpectTimeout(RuntimeBuildSourcingTimeout) ) // Session represents an end-to-end testing session during which several console process can be spawned and tested @@ -63,6 +68,18 @@ type Session struct { ExecutorExe string spawned []*SpawnedCmd ignoreLogErrors bool + cache keyCache +} + +type keyCache map[string]string + +func (k keyCache) GetCache(key string) (string, error) { + return k[key], nil +} + +func (k keyCache) SetCache(key, value string, _ time.Duration) error { + k[key] = value + return nil } var ( @@ -173,7 +190,7 @@ func new(t *testing.T, retainDirs, updatePath bool, extraEnv ...string) *Session require.NoError(t, err) env := sandboxedTestEnvironment(t, dirs, updatePath, extraEnv...) - session := &Session{Dirs: dirs, Env: env, retainDirs: retainDirs, T: t} + session := &Session{Dirs: dirs, Env: env, retainDirs: retainDirs, T: t, cache: keyCache{}} // Mock installation directory exe, svcExe, execExe := executablePaths(t) @@ -184,7 +201,7 @@ func new(t *testing.T, retainDirs, updatePath bool, extraEnv ...string) *Session err = fileutils.Touch(filepath.Join(dirs.Base, installation.InstallDirMarker)) require.NoError(session.T, err) - cfg, err := config.New() + cfg, err := config.NewCustom(dirs.Config, singlethread.New(), true) require.NoError(session.T, err) if err := cfg.Set(constants.SecurityPromptConfig, false); err != nil { @@ -211,6 +228,26 @@ func (s *Session) Spawn(args ...string) *SpawnedCmd { return s.SpawnCmdWithOpts(s.Exe, OptArgs(args...)) } +// SpawnDebuggerWithOpts will spawn a state tool command with the dlv debugger in remote debugging port. +// It uses the default dlv port of `2345`. It has been tested in Goland (intellij), see instructions here: +// https://www.jetbrains.com/help/go/attach-to-running-go-processes-with-debugger.html#step-3-create-the-remote-run-debug-configuration-on-the-client-computer +// Note remote debugging seems a bit unreliable. I've found it works best to start the test code first, and once it is +// running then start the remote debugger. When I launch the remote debugger first it often doesn't take. But even +// when using this trickery it may at times not work; try restarting goland, your machine, or dlv. +func (s *Session) SpawnDebuggerWithOpts(opts ...SpawnOptSetter) *SpawnedCmd { + spawnOpts := s.newSpawnOpts(opts...) + args := slices.Clone(spawnOpts.Args) + + workDir := spawnOpts.Dir + spawnOpts.Args = []string{"debug", "--wd", workDir, "--headless", "--listen=:2345", "--api-version=2", "github.com/ActiveState/cli/cmd/state", "--"} + spawnOpts.Args = append(spawnOpts.Args, args...) + spawnOpts.Dir = environment.GetRootPathUnsafe() + + return s.SpawnCmdWithOpts("dlv", func(opts *SpawnOpts) { + *opts = spawnOpts + }) +} + // SpawnWithOpts spawns the state tool executable to be tested with arguments func (s *Session) SpawnWithOpts(opts ...SpawnOptSetter) *SpawnedCmd { return s.SpawnCmdWithOpts(s.Exe, opts...) @@ -233,33 +270,7 @@ func (s *Session) SpawnShellWithOpts(shell Shell, opts ...SpawnOptSetter) *Spawn // SpawnCmdWithOpts executes an executable in a pseudo-terminal for integration tests // Arguments and other parameters can be specified by specifying SpawnOptSetter func (s *Session) SpawnCmdWithOpts(exe string, optSetters ...SpawnOptSetter) *SpawnedCmd { - spawnOpts := NewSpawnOpts() - spawnOpts.Env = s.Env - spawnOpts.Dir = s.Dirs.Work - - spawnOpts.TermtestOpts = append(spawnOpts.TermtestOpts, - termtest.OptErrorHandler(func(tt *termtest.TermTest, err error) error { - s.T.Fatal(s.DebugMessage(errs.JoinMessage(err))) - return err - }), - termtest.OptDefaultTimeout(defaultTimeout), - termtest.OptCols(140), - termtest.OptRows(30), // Needs to be able to accommodate most JSON output - ) - - // TTYs output newlines in two steps: '\r' (CR) to move the caret to the beginning of the line, - // and '\n' (LF) to move the caret one line down. Terminal emulators do the same thing, so the - // raw terminal output will contain "\r\n". Since our multi-line expectation messages often use - // '\n', normalize line endings to that for convenience, regardless of platform ('\n' for Linux - // and macOS, "\r\n" for Windows). - // More info: https://superuser.com/a/1774370 - spawnOpts.TermtestOpts = append(spawnOpts.TermtestOpts, - termtest.OptNormalizedLineEnds(true), - ) - - for _, optSet := range optSetters { - optSet(&spawnOpts) - } + spawnOpts := s.newSpawnOpts(optSetters...) var shell string var args []string @@ -321,12 +332,48 @@ func (s *Session) SpawnCmdWithOpts(exe string, optSetters ...SpawnOptSetter) *Sp return spawn } +func (s *Session) newSpawnOpts(optSetters ...SpawnOptSetter) SpawnOpts { + spawnOpts := NewSpawnOpts() + spawnOpts.Env = s.Env + spawnOpts.Dir = s.Dirs.Work + + spawnOpts.TermtestOpts = append(spawnOpts.TermtestOpts, + termtest.OptErrorHandler(func(tt *termtest.TermTest, err error) error { + s.T.Fatal(s.DebugMessage(errs.JoinMessage(err))) + return err + }), + termtest.OptDefaultTimeout(defaultTimeout), + termtest.OptCols(140), + termtest.OptRows(30), // Needs to be able to accommodate most JSON output + ) + + // TTYs output newlines in two steps: '\r' (CR) to move the caret to the beginning of the line, + // and '\n' (LF) to move the caret one line down. Terminal emulators do the same thing, so the + // raw terminal output will contain "\r\n". Since our multi-line expectation messages often use + // '\n', normalize line endings to that for convenience, regardless of platform ('\n' for Linux + // and macOS, "\r\n" for Windows). + // More info: https://superuser.com/a/1774370 + spawnOpts.TermtestOpts = append(spawnOpts.TermtestOpts, + termtest.OptNormalizedLineEnds(true), + ) + + for _, optSet := range optSetters { + optSet(&spawnOpts) + } + + return spawnOpts +} + // PrepareActiveStateYAML creates an activestate.yaml in the session's work directory from the // given YAML contents. func (s *Session) PrepareActiveStateYAML(contents string) { require.NoError(s.T, fileutils.WriteFile(filepath.Join(s.Dirs.Work, constants.ConfigFileName), []byte(contents))) } +func (s *Session) PrepareBuildScript(contents string) { + require.NoError(s.T, fileutils.WriteFile(filepath.Join(s.Dirs.Work, constants.BuildScriptFileName), []byte(contents))) +} + func (s *Session) PrepareCommitIdFile(commitID string) { pjfile, err := projectfile.Parse(filepath.Join(s.Dirs.Work, constants.ConfigFileName)) require.NoError(s.T, err) @@ -342,6 +389,13 @@ func (s *Session) CommitID() string { return pjfile.LegacyCommitID() } +// PrepareEmptyProject creates a checkout of the empty ActiveState-CLI/Empty project without using +// `state checkout`. +func (s *Session) PrepareEmptyProject() { + s.PrepareActiveStateYAML(fmt.Sprintf("project: https://%s/%s", constants.DefaultAPIHost, "ActiveState-CLI/Empty")) + s.PrepareCommitIdFile("6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") +} + // PrepareProject creates a very simple activestate.yaml file for the given org/project and, if a // commit ID is given, an .activestate/commit file. func (s *Session) PrepareProject(namespace, commitID string) { @@ -353,7 +407,7 @@ func (s *Session) PrepareProject(namespace, commitID string) { func (s *Session) PrepareProjectAndBuildScript(namespace, commitID string) { s.PrepareProject(namespace, commitID) - bp := buildplanner.NewBuildPlannerModel(nil) + bp := buildplanner.NewBuildPlannerModel(nil, s.cache) script, err := bp.GetBuildScript(commitID) require.NoError(s.T, err) b, err := script.Marshal() @@ -454,6 +508,7 @@ func (s *Session) DeleteUUIDProjects(org string) { func (s *Session) DebugMessage(prefix string) string { var sectionStart, sectionEnd string sectionStart = "\n=== " + sectionEnd = "\n/==\n" if os.Getenv("GITHUB_ACTIONS") == "true" { sectionStart = "##[group]" sectionEnd = "##[endgroup]" @@ -463,27 +518,36 @@ func (s *Session) DebugMessage(prefix string) string { prefix = prefix + "\n" } - output := map[string]string{} + output := []string{} for _, spawn := range s.spawned { name := spawn.Cmd().String() if spawn.opts.HideCmdArgs { name = spawn.Cmd().Path } - output[name] = strings.TrimSpace(spawn.Snapshot()) + out := spawn.Output() + if strings.Contains(out, "panic") || strings.Contains(out, "goroutine") { + // If we encountered a panic it's unlikely the snapshot has enough information to be useful, so in this + // case we include the full output. Which we don't normally do as it is just the dump of pty data, and + // tends to be overly verbose and difficult to grok. + output = append(output, fmt.Sprintf("Snapshot for Cmd '%s':\n%s", name, strings.TrimSpace(out))) + } else { + output = append(output, fmt.Sprintf("Snapshot for Cmd '%s':\n%s", name, strings.TrimSpace(spawn.Snapshot()))) + } + } + + logs := []string{} + for name, log := range s.DebugLogs() { + logs = append(logs, fmt.Sprintf("Log for '%s':\n%s", name, log)) } v, err := strutils.ParseTemplate(` {{.Prefix}}Stack: {{.Stacktrace}} -{{range $title, $value := .Outputs}} -{{$.A}}Snapshot for Cmd '{{$title}}': -{{$value}} -{{$.Z}} +{{range $value := .Outputs}} +{{$.A}}{{$value}}{{$.Z}} {{end}} -{{range $title, $value := .Logs}} -{{$.A}}Log '{{$title}}': -{{$value}} -{{$.Z}} +{{range $value := .Logs}} +{{$.A}}{{$value}}{{$.Z}} {{else}} No logs {{end}} @@ -491,7 +555,7 @@ No logs "Prefix": prefix, "Stacktrace": stacktrace.Get().String(), "Outputs": output, - "Logs": s.DebugLogs(), + "Logs": logs, "A": sectionStart, "Z": sectionEnd, }, nil) @@ -667,6 +731,13 @@ func (s *Session) LogFiles() []string { fmt.Printf("Error walking log dir: %v", err) } + // Sort by filename timestamp (filenames are `[executable]-[processid]-[timestamp].log`) + slices.SortFunc(result, func(a, b string) int { + aa := strings.Split(a, "-") + bb := strings.Split(b, "-") + return strings.Compare(bb[len(bb)-1], aa[len(aa)-1]) + }) + return result } @@ -728,8 +799,8 @@ func (s *Session) detectLogErrors() { continue } if contents := string(fileutils.ReadFileUnsafe(path)); errorOrPanicRegex.MatchString(contents) { - s.T.Errorf("%sFound error and/or panic in log file %s\nIf this was expected, call session.IgnoreLogErrors() to avoid this check\nLog contents:\n%s%s", - sectionStart, path, contents, sectionEnd) + s.T.Errorf(s.DebugMessage(fmt.Sprintf("%sFound error and/or panic in log file %s\nIf this was expected, call session.IgnoreLogErrors() to avoid this check\nLog contents:\n%s%s", + sectionStart, path, contents, sectionEnd))) } } } diff --git a/internal/testhelpers/e2e/session_unix.go b/internal/testhelpers/e2e/session_unix.go index 970a8fbec0..c9f594ded2 100644 --- a/internal/testhelpers/e2e/session_unix.go +++ b/internal/testhelpers/e2e/session_unix.go @@ -3,13 +3,6 @@ package e2e -import ( - "time" +import "time" - "github.com/ActiveState/termtest" -) - -var ( - RuntimeSourcingTimeoutOpt = termtest.OptExpectTimeout(3 * time.Minute) - RuntimeBuildSourcingTimeoutOpt = termtest.OptExpectTimeout(6 * time.Minute) -) +const RuntimeBuildSourcingTimeout = 6 * time.Minute diff --git a/internal/testhelpers/e2e/session_windows.go b/internal/testhelpers/e2e/session_windows.go index 6c1830eadd..4c6d8fbf62 100644 --- a/internal/testhelpers/e2e/session_windows.go +++ b/internal/testhelpers/e2e/session_windows.go @@ -1,15 +1,6 @@ -//go:build windows -// +build windows - package e2e -import ( - "time" - - "github.com/ActiveState/termtest" -) +import "time" -var ( - RuntimeSourcingTimeoutOpt = termtest.OptExpectTimeout(3 * time.Minute) - RuntimeBuildSourcingTimeoutOpt = termtest.OptExpectTimeout(6 * time.Minute) -) +// RuntimeBuildSourcingTimeout uses a higher timeout on Windows cause Windows +const RuntimeBuildSourcingTimeout = 12 * time.Minute diff --git a/internal/testhelpers/e2e/spawn.go b/internal/testhelpers/e2e/spawn.go index 33aff86cef..fff1cd25b8 100644 --- a/internal/testhelpers/e2e/spawn.go +++ b/internal/testhelpers/e2e/spawn.go @@ -73,8 +73,13 @@ func (s *SpawnedCmd) ExpectInput(opts ...termtest.SetExpectOpt) error { send := `echo $'expect\'input from posix shell'` expect := `expect'input from posix shell` if cmdName != "bash" && shellName != "bash" && runtime.GOOS == "windows" { - send = `echo ^` - expect = `` + if strings.Contains(cmdName, "powershell") || strings.Contains(shellName, "powershell") { + send = "echo \"\"" + expect = `` + } else { + send = `echo ^` + expect = `` + } } // Termtest internal functions already implement error handling diff --git a/internal/testhelpers/tagsuite/tagsuite.go b/internal/testhelpers/tagsuite/tagsuite.go index cbaa75737a..3066469670 100644 --- a/internal/testhelpers/tagsuite/tagsuite.go +++ b/internal/testhelpers/tagsuite/tagsuite.go @@ -32,6 +32,7 @@ const ( DeleteProjects = "delete-uuid-projects" Deploy = "deploy" Edit = "edit" + Environment = "environment" Errors = "error" Events = "events" Exec = "exec" @@ -80,6 +81,7 @@ const ( Show = "show" Switch = "switch" Uninstall = "uninstall" + Upgrade = "upgrade" Update = "update" Use = "use" ) diff --git a/internal/unarchiver/unarchiver.go b/internal/unarchiver/unarchiver.go index 29726eee88..b90019c1f5 100644 --- a/internal/unarchiver/unarchiver.go +++ b/internal/unarchiver/unarchiver.go @@ -9,6 +9,7 @@ import ( "path/filepath" "runtime" + "github.com/ActiveState/cli/internal/errs" "github.com/mholt/archiver/v3" "github.com/ActiveState/cli/internal/fileutils" @@ -101,10 +102,10 @@ func (ua *Unarchiver) Unarchive(archiveStream io.Reader, archiveSize int64, dest break } if err != nil { - return + return errs.Wrap(err, "error extracting next file") } - //logging.Debug("Extracted %s File size: %d", f.Name(), f.Size()) + // logging.Debug("Extracted %s File size: %d", f.Name(), f.Size()) ua.notifier(f.Name(), f.Size(), f.IsDir()) } diff --git a/internal/updater/updater.go b/internal/updater/updater.go index c8ad964e00..bd2a661cb0 100644 --- a/internal/updater/updater.go +++ b/internal/updater/updater.go @@ -187,10 +187,13 @@ func (u *UpdateInstaller) InstallBlocking(installTargetPath string, args ...stri if rerr == nil { return } + + var errInProgress *ErrorInProgress + switch { case os.IsPermission(rerr): u.analyticsEvent(anaConst.ActUpdateInstall, anaConst.UpdateLabelFailed, "Could not update the state tool due to insufficient permissions.") - case errs.Matches(rerr, &ErrorInProgress{}): + case errors.As(rerr, &errInProgress): u.analyticsEvent(anaConst.ActUpdateInstall, anaConst.UpdateLabelFailed, anaConst.UpdateErrorInProgress) default: u.analyticsEvent(anaConst.ActUpdateInstall, anaConst.UpdateLabelFailed, anaConst.UpdateErrorInstallFailed) diff --git a/internal/virtualenvironment/virtualenvironment.go b/internal/virtualenvironment/virtualenvironment.go index e9e8cc2b2e..182f2c415f 100644 --- a/internal/virtualenvironment/virtualenvironment.go +++ b/internal/virtualenvironment/virtualenvironment.go @@ -6,10 +6,11 @@ import ( "github.com/google/uuid" + "github.com/ActiveState/cli/pkg/runtime" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/osutils" - "github.com/ActiveState/cli/pkg/platform/runtime" "github.com/ActiveState/cli/pkg/project" ) @@ -31,12 +32,12 @@ func (v *VirtualEnvironment) GetEnv(inherit bool, useExecutors bool, projectDir, envMap := make(map[string]string) // Source runtime environment information - if !v.runtime.Disabled() { - var err error - envMap, err = v.runtime.Env(inherit, useExecutors) - if err != nil { - return envMap, err - } + + env := v.runtime.Env(inherit) + if useExecutors { + envMap = env.VariablesWithExecutors + } else { + envMap = env.Variables } if projectDir != "" { @@ -59,10 +60,6 @@ func (v *VirtualEnvironment) GetEnv(inherit bool, useExecutors bool, projectDir, } } - if inherit { - envMap = osutils.InheritEnv(envMap) - } - return envMap, nil } diff --git a/pkg/buildplan/artifact.go b/pkg/buildplan/artifact.go index a1f832987a..6c79425742 100644 --- a/pkg/buildplan/artifact.go +++ b/pkg/buildplan/artifact.go @@ -4,7 +4,6 @@ import ( "reflect" "sort" - "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/sliceutils" "github.com/ActiveState/cli/pkg/buildplan/raw" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" @@ -27,8 +26,8 @@ type Artifact struct { Ingredients []*Ingredient `json:"-"` // While most artifacts only have a single ingredient, some artifacts such as installers can have multiple. - isRuntimeDependency bool - isBuildtimeDependency bool + IsRuntimeDependency bool + IsBuildtimeDependency bool platforms []strfmt.UUID children []ArtifactRelation @@ -52,7 +51,6 @@ func (a *Artifact) Name() string { if len(a.Ingredients) == 1 { return a.Ingredients[0].Name } - logging.Debug("Using displayname because artifact has %d ingredients", len(a.Ingredients)) return a.DisplayName } @@ -65,6 +63,26 @@ func (a *Artifact) Version() string { return "" } +// Revision returns the name of the ingredient for this artifact, if it only has exactly one ingredient associated. +// Otherwise it returns an empty version. +func (a *Artifact) Revision() int { + if len(a.Ingredients) == 1 { + return a.Ingredients[0].Revision + } + return -1 +} + +func (a *Artifact) Licenses() []string { + result := []string{} + if len(a.Ingredients) == 0 { + return result + } + for _, ing := range a.Ingredients { + result = append(result, ing.Licenses...) + } + return result +} + func (a *Artifact) NameAndVersion() string { version := a.Version() if version == "" { @@ -126,34 +144,65 @@ func (a Artifacts) ToIDSlice() []strfmt.UUID { func (a Artifacts) ToNameMap() ArtifactNameMap { result := make(map[string]*Artifact, len(a)) for _, a := range a { - name := a.DisplayName - if len(a.Ingredients) == 0 { - name = a.Ingredients[0].Name - } - result[name] = a + result[a.Name()] = a } return result } -type ArtifactChangeset struct { - Added []*Artifact - Removed []*Artifact - Updated []ArtifactUpdate +type ChangeType int + +const ( + ArtifactAdded ChangeType = iota + ArtifactRemoved + ArtifactUpdated +) + +func (c ChangeType) String() string { + switch c { + case ArtifactAdded: + return "added" + case ArtifactRemoved: + return "removed" + case ArtifactUpdated: + return "updated" + } + + return "unknown" } -type ArtifactUpdate struct { - From *Artifact - To *Artifact +type ArtifactChange struct { + ChangeType ChangeType + Artifact *Artifact + Old *Artifact // Old is only set when ChangeType=ArtifactUpdated } -func (a ArtifactUpdate) VersionsChanged() bool { +type ArtifactChangeset []ArtifactChange + +func (a ArtifactChangeset) Filter(t ...ChangeType) ArtifactChangeset { + lookup := make(map[ChangeType]struct{}, len(t)) + for _, t := range t { + lookup[t] = struct{}{} + } + result := ArtifactChangeset{} + for _, ac := range a { + if _, ok := lookup[ac.ChangeType]; ok { + result = append(result, ac) + } + } + return result +} + +func (a ArtifactChange) VersionsChanged() bool { + if a.Old == nil { + return false + } fromVersions := []string{} - for _, ing := range a.From.Ingredients { + for _, ing := range a.Old.Ingredients { fromVersions = append(fromVersions, ing.Version) } sort.Strings(fromVersions) toVersions := []string{} - for _, ing := range a.To.Ingredients { + for _, ing := range a.Artifact.Ingredients { toVersions = append(toVersions, ing.Version) } sort.Strings(toVersions) @@ -161,35 +210,66 @@ func (a ArtifactUpdate) VersionsChanged() bool { return !reflect.DeepEqual(fromVersions, toVersions) } -func (as Artifacts) RuntimeDependencies(recursive bool) Artifacts { - seen := make(map[strfmt.UUID]struct{}) +func (as Artifacts) RuntimeDependencies(recursive bool, ignore *map[strfmt.UUID]struct{}) Artifacts { dependencies := Artifacts{} for _, a := range as { - dependencies = append(dependencies, a.runtimeDependencies(recursive, seen)...) + dependencies = append(dependencies, a.dependencies(recursive, ignore, RuntimeRelation)...) } return dependencies } -func (a *Artifact) RuntimeDependencies(recursive bool) Artifacts { - return a.runtimeDependencies(recursive, make(map[strfmt.UUID]struct{})) +func (a *Artifact) RuntimeDependencies(recursive bool, ignore *map[strfmt.UUID]struct{}) Artifacts { + return a.dependencies(recursive, ignore, RuntimeRelation) } -func (a *Artifact) runtimeDependencies(recursive bool, seen map[strfmt.UUID]struct{}) Artifacts { +// Dependencies returns ALL dependencies that an artifact has, this covers runtime and build time dependencies. +// It does not cover test dependencies as we have no use for them in the state tool. +func (as Artifacts) Dependencies(recursive bool, ignore *map[strfmt.UUID]struct{}) Artifacts { + dependencies := Artifacts{} + for _, a := range as { + dependencies = append(dependencies, a.dependencies(recursive, ignore, RuntimeRelation, BuildtimeRelation)...) + } + return dependencies +} + +// Dependencies returns ALL dependencies that an artifact has, this covers runtime and build time dependencies. +// It does not cover test dependencies as we have no use for them in the state tool. +func (a *Artifact) Dependencies(recursive bool, ignore *map[strfmt.UUID]struct{}) Artifacts { + as := a.dependencies(recursive, ignore, RuntimeRelation, BuildtimeRelation) + as = sliceutils.UniqueByProperty(as, func(a *Artifact) any { return a.ArtifactID }) + return as +} + +func (a *Artifact) dependencies(recursive bool, maybeIgnore *map[strfmt.UUID]struct{}, relations ...Relation) Artifacts { + ignore := map[strfmt.UUID]struct{}{} + if maybeIgnore != nil { + ignore = *maybeIgnore + } + // Guard against recursion, this shouldn't really be possible but we don't know how the buildplan might evolve // so better safe than sorry. - if _, ok := seen[a.ArtifactID]; ok { + if _, ok := ignore[a.ArtifactID]; ok { return Artifacts{} } - seen[a.ArtifactID] = struct{}{} + ignore[a.ArtifactID] = struct{}{} dependencies := Artifacts{} for _, ac := range a.children { - if ac.Relation != RuntimeRelation { + related := len(relations) == 0 + for _, relation := range relations { + if ac.Relation == relation { + related = true + } + } + if !related { continue } - dependencies = append(dependencies, ac.Artifact) - if recursive { - dependencies = append(dependencies, ac.Artifact.RuntimeDependencies(recursive)...) + + if _, ok := ignore[ac.Artifact.ArtifactID]; !ok { + dependencies = append(dependencies, ac.Artifact) + if recursive { + dependencies = append(dependencies, ac.Artifact.dependencies(recursive, &ignore, relations...)...) + } } } return dependencies diff --git a/pkg/buildplan/artifact_test.go b/pkg/buildplan/artifact_test.go new file mode 100644 index 0000000000..88ba3d707f --- /dev/null +++ b/pkg/buildplan/artifact_test.go @@ -0,0 +1,74 @@ +package buildplan + +import ( + "reflect" + "testing" +) + +func TestArtifact_Dependencies(t *testing.T) { + tests := []struct { + name string + artifact *Artifact + recursive bool + want []string // Artifact IDs + }{ + { + name: "Artifact with runtime dependencies", + artifact: createMockArtifactWithRuntimeDeps(), + recursive: true, + want: []string{ + "00000000-0000-0000-0000-000000000002", + "00000000-0000-0000-0000-000000000003", + "00000000-0000-0000-0000-000000000004", + }, + }, + { + name: "Artifact with runtime dependencies, non-recursive", + artifact: createMockArtifactWithRuntimeDeps(), + recursive: false, + want: []string{ + "00000000-0000-0000-0000-000000000002", + }, + }, + { + name: "Artifact with build time dependencies", + artifact: createMockArtifactWithBuildTimeDeps(), + recursive: true, + want: []string{ + "00000000-0000-0000-0000-000000000002", + "00000000-0000-0000-0000-000000000003", + }, + }, + { + name: "Artifact with build time dependencies, non-recursive", + artifact: createMockArtifactWithBuildTimeDeps(), + recursive: false, + want: []string{ + "00000000-0000-0000-0000-000000000002", + }, + }, + { + name: "Artifact with cycle", + artifact: createMockArtifactWithCycles(), + recursive: true, + want: []string{ + "00000000-0000-0000-0000-000000000002", + "00000000-0000-0000-0000-000000000003", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := tt.artifact + deps := a.Dependencies(tt.recursive, nil) + got := make([]string, len(deps)) + for i, dep := range deps { + got[i] = dep.ArtifactID.String() + } + + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Artifact.Dependencies() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/buildplan/buildplan.go b/pkg/buildplan/buildplan.go index 4d38dd9f37..302d7df633 100644 --- a/pkg/buildplan/buildplan.go +++ b/pkg/buildplan/buildplan.go @@ -2,26 +2,26 @@ package buildplan import ( "encoding/json" + "sort" + + "github.com/go-openapi/strfmt" "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/sliceutils" "github.com/ActiveState/cli/pkg/buildplan/raw" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/go-openapi/strfmt" ) type BuildPlan struct { - platforms []strfmt.UUID - artifacts Artifacts - requirements Requirements - ingredients Ingredients - raw *raw.Build + legacyRecipeID strfmt.UUID // still used for buildlog streamer + platforms []strfmt.UUID + artifacts Artifacts + requirements Requirements + ingredients Ingredients + raw *raw.Build } func Unmarshal(data []byte) (*BuildPlan, error) { - logging.Debug("Unmarshalling buildplan") - b := &BuildPlan{} var rawBuild raw.Build @@ -31,29 +31,29 @@ func Unmarshal(data []byte) (*BuildPlan, error) { b.raw = &rawBuild - b.cleanup() + b.sanitize() if err := b.hydrate(); err != nil { return nil, errs.Wrap(err, "error hydrating build plan") } - if len(b.artifacts) == 0 || len(b.ingredients) == 0 || len(b.platforms) == 0 { - return nil, errs.New("Buildplan unmarshalling failed as it got zero artifacts (%d), ingredients (%d) and or platforms (%d).", - len(b.artifacts), len(b.ingredients), len(b.platforms)) + if len(b.artifacts) == 0 || len(b.platforms) == 0 { + // Ingredients are not considered here because certain builds (eg. camel) won't be able to relate to a single ingredient + return nil, errs.New("Buildplan unmarshalling failed as it got zero artifacts (%d) and/or platforms (%d).", + len(b.artifacts), len(b.platforms)) } return b, nil } func (b *BuildPlan) Marshal() ([]byte, error) { - return json.Marshal(b.raw) + return json.MarshalIndent(b.raw, "", " ") } -// cleanup empty targets -// The type aliasing in the query populates the response with emtpy targets that we should remove -func (b *BuildPlan) cleanup() { - logging.Debug("Cleaning up build plan") - +// sanitize will remove empty targets and sort slices to ensure consistent interpretation of the same buildplan +// Empty targets: The type aliasing in the query populates the response with emtpy targets that we should remove +// Sorting: The API does not do any slice ordering, meaning the same buildplan retrieved twice can use different ordering +func (b *BuildPlan) sanitize() { b.raw.Steps = sliceutils.Filter(b.raw.Steps, func(s *raw.Step) bool { return s.StepID != "" }) @@ -65,6 +65,27 @@ func (b *BuildPlan) cleanup() { b.raw.Artifacts = sliceutils.Filter(b.raw.Artifacts, func(a *raw.Artifact) bool { return a.NodeID != "" }) + + sort.Slice(b.raw.Sources, func(i, j int) bool { return b.raw.Sources[i].NodeID < b.raw.Sources[j].NodeID }) + sort.Slice(b.raw.Steps, func(i, j int) bool { return b.raw.Steps[i].StepID < b.raw.Steps[j].StepID }) + sort.Slice(b.raw.Artifacts, func(i, j int) bool { return b.raw.Artifacts[i].NodeID < b.raw.Artifacts[j].NodeID }) + sort.Slice(b.raw.Terminals, func(i, j int) bool { return b.raw.Terminals[i].Tag < b.raw.Terminals[j].Tag }) + sort.Slice(b.raw.ResolvedRequirements, func(i, j int) bool { + return b.raw.ResolvedRequirements[i].Source < b.raw.ResolvedRequirements[j].Source + }) + for _, t := range b.raw.Terminals { + sort.Slice(t.NodeIDs, func(i, j int) bool { return t.NodeIDs[i] < t.NodeIDs[j] }) + } + for _, a := range b.raw.Artifacts { + sort.Slice(a.RuntimeDependencies, func(i, j int) bool { return a.RuntimeDependencies[i] < a.RuntimeDependencies[j] }) + } + for _, step := range b.raw.Steps { + sort.Slice(step.Inputs, func(i, j int) bool { return step.Inputs[i].Tag < step.Inputs[j].Tag }) + sort.Slice(step.Outputs, func(i, j int) bool { return step.Outputs[i] < step.Outputs[j] }) + for _, input := range step.Inputs { + sort.Slice(input.NodeIDs, func(i, j int) bool { return input.NodeIDs[i] < input.NodeIDs[j] }) + } + } } func (b *BuildPlan) Platforms() []strfmt.UUID { @@ -92,44 +113,51 @@ func (b *BuildPlan) DiffArtifacts(oldBp *BuildPlan, requestedOnly bool) Artifact if requestedOnly { new = b.RequestedArtifacts().ToNameMap() - old = oldBp.RequestedArtifacts().ToNameMap() + if oldBp != nil { + old = oldBp.RequestedArtifacts().ToNameMap() + } } else { new = b.Artifacts().ToNameMap() - old = oldBp.Artifacts().ToNameMap() + if oldBp != nil { + old = oldBp.Artifacts().ToNameMap() + } } - var updated []ArtifactUpdate - var added []*Artifact + changeset := ArtifactChangeset{} for name, artf := range new { if artfOld, notNew := old[name]; notNew { // The artifact name exists in both the old and new recipe, maybe it was updated though if artfOld.ArtifactID == artf.ArtifactID { continue } - updated = append(updated, ArtifactUpdate{ - From: artfOld, - To: artf, + changeset = append(changeset, ArtifactChange{ + ChangeType: ArtifactUpdated, + Artifact: artf, + Old: artfOld, }) } else { // If it's not an update it is a new artifact - added = append(added, artf) + changeset = append(changeset, ArtifactChange{ + ChangeType: ArtifactAdded, + Artifact: artf, + }) } } - var removed []*Artifact for name, artf := range old { if _, noDiff := new[name]; noDiff { continue } - removed = append(removed, artf) + changeset = append(changeset, ArtifactChange{ + ChangeType: ArtifactRemoved, + Artifact: artf, + }) } - return ArtifactChangeset{ - Added: added, - Removed: removed, - Updated: updated, - } + sort.SliceStable(changeset, func(i, j int) bool { return changeset[i].Artifact.Name() < changeset[j].Artifact.Name() }) + + return changeset } func (b *BuildPlan) Engine() types.BuildEngine { @@ -143,20 +171,13 @@ func (b *BuildPlan) Engine() types.BuildEngine { return buildEngine } -// RecipeID extracts the recipe ID from the BuildLogIDs. +// LegacyRecipeID extracts the recipe ID from the BuildLogIDs. // We do this because if the build is in progress we will need to reciepe ID to // initialize the build log streamer. // This information will only be populated if the build is an alternate build. // This is specified in the build planner queries. -func (b *BuildPlan) RecipeID() (strfmt.UUID, error) { - var result strfmt.UUID - for _, id := range b.raw.BuildLogIDs { - if result != "" && result.String() != id.ID { - return result, errs.New("Build plan contains multiple recipe IDs") - } - result = strfmt.UUID(id.ID) - } - return result, nil +func (b *BuildPlan) LegacyRecipeID() strfmt.UUID { + return b.legacyRecipeID } func (b *BuildPlan) IsBuildReady() bool { diff --git a/pkg/buildplan/filters.go b/pkg/buildplan/filters.go index 3e5af52197..7bf552ce34 100644 --- a/pkg/buildplan/filters.go +++ b/pkg/buildplan/filters.go @@ -22,13 +22,13 @@ func FilterPlatformArtifacts(platformID strfmt.UUID) FilterArtifact { func FilterBuildtimeArtifacts() FilterArtifact { return func(a *Artifact) bool { - return a.isBuildtimeDependency + return a.IsBuildtimeDependency } } func FilterRuntimeArtifacts() FilterArtifact { return func(a *Artifact) bool { - return a.isRuntimeDependency + return a.IsRuntimeDependency } } @@ -47,7 +47,7 @@ func FilterStateArtifacts() FilterArtifact { internalIngredients := sliceutils.Filter(a.Ingredients, func(i *Ingredient) bool { return i.Namespace == NamespaceInternal }) - if len(a.Ingredients) == len(internalIngredients) { + if len(a.Ingredients) > 0 && len(a.Ingredients) == len(internalIngredients) { return false } if strings.Contains(a.URL, "as-builds/noop") { @@ -59,9 +59,28 @@ func FilterStateArtifacts() FilterArtifact { func FilterSuccessfulArtifacts() FilterArtifact { return func(a *Artifact) bool { - return a.Status == types.ArtifactSucceeded || - a.Status == types.ArtifactBlocked || - a.Status == types.ArtifactStarted || - a.Status == types.ArtifactReady + return a.Status == types.ArtifactSucceeded } } + +func FilterFailedArtifacts() FilterArtifact { + return func(a *Artifact) bool { + return a.Status == types.ArtifactFailedTransiently || + a.Status == types.ArtifactFailedPermanently + } +} + +func FilterNotBuild() FilterArtifact { + return func(a *Artifact) bool { + return a.Status != types.ArtifactSucceeded + } +} + +type FilterOutIngredients struct { + Ingredients IngredientIDMap +} + +func (f FilterOutIngredients) Filter(i *Ingredient) bool { + _, blacklist := f.Ingredients[i.IngredientID] + return !blacklist +} diff --git a/pkg/buildplan/hydrate.go b/pkg/buildplan/hydrate.go index 9e8defac4d..05f84302b9 100644 --- a/pkg/buildplan/hydrate.go +++ b/pkg/buildplan/hydrate.go @@ -3,21 +3,19 @@ package buildplan import ( "strings" + "github.com/go-openapi/strfmt" + "github.com/ActiveState/cli/internal/condition" "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/rtutils/ptr" "github.com/ActiveState/cli/internal/sliceutils" "github.com/ActiveState/cli/pkg/buildplan/raw" - "github.com/go-openapi/strfmt" ) // hydrate will add additional information to the unmarshalled structures, based on the raw data that was unmarshalled. // For example, rather than having to walk the buildplan to find associations between artifacts and ingredients, this // will add this context straight on the relevant artifacts. func (b *BuildPlan) hydrate() error { - logging.Debug("Hydrating build plan") - artifactLookup := make(map[strfmt.UUID]*Artifact) ingredientLookup := make(map[strfmt.UUID]*Ingredient) @@ -57,7 +55,9 @@ func (b *BuildPlan) hydrate() error { } ingredient, ok := ingredientLookup[source.IngredientID] if !ok { - return errs.New("missing ingredient for source ID: %s", req.Source) + // It's possible that we haven't associated a source to an artifact if that source links to multiple artifacts. + // In this case we cannot determine which artifact relates to which source. + continue } b.requirements = append(b.requirements, &Requirement{ Requirement: req.Requirement, @@ -65,6 +65,15 @@ func (b *BuildPlan) hydrate() error { }) } + // Detect Recipe ID + var result strfmt.UUID + for _, id := range b.raw.BuildLogIDs { + if result != "" && result.String() != id.ID { + return errs.New("Build plan contains multiple recipe IDs") + } + b.legacyRecipeID = strfmt.UUID(id.ID) + } + if err := b.sanityCheck(); err != nil { return errs.Wrap(err, "sanity check failed") } @@ -73,7 +82,7 @@ func (b *BuildPlan) hydrate() error { } func (b *BuildPlan) hydrateWithBuildClosure(nodeIDs []strfmt.UUID, platformID *strfmt.UUID, artifactLookup map[strfmt.UUID]*Artifact) error { - err := b.raw.WalkViaSteps(nodeIDs, raw.TagDependency, func(node interface{}, parent *raw.Artifact) error { + err := b.raw.WalkViaSteps(nodeIDs, raw.WalkViaDeps, func(node interface{}, parent *raw.Artifact) error { switch v := node.(type) { case *raw.Artifact: // logging.Debug("Walking build closure artifact '%s (%s)'", v.DisplayName, v.NodeID) @@ -85,7 +94,7 @@ func (b *BuildPlan) hydrateWithBuildClosure(nodeIDs []strfmt.UUID, platformID *s } artifact.platforms = sliceutils.Unique(append(artifact.platforms, *platformID)) - artifact.isBuildtimeDependency = true + artifact.IsBuildtimeDependency = true if parent != nil { parentArtifact, ok := artifactLookup[parent.NodeID] @@ -101,7 +110,6 @@ func (b *BuildPlan) hydrateWithBuildClosure(nodeIDs []strfmt.UUID, platformID *s default: return errs.New("unexpected node type '%T': %#v", v, v) } - return nil }) if err != nil { return errs.Wrap(err, "error hydrating from build closure") @@ -131,13 +139,12 @@ func (b *BuildPlan) hydrateWithRuntimeClosure(nodeIDs []strfmt.UUID, platformID } artifact.platforms = sliceutils.Unique(append(artifact.platforms, *platformID)) - artifact.isRuntimeDependency = true + artifact.IsRuntimeDependency = true return nil default: return errs.New("unexpected node type '%T': %#v", v, v) } - return nil }) if err != nil { return errs.Wrap(err, "error hydrating from runtime closure") @@ -146,49 +153,44 @@ func (b *BuildPlan) hydrateWithRuntimeClosure(nodeIDs []strfmt.UUID, platformID } func (b *BuildPlan) hydrateWithIngredients(artifact *Artifact, platformID *strfmt.UUID, ingredientLookup map[strfmt.UUID]*Ingredient) error { - err := b.raw.WalkViaSteps([]strfmt.UUID{artifact.ArtifactID}, raw.TagSource, + err := b.raw.WalkViaSteps([]strfmt.UUID{artifact.ArtifactID}, raw.WalkViaSingleSource, func(node interface{}, parent *raw.Artifact) error { - switch v := node.(type) { - case *raw.Artifact: - return nil // We've already got our artifacts - case *raw.Source: - // logging.Debug("Walking source '%s (%s)'", v.Name, v.NodeID) - - // Ingredients aren't explicitly represented in buildplans. Technically all sources are ingredients - // but this may not always be true in the future. For our purposes we will initialize our own ingredients - // based on the source information, but we do not want to make the assumption in our logic that all - // sources are ingredients. - ingredient, ok := ingredientLookup[v.IngredientID] - if !ok { - ingredient = &Ingredient{ - IngredientSource: &v.IngredientSource, - platforms: []strfmt.UUID{}, - Artifacts: []*Artifact{}, - } - b.ingredients = append(b.ingredients, ingredient) - ingredientLookup[v.IngredientID] = ingredient - } + // logging.Debug("Walking source '%s (%s)'", v.Name, v.NodeID) + v, ok := node.(*raw.Source) + if !ok { + return nil // continue + } - // With multiple terminals it's possible we encounter the same combination multiple times. - // And an artifact usually only has one ingredient, so this is the cheapest lookup. - if !sliceutils.Contains(artifact.Ingredients, ingredient) { - artifact.Ingredients = append(artifact.Ingredients, ingredient) - ingredient.Artifacts = append(ingredient.Artifacts, artifact) - } - if platformID != nil { - ingredient.platforms = append(ingredient.platforms, *platformID) + // Ingredients aren't explicitly represented in buildplans. Technically all sources are ingredients + // but this may not always be true in the future. For our purposes we will initialize our own ingredients + // based on the source information, but we do not want to make the assumption in our logic that all + // sources are ingredients. + ingredient, ok := ingredientLookup[v.IngredientID] + if !ok { + ingredient = &Ingredient{ + IngredientSource: &v.IngredientSource, + platforms: []strfmt.UUID{}, + Artifacts: []*Artifact{}, } + b.ingredients = append(b.ingredients, ingredient) + ingredientLookup[v.IngredientID] = ingredient + } - if artifact.isBuildtimeDependency { - ingredient.IsBuildtimeDependency = true - } - if artifact.isRuntimeDependency { - ingredient.IsRuntimeDependency = true - } + // With multiple terminals it's possible we encounter the same combination multiple times. + // And an artifact usually only has one ingredient, so this is the cheapest lookup. + if !sliceutils.Contains(artifact.Ingredients, ingredient) { + artifact.Ingredients = append(artifact.Ingredients, ingredient) + ingredient.Artifacts = append(ingredient.Artifacts, artifact) + } + if platformID != nil { + ingredient.platforms = append(ingredient.platforms, *platformID) + } - return nil - default: - return errs.New("unexpected node type '%T': %#v", v, v) + if artifact.IsBuildtimeDependency { + ingredient.IsBuildtimeDependency = true + } + if artifact.IsRuntimeDependency { + ingredient.IsRuntimeDependency = true } return nil @@ -204,14 +206,6 @@ func (b *BuildPlan) hydrateWithIngredients(artifact *Artifact, platformID *strfm // If there are duplicates we're likely to see failures down the chain if live, though that's by no means guaranteed. // Surfacing it here will make it easier to reason about the failure. func (b *BuildPlan) sanityCheck() error { - // Ensure all artifacts have an associated ingredient - // If this fails either the API is bugged or the hydrate logic is bugged - for _, a := range b.Artifacts() { - if len(a.Ingredients) == 0 { - return errs.New("artifact '%s (%s)' does not have an ingredient", a.ArtifactID, a.DisplayName) - } - } - // The remainder of sanity checks aren't checking for error conditions so much as they are checking for smoking guns // If these fail then it's likely the API has changed in a backward incompatible way, or we broke something. // In any case it does not necessarily mean runtime sourcing is broken. diff --git a/pkg/buildplan/hydrate_test.go b/pkg/buildplan/hydrate_test.go new file mode 100644 index 0000000000..9ca9ba42bb --- /dev/null +++ b/pkg/buildplan/hydrate_test.go @@ -0,0 +1,63 @@ +package buildplan + +import ( + "testing" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/pkg/buildplan/mock" + "github.com/go-openapi/strfmt" + "github.com/stretchr/testify/require" +) + +func TestBuildPlan_hydrateWithIngredients(t *testing.T) { + tests := []struct { + name string + buildplan *BuildPlan + inputArtifact *Artifact + wantIngredient string + }{ + { + "Ingredient solves for simple artifact > src hop", + &BuildPlan{raw: mock.BuildWithInstallerDepsViaSrc}, + &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000007"}, + "00000000-0000-0000-0000-000000000009", + }, + { + "Installer should not resolve to an ingredient as it doesn't have a direct source", + &BuildPlan{raw: mock.BuildWithInstallerDepsViaSrc}, + &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000002"}, + "", + }, + { + "State artifact should resolve to source even when hopping through a python wheel", + &BuildPlan{raw: mock.BuildWithStateArtifactThroughPyWheel}, + &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000002"}, + "00000000-0000-0000-0000-000000000009", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := tt.buildplan + if err := b.hydrateWithIngredients(tt.inputArtifact, nil, map[strfmt.UUID]*Ingredient{}); err != nil { + t.Fatalf("hydrateWithIngredients() error = %v", errs.JoinMessage(err)) + } + + // Use string slice so testify doesn't just dump a bunch of pointer addresses on failure -.- + ingredients := []string{} + for _, i := range tt.inputArtifact.Ingredients { + ingredients = append(ingredients, i.IngredientID.String()) + } + if tt.wantIngredient == "" { + require.Empty(t, ingredients) + return + } + + if len(tt.inputArtifact.Ingredients) != 1 { + t.Fatalf("expected 1 ingredient resolution, got %d", len(tt.inputArtifact.Ingredients)) + } + if string(tt.inputArtifact.Ingredients[0].IngredientID) != tt.wantIngredient { + t.Errorf("expected ingredient ID %s, got %s", tt.wantIngredient, tt.inputArtifact.Ingredients[0].IngredientID) + } + }) + } +} diff --git a/pkg/buildplan/ingredient.go b/pkg/buildplan/ingredient.go index 16672f0fc8..e08a8e1dc4 100644 --- a/pkg/buildplan/ingredient.go +++ b/pkg/buildplan/ingredient.go @@ -11,7 +11,7 @@ type Ingredient struct { IsBuildtimeDependency bool IsRuntimeDependency bool - Artifacts []*Artifact + Artifacts Artifacts platforms []strfmt.UUID } @@ -58,6 +58,40 @@ func (i Ingredients) ToNameMap() IngredientNameMap { return result } +// CommonRuntimeDependencies returns the set of runtime dependencies that are common between all ingredients. +// For example, given a set of python ingredients this will return at the very least the python language ingredient. +func (i Ingredients) CommonRuntimeDependencies() Ingredients { + var is []ingredientsWithRuntimeDeps + for _, ig := range i { + is = append(is, ig) + } + return commonRuntimeDependencies(is) +} + +type ingredientsWithRuntimeDeps interface { + RuntimeDependencies(recursive bool) Ingredients +} + +func commonRuntimeDependencies(i []ingredientsWithRuntimeDeps) Ingredients { + counts := map[strfmt.UUID]int{} + common := Ingredients{} + + for _, ig := range i { + runtimeDeps := ig.RuntimeDependencies(true) + for _, rd := range runtimeDeps { + if _, ok := counts[rd.IngredientID]; !ok { + counts[rd.IngredientID] = 0 + } + counts[rd.IngredientID]++ + if counts[rd.IngredientID] == 2 { // only append on 2; we don't want dupes + common = append(common, rd) + } + } + } + + return common +} + func (i *Ingredient) RuntimeDependencies(recursive bool) Ingredients { dependencies := i.runtimeDependencies(recursive, make(map[strfmt.UUID]struct{})) return sliceutils.UniqueByProperty(dependencies, func(i *Ingredient) any { return i.IngredientID }) diff --git a/pkg/buildplan/ingredient_test.go b/pkg/buildplan/ingredient_test.go new file mode 100644 index 0000000000..85ca41de07 --- /dev/null +++ b/pkg/buildplan/ingredient_test.go @@ -0,0 +1,111 @@ +package buildplan + +import ( + "reflect" + "sort" + "testing" + + "github.com/ActiveState/cli/pkg/buildplan/raw" +) + +func TestIngredient_RuntimeDependencies(t *testing.T) { + tests := []struct { + name string + ingredient *Ingredient + recursive bool + want []string // Ingredient artifact IDs + }{ + { + name: "Ingredient with runtime dependencies", + ingredient: createIngredientWithRuntimeDeps(), + recursive: true, + want: []string{ + "00000000-0000-0000-0000-000000000020", + "00000000-0000-0000-0000-000000000030", + }, + }, + { + name: "Ingredient with runtime dependencies non recursive", + ingredient: createIngredientWithRuntimeDeps(), + recursive: false, + want: []string{ + "00000000-0000-0000-0000-000000000020", + }, + }, + { + name: "Ingredient with cycle", + ingredient: createMockIngredientWithCycles(), + recursive: true, + want: []string{ + "00000000-0000-0000-0000-000000000020", + "00000000-0000-0000-0000-000000000030", + "00000000-0000-0000-0000-000000000010", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i := tt.ingredient + deps := i.RuntimeDependencies(tt.recursive) + var got []string + for _, dep := range deps { + got = append(got, dep.IngredientID.String()) + } + + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Artifact.Dependencies() = %v, want %v", got, tt.want) + } + }) + } +} + +type mockIngredient struct { + deps Ingredients +} + +func (m mockIngredient) RuntimeDependencies(recursive bool) Ingredients { + return m.deps +} + +func TestIngredients_CommonRuntimeDependencies(t *testing.T) { + tests := []struct { + name string + i []ingredientsWithRuntimeDeps + want []string + }{ + { + "Simple", + []ingredientsWithRuntimeDeps{ + mockIngredient{ + deps: Ingredients{ + { + IngredientSource: &raw.IngredientSource{IngredientID: "sub-ingredient-1"}, + }, + }, + }, + mockIngredient{ + deps: Ingredients{ + { + IngredientSource: &raw.IngredientSource{IngredientID: "sub-ingredient-1"}, + }, + }, + }, + }, + []string{"sub-ingredient-1"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := commonRuntimeDependencies(tt.i) + gotIDs := []string{} + for _, i := range got { + gotIDs = append(gotIDs, string(i.IngredientID)) + } + sort.Strings(gotIDs) + sort.Strings(tt.want) + if !reflect.DeepEqual(gotIDs, tt.want) { + t.Errorf("Ingredients.CommonRuntimeDependencies() = %v, want %v", gotIDs, tt.want) + } + }) + } +} diff --git a/pkg/buildplan/mock/mock.go b/pkg/buildplan/mock/mock.go new file mode 100644 index 0000000000..ed575535ee --- /dev/null +++ b/pkg/buildplan/mock/mock.go @@ -0,0 +1,436 @@ +package mock + +import ( + "github.com/ActiveState/cli/pkg/buildplan/raw" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/go-openapi/strfmt" +) + +var BuildWithSourceFromStep = &raw.Build{ + Terminals: []*raw.NamedTarget{ + { + Tag: "platform:00000000-0000-0000-0000-000000000001", + // Step 1: Traversal starts here, this one points to an artifact + NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, + }, + }, + Steps: []*raw.Step{ + { + // Step 4: From here we can find which other nodes are linked to this one + StepID: "00000000-0000-0000-0000-000000000003", + Outputs: []string{"00000000-0000-0000-0000-000000000002"}, + Inputs: []*raw.NamedTarget{ + // Step 5: Now we know which nodes are responsible for producing the output + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000004"}}, + }, + }, + { + // Step 8: Same as step 4 + StepID: "00000000-0000-0000-0000-000000000005", + Outputs: []string{"00000000-0000-0000-0000-000000000004"}, + Inputs: []*raw.NamedTarget{ + // Step 9: Same as step 5 + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000006"}}, + }, + }, + }, + Artifacts: []*raw.Artifact{ + { + // Step 2: We got an artifact, but there may be more hiding behind this one + NodeID: "00000000-0000-0000-0000-000000000002", + DisplayName: "installer", + // Step 3: Now to traverse any other input nodes that generated this one, this goes to the step + GeneratedBy: "00000000-0000-0000-0000-000000000003", + }, + { + // Step 6: We have another artifact, but since this is an x-artifact we also want meta info (ingredient name, version) + NodeID: "00000000-0000-0000-0000-000000000004", + DisplayName: "pkgOne", + // Step 7: Same as step 3 + GeneratedBy: "00000000-0000-0000-0000-000000000005", + }, + }, + Sources: []*raw.Source{ + { + // Step 10: We have our ingredient + NodeID: "00000000-0000-0000-0000-000000000006", + }, + }, +} + +var BuildWithSourceFromGeneratedBy = &raw.Build{ + Terminals: []*raw.NamedTarget{ + { + Tag: "platform:00000000-0000-0000-0000-000000000001", + NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002", "00000000-0000-0000-0000-000000000004"}, + }, + }, + Artifacts: []*raw.Artifact{ + { + NodeID: "00000000-0000-0000-0000-000000000002", + DisplayName: "installer", + GeneratedBy: "00000000-0000-0000-0000-000000000004", + }, + { + NodeID: "00000000-0000-0000-0000-000000000003", + DisplayName: "installer", + GeneratedBy: "00000000-0000-0000-0000-000000000004", + }, + }, + Sources: []*raw.Source{ + { + NodeID: "00000000-0000-0000-0000-000000000004", + }, + }, +} + +var BuildWithBuildDeps = &raw.Build{ + Terminals: []*raw.NamedTarget{ + { + Tag: "platform:00000000-0000-0000-0000-000000000001", + NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, + }, + }, + Steps: []*raw.Step{ + { + StepID: "00000000-0000-0000-0000-000000000003", + Outputs: []string{"00000000-0000-0000-0000-000000000002"}, + Inputs: []*raw.NamedTarget{ + {Tag: "deps", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000004"}}, + }, + }, + }, + Artifacts: []*raw.Artifact{ + { + NodeID: "00000000-0000-0000-0000-000000000002", + DisplayName: "installer", + GeneratedBy: "00000000-0000-0000-0000-000000000003", + }, + { + NodeID: "00000000-0000-0000-0000-000000000004", + DisplayName: "pkgOne", + GeneratedBy: "00000000-0000-0000-0000-000000000006", + }, + }, + Sources: []*raw.Source{ + { + NodeID: "00000000-0000-0000-0000-000000000006", + }, + }, +} + +var BuildWithRuntimeDeps = &raw.Build{ + Terminals: []*raw.NamedTarget{ + { + Tag: "platform:00000000-0000-0000-0000-000000000001", + NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, + }, + }, + Artifacts: []*raw.Artifact{ + { + NodeID: "00000000-0000-0000-0000-000000000002", + DisplayName: "installer", + MimeType: types.XActiveStateArtifactMimeType, + RuntimeDependencies: []strfmt.UUID{ + "00000000-0000-0000-0000-000000000007", + }, + GeneratedBy: "00000000-0000-0000-0000-000000000003", + }, + { + NodeID: "00000000-0000-0000-0000-000000000007", + DisplayName: "pkgOne", + MimeType: types.XActiveStateArtifactMimeType, + GeneratedBy: "00000000-0000-0000-0000-000000000008", + }, + }, + Sources: []*raw.Source{ + { + NodeID: "00000000-0000-0000-0000-000000000006", + }, + { + NodeID: "00000000-0000-0000-0000-000000000009", + }, + }, +} + +// BuildWithInstallerDepsViaSrc is a build that includes an installer which has two artifacts as its dependencies. +var BuildWithInstallerDepsViaSrc = &raw.Build{ + Terminals: []*raw.NamedTarget{ + { + Tag: "platform:00000000-0000-0000-0000-000000000001", + NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, + }, + }, + Steps: []*raw.Step{ + { + StepID: "00000000-0000-0000-0000-000000000003", + Outputs: []string{"00000000-0000-0000-0000-000000000002"}, + Inputs: []*raw.NamedTarget{ + { + Tag: "src", NodeIDs: []strfmt.UUID{ + "00000000-0000-0000-0000-000000000007", + "00000000-0000-0000-0000-000000000010", + }, + }, + }, + }, + { + StepID: "00000000-0000-0000-0000-000000000008", + Outputs: []string{"00000000-0000-0000-0000-000000000007"}, + Inputs: []*raw.NamedTarget{ + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000009"}}, + }, + }, + { + StepID: "00000000-0000-0000-0000-000000000011", + Outputs: []string{"00000000-0000-0000-0000-000000000010"}, + Inputs: []*raw.NamedTarget{ + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000012"}}, + }, + }, + }, + Artifacts: []*raw.Artifact{ + { + NodeID: "00000000-0000-0000-0000-000000000002", + DisplayName: "installer", + MimeType: "application/unrecognized", + RuntimeDependencies: []strfmt.UUID{}, + GeneratedBy: "00000000-0000-0000-0000-000000000003", + }, + { + NodeID: "00000000-0000-0000-0000-000000000007", + DisplayName: "pkgOne", + MimeType: types.XActiveStateArtifactMimeType, + GeneratedBy: "00000000-0000-0000-0000-000000000008", + }, + { + NodeID: "00000000-0000-0000-0000-000000000010", + DisplayName: "pkgTwo", + MimeType: types.XActiveStateArtifactMimeType, + GeneratedBy: "00000000-0000-0000-0000-000000000011", + }, + }, + Sources: []*raw.Source{ + { + "00000000-0000-0000-0000-000000000009", + raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000009", + }, + }, + { + "00000000-0000-0000-0000-000000000012", + raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000012", + }, + }, + }, +} + +// BuildWithStateArtifactThroughPyWheel is a build with a state tool artifact that has a python wheel as its dependency +var BuildWithStateArtifactThroughPyWheel = &raw.Build{ + Terminals: []*raw.NamedTarget{ + { + Tag: "platform:00000000-0000-0000-0000-000000000001", + NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, + }, + }, + Steps: []*raw.Step{ + { + StepID: "00000000-0000-0000-0000-000000000003", + Outputs: []string{"00000000-0000-0000-0000-000000000002"}, + Inputs: []*raw.NamedTarget{ + { + Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000007"}, + }, + }, + }, + { + StepID: "00000000-0000-0000-0000-000000000008", + Outputs: []string{"00000000-0000-0000-0000-000000000007"}, + Inputs: []*raw.NamedTarget{ + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000009"}}, + }, + }, + }, + Artifacts: []*raw.Artifact{ + { + NodeID: "00000000-0000-0000-0000-000000000002", + DisplayName: "pkgStateArtifact", + GeneratedBy: "00000000-0000-0000-0000-000000000003", + }, + { + NodeID: "00000000-0000-0000-0000-000000000007", + DisplayName: "pkgPyWheel", + GeneratedBy: "00000000-0000-0000-0000-000000000008", + }, + }, + Sources: []*raw.Source{ + { + "00000000-0000-0000-0000-000000000009", + raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000009", + }, + }, + }, +} + +var BuildWithCommonRuntimeDepsViaSrc = &raw.Build{ + Terminals: []*raw.NamedTarget{ + { + Tag: "platform:00000000-0000-0000-0000-000000000001", + NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, + }, + }, + Steps: []*raw.Step{ + { + StepID: "00000000-0000-0000-0000-000000000008", + Outputs: []string{"00000000-0000-0000-0000-000000000007"}, + Inputs: []*raw.NamedTarget{ + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000009"}}, + }, + }, + { + StepID: "00000000-0000-0000-0000-0000000000011", + Outputs: []string{"00000000-0000-0000-0000-000000000010"}, + Inputs: []*raw.NamedTarget{ + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000013"}}, + }, + }, + { + StepID: "00000000-0000-0000-0000-0000000000101", + Outputs: []string{"00000000-0000-0000-0000-000000000100"}, + Inputs: []*raw.NamedTarget{ + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000103"}}, + }, + }, + }, + Artifacts: []*raw.Artifact{ + { + NodeID: "00000000-0000-0000-0000-000000000007", + DisplayName: "pkgOne", + MimeType: types.XActiveStateArtifactMimeType, + GeneratedBy: "00000000-0000-0000-0000-000000000008", + RuntimeDependencies: []strfmt.UUID{ + "00000000-0000-0000-0000-000000000100", + }, + }, + { + NodeID: "00000000-0000-0000-0000-000000000010", + DisplayName: "pkgTwo", + MimeType: types.XActiveStateArtifactMimeType, + GeneratedBy: "00000000-0000-0000-0000-0000000000011", + RuntimeDependencies: []strfmt.UUID{ + "00000000-0000-0000-0000-000000000100", + }, + }, + { + NodeID: "00000000-0000-0000-0000-000000000100", + DisplayName: "pkgThatsCommonDep", + MimeType: types.XActiveStateArtifactMimeType, + GeneratedBy: "00000000-0000-0000-0000-0000000000101", + }, + }, + Sources: []*raw.Source{ + { + "00000000-0000-0000-0000-000000000009", + raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000009", + }, + }, + { + "00000000-0000-0000-0000-000000000013", + raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000013", + }, + }, + { + "00000000-0000-0000-0000-000000000103", + raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000103", + }, + }, + }, +} + +// BuildWithRuntimeDepsViaSrcCycle is a build with a cycle in the runtime dependencies. +// The cycle is as follows: +// 00000000-0000-0000-0000-000000000002 (Terminal Artifact) +// +// -> 00000000-0000-0000-0000-000000000003 (Generated by Step) +// -> 00000000-0000-0000-0000-000000000007 (Step Input Artifact) +// -> 00000000-0000-0000-0000-000000000008 (Generated by Step) +// -> 00000000-0000-0000-0000-000000000010 (Step Input Artifact) +// -> 00000000-0000-0000-0000-000000000011 (Generated by Step) +// -> 00000000-0000-0000-0000-000000000013 (Step Input Artifact) +// -> 00000000-0000-0000-0000-000000000002 (Runtime dependency Artifact - Generates Cycle) +var BuildWithRuntimeDepsViaSrcCycle = &raw.Build{ + Terminals: []*raw.NamedTarget{ + { + Tag: "platform:00000000-0000-0000-0000-000000000001", + NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, + }, + }, + Steps: []*raw.Step{ + { + StepID: "00000000-0000-0000-0000-000000000003", + Outputs: []string{"00000000-0000-0000-0000-000000000002"}, + Inputs: []*raw.NamedTarget{ + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000007"}}, + }, + }, + { + StepID: "00000000-0000-0000-0000-000000000008", + Outputs: []string{"00000000-0000-0000-0000-000000000007"}, + Inputs: []*raw.NamedTarget{ + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000010"}}, + }, + }, + { + StepID: "00000000-0000-0000-0000-000000000011", + Outputs: []string{ + "00000000-0000-0000-0000-000000000010", + }, + Inputs: []*raw.NamedTarget{ + {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000013"}}, + }, + }, + }, + Artifacts: []*raw.Artifact{ + { + NodeID: "00000000-0000-0000-0000-000000000002", + DisplayName: "installer", + MimeType: "application/unrecognized", + GeneratedBy: "00000000-0000-0000-0000-000000000003", + }, + { + NodeID: "00000000-0000-0000-0000-000000000007", + DisplayName: "pkgOne", + MimeType: "application/unrecognized", + GeneratedBy: "00000000-0000-0000-0000-000000000008", + }, + { + NodeID: "00000000-0000-0000-0000-000000000010", + DisplayName: "pkgTwo", + MimeType: "application/unrecognized", + GeneratedBy: "00000000-0000-0000-0000-000000000011", + }, + { + NodeID: "00000000-0000-0000-0000-000000000013", + DisplayName: "pkgThree", + MimeType: types.XActiveStateArtifactMimeType, + RuntimeDependencies: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, // Generates a cycle back to the first artifact + GeneratedBy: "00000000-0000-0000-0000-000000000011", + }, + }, + Sources: []*raw.Source{ + { + NodeID: "00000000-0000-0000-0000-000000000006", + }, + { + NodeID: "00000000-0000-0000-0000-000000000009", + }, + { + NodeID: "00000000-0000-0000-0000-000000000012", + }, + }, +} diff --git a/pkg/buildplan/mock_test.go b/pkg/buildplan/mock_test.go new file mode 100644 index 0000000000..b4705dfc86 --- /dev/null +++ b/pkg/buildplan/mock_test.go @@ -0,0 +1,267 @@ +package buildplan + +import ( + "github.com/ActiveState/cli/pkg/buildplan/raw" +) + +// createMockArtifactWithCycles creates a mock artifact with a cycle. +// Unfortunately go doesn't support circular variable initialization, so we have to do it manually. +// Rather than have a highly nested structure, we'll create the artifacts and ingredients separately +// and then link them together in a function. +// +// The artifact cycle is: +// 00000000-0000-0000-0000-000000000001 +// +// -> 00000000-0000-0000-0000-000000000002 +// -> 00000000-0000-0000-0000-000000000003 +// -> 00000000-0000-0000-0000-000000000001 (Cycle back to the first artifact) +func createMockArtifactWithCycles() *Artifact { + // Create the artifacts with placeholders + artifact0001 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000001"} + artifact0002 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000002"} + artifact0003 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000003"} + + // Create the deepest ingredients and artifacts first + artifact0003.children = []ArtifactRelation{ + { + Artifact: artifact0001, // This creates an artifact cycle back to artifact0001 + Relation: RuntimeRelation, + }, + } + + artifact0002.children = []ArtifactRelation{ + { + Artifact: artifact0003, + Relation: RuntimeRelation, + }, + } + + artifact0001.children = []ArtifactRelation{ + { + Artifact: artifact0002, + Relation: RuntimeRelation, + }, + } + + return artifact0001 +} + +// createMockArtifactWithRuntimeDeps creates a mock artifact with runtime dependencies. +// The dependencies are: +// 00000000-0000-0000-0000-000000000001 +// +// -> 00000000-0000-0000-0000-000000000002 (child) +// -> 00000000-0000-0000-0000-000000000003 (child) +func createMockArtifactWithRuntimeDeps() *Artifact { + artifact0001 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000001"} + artifact0002 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000002"} + artifact0003 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000003"} + artifact0004 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000004"} + + artifact0001.children = []ArtifactRelation{ + { + Artifact: artifact0002, + Relation: RuntimeRelation, + }, + } + + artifact0002.children = []ArtifactRelation{ + { + Artifact: artifact0003, + Relation: RuntimeRelation, + }, + } + + artifact0003.children = []ArtifactRelation{ + { + Artifact: artifact0004, + Relation: RuntimeRelation, + }, + } + + return artifact0001 +} + +// createMockArtifactWithBuildTimeDeps creates a mock artifact with build time dependencies. +// The dependencies are: +// 00000000-0000-0000-0000-000000000001 +// +// -> 00000000-0000-0000-0000-000000000002 (child) +// -> 00000000-0000-0000-0000-000000000003 (child) +func createMockArtifactWithBuildTimeDeps() *Artifact { + artifact0001 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000001"} + artifact0002 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000002"} + artifact0003 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000003"} + + artifact0001.children = []ArtifactRelation{ + { + Artifact: artifact0002, + Relation: BuildtimeRelation, + }, + } + + artifact0002.children = []ArtifactRelation{ + { + Artifact: artifact0003, + Relation: BuildtimeRelation, + }, + } + + return artifact0001 +} + +// createIngredientWithRuntimeDeps creates a mock ingredient with runtime dependencies. +// The dependencies are: +// 00000000-0000-0000-0000-000000000010 (Ingredient0010) +// +// -> 00000000-0000-0000-0000-000000000001 (Artifact0001) +// -> 00000000-0000-0000-0000-000000000002 (Artifact child of Artifact0001) +// -> 00000000-0000-0000-0000-000000000020 (Ingredient0020) +// -> 00000000-0000-0000-0000-000000000003 (Artifact0003) +// -> 00000000-0000-0000-0000-000000000004 (Artifact child of Artifact0003) +// -> 00000000-0000-0000-0000-000000000030 (Ingredient0030) +func createIngredientWithRuntimeDeps() *Ingredient { + artifact0001 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000001"} + artifact0002 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000002"} + artifact0003 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000003"} + artifact0004 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000004"} + + ingredient0010 := &Ingredient{ + IngredientSource: &raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000010", + }, + Artifacts: []*Artifact{ + artifact0001, + }, + } + + ingredient0020 := &Ingredient{ + IngredientSource: &raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000020", + }, + Artifacts: []*Artifact{ + artifact0002, + }, + } + + ingredient0030 := &Ingredient{ + IngredientSource: &raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000030", + }, + Artifacts: []*Artifact{ + artifact0003, + }, + } + + artifact0001.children = []ArtifactRelation{ + { + Artifact: artifact0002, + Relation: RuntimeRelation, + }, + } + + artifact0002.children = []ArtifactRelation{ + { + Artifact: artifact0003, + Relation: RuntimeRelation, + }, + } + artifact0002.Ingredients = []*Ingredient{ingredient0020} + + artifact0003.children = []ArtifactRelation{ + { + Artifact: artifact0004, + Relation: RuntimeRelation, + }, + } + artifact0003.Ingredients = []*Ingredient{ingredient0030} + + return ingredient0010 +} + +// createMockIngredientWithCycles creates a mock ingredient with a cycle and avoids +// the circular variable initialization problem and the need for a highly nested structure. +// +// Ingredient are a bit more complex than artifacts as we first traverse the artifacts related +// to the ingredient then the children of that artifact and finally the ingredients of those children. +// +// The ingredient cycle is: +// 00000000-0000-0000-0000-000000000010 (Ingredient0010) +// +// -> 00000000-0000-0000-0000-000000000001 (Artifact0001) +// -> 00000000-0000-0000-0000-000000000002 (Child of Artifact0001) +// -> 00000000-0000-0000-0000-000000000020 (Ingredient0020) +// -> 00000000-0000-0000-0000-000000000003 (Artifact0003) +// -> 00000000-0000-0000-0000-000000000004 (Child of Artifact0003) +// -> 00000000-0000-0000-0000-000000000030 (Ingredient0030) +// -> 00000000-0000-0000-0000-000000000005 (Artifact0005) +// -> 00000000-0000-0000-0000-000000000006 (Child of Artifact0005) +// -> 00000000-0000-0000-0000-000000000010 (Ingredient0010 cycle back to the first ingredient) +func createMockIngredientWithCycles() *Ingredient { + artifact0001 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000001"} + artifact0002 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000002"} + artifact0003 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000003"} + artifact0004 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000004"} + artifact0005 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000005"} + artifact0006 := &Artifact{ArtifactID: "00000000-0000-0000-0000-000000000006"} + + ingredient0010 := &Ingredient{ + IngredientSource: &raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000010", + }, + Artifacts: []*Artifact{ + artifact0001, + }, + } + + ingredient0020 := &Ingredient{ + IngredientSource: &raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000020", + }, + Artifacts: []*Artifact{ + artifact0003, + }, + } + + ingredient0030 := &Ingredient{ + IngredientSource: &raw.IngredientSource{ + IngredientID: "00000000-0000-0000-0000-000000000030", + }, + Artifacts: []*Artifact{ + artifact0005, + }, + } + + artifact0001.children = []ArtifactRelation{ + { + Artifact: artifact0002, + }, + } + + artifact0003.children = []ArtifactRelation{ + { + Artifact: artifact0004, + }, + } + + artifact0005.children = []ArtifactRelation{ + { + Artifact: artifact0006, + }, + } + + artifact0002.Ingredients = []*Ingredient{ + ingredient0020, + } + + artifact0004.Ingredients = []*Ingredient{ + ingredient0030, + } + + artifact0006.Ingredients = []*Ingredient{ + ingredient0010, + } + + return ingredient0010 + +} diff --git a/pkg/buildplan/raw/mock_test.go b/pkg/buildplan/raw/mock_test.go deleted file mode 100644 index e4ac797b6a..0000000000 --- a/pkg/buildplan/raw/mock_test.go +++ /dev/null @@ -1,194 +0,0 @@ -package raw - -import ( - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/go-openapi/strfmt" -) - -var buildWithSourceFromStep = &Build{ - Terminals: []*NamedTarget{ - { - Tag: "platform:00000000-0000-0000-0000-000000000001", - // Step 1: Traversal starts here, this one points to an artifact - NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, - }, - }, - Steps: []*Step{ - { - // Step 4: From here we can find which other nodes are linked to this one - StepID: "00000000-0000-0000-0000-000000000003", - Outputs: []string{"00000000-0000-0000-0000-000000000002"}, - Inputs: []*NamedTarget{ - // Step 5: Now we know which nodes are responsible for producing the output - {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000004"}}, - }, - }, - { - // Step 8: Same as step 4 - StepID: "00000000-0000-0000-0000-000000000005", - Outputs: []string{"00000000-0000-0000-0000-000000000004"}, - Inputs: []*NamedTarget{ - // Step 9: Same as step 5 - {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000006"}}, - }, - }, - }, - Artifacts: []*Artifact{ - { - // Step 2: We got an artifact, but there may be more hiding behind this one - NodeID: "00000000-0000-0000-0000-000000000002", - DisplayName: "installer", - // Step 3: Now to traverse any other input nodes that generated this one, this goes to the step - GeneratedBy: "00000000-0000-0000-0000-000000000003", - }, - { - // Step 6: We have another artifact, but since this is an x-artifact we also want meta info (ingredient name, version) - NodeID: "00000000-0000-0000-0000-000000000004", - DisplayName: "pkgOne", - // Step 7: Same as step 3 - GeneratedBy: "00000000-0000-0000-0000-000000000005", - }, - }, - Sources: []*Source{ - { - // Step 10: We have our ingredient - NodeID: "00000000-0000-0000-0000-000000000006", - }, - }, -} - -var buildWithSourceFromGeneratedBy = &Build{ - Terminals: []*NamedTarget{ - { - Tag: "platform:00000000-0000-0000-0000-000000000001", - NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002", "00000000-0000-0000-0000-000000000004"}, - }, - }, - Artifacts: []*Artifact{ - { - NodeID: "00000000-0000-0000-0000-000000000002", - DisplayName: "installer", - GeneratedBy: "00000000-0000-0000-0000-000000000004", - }, - { - NodeID: "00000000-0000-0000-0000-000000000003", - DisplayName: "installer", - GeneratedBy: "00000000-0000-0000-0000-000000000004", - }, - }, - Sources: []*Source{ - { - NodeID: "00000000-0000-0000-0000-000000000004", - }, - }, -} - -var buildWithBuildDeps = &Build{ - Terminals: []*NamedTarget{ - { - Tag: "platform:00000000-0000-0000-0000-000000000001", - NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, - }, - }, - Steps: []*Step{ - { - StepID: "00000000-0000-0000-0000-000000000003", - Outputs: []string{"00000000-0000-0000-0000-000000000002"}, - Inputs: []*NamedTarget{ - {Tag: "deps", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000004"}}, - }, - }, - }, - Artifacts: []*Artifact{ - { - NodeID: "00000000-0000-0000-0000-000000000002", - DisplayName: "installer", - GeneratedBy: "00000000-0000-0000-0000-000000000003", - }, - { - NodeID: "00000000-0000-0000-0000-000000000004", - DisplayName: "pkgOne", - GeneratedBy: "00000000-0000-0000-0000-000000000006", - }, - }, - Sources: []*Source{ - { - NodeID: "00000000-0000-0000-0000-000000000006", - }, - }, -} - -var buildWithRuntimeDeps = &Build{ - Terminals: []*NamedTarget{ - { - Tag: "platform:00000000-0000-0000-0000-000000000001", - NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, - }, - }, - Artifacts: []*Artifact{ - { - NodeID: "00000000-0000-0000-0000-000000000002", - DisplayName: "installer", - MimeType: types.XActiveStateArtifactMimeType, - RuntimeDependencies: []strfmt.UUID{ - "00000000-0000-0000-0000-000000000007", - }, - GeneratedBy: "00000000-0000-0000-0000-000000000003", - }, - { - NodeID: "00000000-0000-0000-0000-000000000007", - DisplayName: "pkgOne", - MimeType: types.XActiveStateArtifactMimeType, - GeneratedBy: "00000000-0000-0000-0000-000000000008", - }, - }, - Sources: []*Source{ - { - NodeID: "00000000-0000-0000-0000-000000000006", - }, - { - NodeID: "00000000-0000-0000-0000-000000000009", - }, - }, -} - -var buildWithRuntimeDepsViaSrc = &Build{ - Terminals: []*NamedTarget{ - { - Tag: "platform:00000000-0000-0000-0000-000000000001", - NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, - }, - }, - Steps: []*Step{ - { - StepID: "00000000-0000-0000-0000-000000000003", - Outputs: []string{"00000000-0000-0000-0000-000000000002"}, - Inputs: []*NamedTarget{ - {Tag: "src", NodeIDs: []strfmt.UUID{"00000000-0000-0000-0000-000000000007"}}, - }, - }, - }, - Artifacts: []*Artifact{ - { - NodeID: "00000000-0000-0000-0000-000000000002", - DisplayName: "installer", - MimeType: "application/unrecognized", - RuntimeDependencies: []strfmt.UUID{}, - GeneratedBy: "00000000-0000-0000-0000-000000000003", - }, - { - NodeID: "00000000-0000-0000-0000-000000000007", - DisplayName: "pkgOne", - MimeType: types.XActiveStateArtifactMimeType, - GeneratedBy: "00000000-0000-0000-0000-000000000008", - }, - }, - Sources: []*Source{ - { - NodeID: "00000000-0000-0000-0000-000000000006", - }, - { - NodeID: "00000000-0000-0000-0000-000000000009", - }, - }, -} diff --git a/pkg/buildplan/raw/walk.go b/pkg/buildplan/raw/walk.go index 0096b3ed27..89294a8cac 100644 --- a/pkg/buildplan/raw/walk.go +++ b/pkg/buildplan/raw/walk.go @@ -1,25 +1,38 @@ package raw import ( + "github.com/go-openapi/strfmt" + "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/go-openapi/strfmt" ) type walkFunc func(node interface{}, parent *Artifact) error -type WalkNodeContext struct { - Node interface{} - ParentArtifact *Artifact - tag StepInputTag - lookup map[strfmt.UUID]interface{} +type WalkStrategy struct { + tag StepInputTag + stopAtMultiSource bool // If true, we will stop walking if the artifact relates to multiple sources (eg. installer, docker img) } +var ( + WalkViaSingleSource = WalkStrategy{ + TagSource, + true, + } + WalkViaMultiSource = WalkStrategy{ + TagSource, + false, + } + WalkViaDeps = WalkStrategy{ + TagDependency, + false, + } +) + // WalkViaSteps walks the graph and reports on nodes it encounters // Note that the same node can be encountered multiple times if it is referenced in the graph multiple times. // In this case the context around the node may be different, even if the node itself isn't. -func (b *Build) WalkViaSteps(nodeIDs []strfmt.UUID, inputTag StepInputTag, walk walkFunc) error { +func (b *Build) WalkViaSteps(nodeIDs []strfmt.UUID, strategy WalkStrategy, walk walkFunc) error { lookup := b.LookupMap() for _, nodeID := range nodeIDs { @@ -27,7 +40,7 @@ func (b *Build) WalkViaSteps(nodeIDs []strfmt.UUID, inputTag StepInputTag, walk if !ok { return errs.New("node ID '%s' does not exist in lookup table", nodeID) } - if err := b.walkNodeViaSteps(node, nil, inputTag, walk); err != nil { + if err := b.walkNodeViaSteps(node, nil, strategy, walk); err != nil { return errs.Wrap(err, "could not recurse over node IDs") } } @@ -35,7 +48,7 @@ func (b *Build) WalkViaSteps(nodeIDs []strfmt.UUID, inputTag StepInputTag, walk return nil } -func (b *Build) walkNodeViaSteps(node interface{}, parent *Artifact, tag StepInputTag, walk walkFunc) error { +func (b *Build) walkNodeViaSteps(node interface{}, parent *Artifact, strategy WalkStrategy, walk walkFunc) error { lookup := b.LookupMap() if err := walk(node, parent); err != nil { @@ -63,24 +76,29 @@ func (b *Build) walkNodeViaSteps(node interface{}, parent *Artifact, tag StepInp // tool, but it's technically possible to happen if someone requested a builder as part of their order. _, isSource = generatedByNode.(*Source) if isSource { - if err := b.walkNodeViaSteps(generatedByNode, ar, tag, walk); err != nil { + if err := b.walkNodeViaSteps(generatedByNode, ar, strategy, walk); err != nil { return errs.Wrap(err, "error walking source from generatedBy") } return nil // Sources are at the end of the recursion. } - nodeIDs, err := b.inputNodeIDsFromStep(ar, tag) + nodeIDs, err := b.inputNodeIDsFromStep(ar, strategy.tag) if err != nil { return errs.Wrap(err, "error walking over step inputs") } + // Stop if the next step has multiple input node ID's; this means we cannot determine a single source + if strategy.stopAtMultiSource && len(nodeIDs) > 1 { + return nil + } + for _, id := range nodeIDs { // Grab subnode that we want to iterate over next subNode, ok := lookup[id] if !ok { return errs.New("node ID '%s' does not exist in lookup table", id) } - if err := b.walkNodeViaSteps(subNode, ar, tag, walk); err != nil { + if err := b.walkNodeViaSteps(subNode, ar, strategy, walk); err != nil { return errs.Wrap(err, "error iterating over %s", id) } } @@ -120,6 +138,7 @@ func (b *Build) inputNodeIDsFromStep(ar *Artifact, tag StepInputTag) ([]strfmt.U func (b *Build) WalkViaRuntimeDeps(nodeIDs []strfmt.UUID, walk walkFunc) error { lookup := b.LookupMap() + visited := make(map[strfmt.UUID]bool) for _, id := range nodeIDs { node, ok := lookup[id] @@ -127,7 +146,7 @@ func (b *Build) WalkViaRuntimeDeps(nodeIDs []strfmt.UUID, walk walkFunc) error { return errs.New("node ID '%s' does not exist in lookup table", id) } - if err := b.walkNodeViaRuntimeDeps(node, nil, walk); err != nil { + if err := b.walkNodeViaRuntimeDeps(node, nil, visited, walk); err != nil { return errs.Wrap(err, "error walking over runtime dep %s", id) } } @@ -135,17 +154,24 @@ func (b *Build) WalkViaRuntimeDeps(nodeIDs []strfmt.UUID, walk walkFunc) error { return nil } -func (b *Build) walkNodeViaRuntimeDeps(node interface{}, parent *Artifact, walk walkFunc) error { +func (b *Build) walkNodeViaRuntimeDeps(node interface{}, parent *Artifact, visited map[strfmt.UUID]bool, walk walkFunc) error { lookup := b.LookupMap() ar, ok := node.(*Artifact) if !ok { - // Technically this should never happen, but because we allow evaluating any part of a buildscript we can - // encounter scenarios where we have top level sources. In this case we can simply skip them, because the - // remaining top level nodes still cover our use-cases. - logging.Debug("node '%#v' is not an artifact, skipping", node) + // This can only happen in two scenarios that we're aware of: + // 1. Because we allow evaluating any part of a buildscript we can encounter scenarios where we have top level + // sources. + // 2. We are dealing with an old camel build. + // In these cases we can simply skip them, because the remaining top level nodes still cover our use-cases. + return nil + } + + // If we detect a cycle we should stop + if visited[ar.NodeID] { return nil } + visited[ar.NodeID] = true // Only state tool artifacts are considered to be a runtime dependency if IsStateToolMimeType(ar.MimeType) { @@ -167,7 +193,7 @@ func (b *Build) walkNodeViaRuntimeDeps(node interface{}, parent *Artifact, walk if !ok { return errs.New("step node ID '%s' does not exist in lookup table", id) } - if err := b.walkNodeViaRuntimeDeps(subNode, ar, walk); err != nil { + if err := b.walkNodeViaRuntimeDeps(subNode, ar, visited, walk); err != nil { return errs.Wrap(err, "error walking over runtime dep %s", id) } } @@ -177,7 +203,7 @@ func (b *Build) walkNodeViaRuntimeDeps(node interface{}, parent *Artifact, walk if !ok { return errs.New("node ID '%s' does not exist in lookup table", id) } - if err := b.walkNodeViaRuntimeDeps(subNode, ar, walk); err != nil { + if err := b.walkNodeViaRuntimeDeps(subNode, ar, visited, walk); err != nil { return errs.Wrap(err, "error walking over runtime dep %s", id) } } diff --git a/pkg/buildplan/raw/walk_test.go b/pkg/buildplan/raw/walk_test.go index 7744cfce64..12a887cf1b 100644 --- a/pkg/buildplan/raw/walk_test.go +++ b/pkg/buildplan/raw/walk_test.go @@ -1,4 +1,4 @@ -package raw +package raw_test import ( "fmt" @@ -7,6 +7,8 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/pkg/buildplan/mock" + "github.com/ActiveState/cli/pkg/buildplan/raw" "github.com/go-openapi/strfmt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -22,16 +24,16 @@ func TestRawBuild_walkNodesViaSteps(t *testing.T) { tests := []struct { name string nodeIDs []strfmt.UUID - tag StepInputTag - build *Build + strategy raw.WalkStrategy + build *raw.Build wantCalls []walkCall wantErr bool }{ { "Ingredient from step", []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, - TagSource, - buildWithSourceFromStep, + raw.WalkViaSingleSource, + mock.BuildWithSourceFromStep, []walkCall{ {"00000000-0000-0000-0000-000000000002", "Artifact", ""}, {"00000000-0000-0000-0000-000000000004", "Artifact", strfmt.UUID("00000000-0000-0000-0000-000000000002")}, @@ -42,8 +44,8 @@ func TestRawBuild_walkNodesViaSteps(t *testing.T) { { "Ingredient from generatedBy, multiple artifacts to same ingredient", []strfmt.UUID{"00000000-0000-0000-0000-000000000002", "00000000-0000-0000-0000-000000000003"}, - TagSource, - buildWithSourceFromGeneratedBy, + raw.WalkViaSingleSource, + mock.BuildWithSourceFromGeneratedBy, []walkCall{ {"00000000-0000-0000-0000-000000000002", "Artifact", ""}, {"00000000-0000-0000-0000-000000000004", "Source", strfmt.UUID("00000000-0000-0000-0000-000000000002")}, @@ -52,11 +54,25 @@ func TestRawBuild_walkNodesViaSteps(t *testing.T) { }, false, }, + { + "Multiple sources through installer artifact", + []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, + raw.WalkViaMultiSource, + mock.BuildWithInstallerDepsViaSrc, + []walkCall{ + {"00000000-0000-0000-0000-000000000002", "Artifact", ""}, + {"00000000-0000-0000-0000-000000000007", "Artifact", "00000000-0000-0000-0000-000000000002"}, + {"00000000-0000-0000-0000-000000000009", "Source", strfmt.UUID("00000000-0000-0000-0000-000000000007")}, + {"00000000-0000-0000-0000-000000000010", "Artifact", "00000000-0000-0000-0000-000000000002"}, + {"00000000-0000-0000-0000-000000000012", "Source", strfmt.UUID("00000000-0000-0000-0000-000000000010")}, + }, + false, + }, { "Build time deps", []strfmt.UUID{"00000000-0000-0000-0000-000000000002"}, - TagDependency, - buildWithBuildDeps, + raw.WalkViaDeps, + mock.BuildWithBuildDeps, []walkCall{ {"00000000-0000-0000-0000-000000000002", "Artifact", ""}, {"00000000-0000-0000-0000-000000000004", "Artifact", strfmt.UUID("00000000-0000-0000-0000-000000000002")}, @@ -69,16 +85,16 @@ func TestRawBuild_walkNodesViaSteps(t *testing.T) { t.Run(tt.name, func(t *testing.T) { calls := []walkCall{} - walk := func(node interface{}, parent *Artifact) error { + walk := func(node interface{}, parent *raw.Artifact) error { var parentID *strfmt.UUID if parent != nil { parentID = &parent.NodeID } var id strfmt.UUID switch v := node.(type) { - case *Artifact: + case *raw.Artifact: id = v.NodeID - case *Source: + case *raw.Source: id = v.NodeID default: t.Fatalf("unexpected node type %T", v) @@ -91,7 +107,7 @@ func TestRawBuild_walkNodesViaSteps(t *testing.T) { return nil } - if err := tt.build.WalkViaSteps(tt.nodeIDs, tt.tag, walk); (err != nil) != tt.wantErr { + if err := tt.build.WalkViaSteps(tt.nodeIDs, tt.strategy, walk); (err != nil) != tt.wantErr { t.Errorf("walkNodes() error = %v, wantErr %v", errs.JoinMessage(err), tt.wantErr) } @@ -122,14 +138,14 @@ func TestRawBuild_walkNodesViaRuntimeDeps(t *testing.T) { tests := []struct { name string nodeIDs []strfmt.UUID - build *Build + build *raw.Build wantCalls []walkCall wantErr bool }{ { "Runtime deps", - buildWithRuntimeDeps.Terminals[0].NodeIDs, - buildWithRuntimeDeps, + mock.BuildWithRuntimeDeps.Terminals[0].NodeIDs, + mock.BuildWithRuntimeDeps, []walkCall{ {"00000000-0000-0000-0000-000000000002", "Artifact", ""}, {"00000000-0000-0000-0000-000000000007", "Artifact", "00000000-0000-0000-0000-000000000002"}, @@ -138,10 +154,20 @@ func TestRawBuild_walkNodesViaRuntimeDeps(t *testing.T) { }, { "Runtime deps via src step", - buildWithRuntimeDepsViaSrc.Terminals[0].NodeIDs, - buildWithRuntimeDepsViaSrc, + mock.BuildWithInstallerDepsViaSrc.Terminals[0].NodeIDs, + mock.BuildWithInstallerDepsViaSrc, []walkCall{ {"00000000-0000-0000-0000-000000000007", "Artifact", "00000000-0000-0000-0000-000000000002"}, + {"00000000-0000-0000-0000-000000000010", "Artifact", "00000000-0000-0000-0000-000000000002"}, + }, + false, + }, + { + "Runtime deps with cycle", + mock.BuildWithRuntimeDepsViaSrcCycle.Terminals[0].NodeIDs, + mock.BuildWithRuntimeDepsViaSrcCycle, + []walkCall{ + {"00000000-0000-0000-0000-000000000013", "Artifact", "00000000-0000-0000-0000-000000000010"}, }, false, }, @@ -150,16 +176,16 @@ func TestRawBuild_walkNodesViaRuntimeDeps(t *testing.T) { t.Run(tt.name, func(t *testing.T) { calls := []walkCall{} - walk := func(node interface{}, parent *Artifact) error { + walk := func(node interface{}, parent *raw.Artifact) error { var parentID *strfmt.UUID if parent != nil { parentID = &parent.NodeID } var id strfmt.UUID switch v := node.(type) { - case *Artifact: + case *raw.Artifact: id = v.NodeID - case *Source: + case *raw.Source: id = v.NodeID default: t.Fatalf("unexpected node type %T", v) diff --git a/pkg/buildscript/buildscript.go b/pkg/buildscript/buildscript.go index f2ea329d53..9909f80527 100644 --- a/pkg/buildscript/buildscript.go +++ b/pkg/buildscript/buildscript.go @@ -1,174 +1,237 @@ package buildscript import ( - "encoding/json" + "errors" + "fmt" "time" + "github.com/ActiveState/cli/internal/condition" "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/pkg/buildscript/internal/buildexpression" - "github.com/ActiveState/cli/pkg/buildscript/internal/raw" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" - "github.com/go-openapi/strfmt" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/sliceutils" + "github.com/brunoga/deep" ) -// BuildScript is what we want consuming code to work with. This specifically makes the raw presentation private as no -// consuming code should ever be looking at the raw representation, instead this package should facilitate the use-case -// of the consuming code through convenience methods that are easy to understand and work with. +// BuildScript is what we want consuming code to work with. This specifically makes the raw +// presentation private as no consuming code should ever be looking at the raw representation. +// Instead this package should facilitate the use-case of the consuming code through convenience +// methods that are easy to understand and work with. type BuildScript struct { - // buildexpression is what we do all our modifications on. We will be planning work to move this to the raw type - // instead, but for now this is where most of the actual low level modification logic is done. - // https://activestatef.atlassian.net/jira/software/c/projects/DX/issues/DX-2825 - buildexpression *buildexpression.BuildExpression - atTime *time.Time + raw *rawBuildScript + + project string + atTime *time.Time } -func New() (*BuildScript, error) { - expr, err := buildexpression.New() - if err != nil { - return nil, errs.Wrap(err, "Could not create empty build expression") - } - script, err := unmarshalBuildExpressionTyped(expr, nil) - if err != nil { - return nil, errs.Wrap(err, "Could not create empty build expression") +func init() { + // Guard against emptyBuildExpression having parsing issues + if !condition.BuiltViaCI() || condition.InActiveStateCI() { + err := New().UnmarshalBuildExpression([]byte(emptyBuildExpression)) + if err != nil { + panic(err) + } } - return script, nil } -// Unmarshal will parse a buildscript from its presentation on disk -// This needs to unmarshal the ascript representation, and then convert that representation into a build expression -func Unmarshal(data []byte) (*BuildScript, error) { - raw, err := raw.Unmarshal(data) - if err != nil { - return nil, errs.Wrap(err, "Could not unmarshal buildscript") - } +func Create() *BuildScript { + bs := New() + // We don't handle unmarshalling errors here, see the init function for that. + // Since the empty build expression is a constant there's really no need to error check this each time. + _ = bs.UnmarshalBuildExpression([]byte(emptyBuildExpression)) + return bs +} - be, err := raw.MarshalBuildExpression() - if err != nil { - return nil, errs.Wrap(err, "Could not marshal build expression from raw") - } +func New() *BuildScript { + bs := &BuildScript{raw: &rawBuildScript{}} + return bs +} - expr, err := buildexpression.Unmarshal(be) - if err != nil { - return nil, errs.Wrap(err, "Could not unmarshal build expression") - } +func (b *BuildScript) Project() string { + return b.project +} + +func (b *BuildScript) SetProject(url string) { + b.project = url +} - return &BuildScript{expr, raw.AtTime}, nil +func (b *BuildScript) AtTime() *time.Time { + return b.atTime } -// UnmarshalBuildExpression will create buildscript using an existing build expression -// Buildscripts and build expressions are almost identical, with the exception of the atTime field. -// Build Expressions ALWAYS set at_time to `$at_time`, which refers to the timestamp on the commit. -// Whereas buildscripts encode this timestamp as part of their definition. For this reason we have to supply the -// timestamp as a separate argument. -func UnmarshalBuildExpression(b []byte, atTime *time.Time) (*BuildScript, error) { - expr, err := buildexpression.Unmarshal(b) +// SetAtTime sets the AtTime value, if the buildscript already has an AtTime value +// and `override=false` then the value passed here will be discarded. +// Override should in most cases only be true if we are making changes to the buildscript. +func (b *BuildScript) SetAtTime(t time.Time, override bool) { + if b.atTime != nil && !override { + return + } + // Ensure time is RFC3339 formatted, even though it's not actually stored at that format, it does still + // affect the specificity of the data stored and can ultimately lead to inconsistencies if not explicitly handled. + t2, err := time.Parse(time.RFC3339, t.Format(time.RFC3339)) if err != nil { - return nil, errs.Wrap(err, "Could not parse build expression") + // Pointless error check as this should never happen, but you know what they say about assumptions + logging.Error("Error parsing time: %s", err) } - - return unmarshalBuildExpressionTyped(expr, atTime) + b.atTime = ptr.To(t2) + _ = b.atTime } -func unmarshalBuildExpressionTyped(expr *buildexpression.BuildExpression, atTime *time.Time) (*BuildScript, error) { - // Copy incoming build expression to keep any modifications local. - var err error - expr, err = expr.Copy() +func (b *BuildScript) Equals(other *BuildScript) (bool, error) { + b2, err := b.Clone() + if err != nil { + return false, errs.Wrap(err, "Unable to clone buildscript") + } + other2, err := other.Clone() if err != nil { - return nil, errs.Wrap(err, "Could not copy build expression") + return false, errs.Wrap(err, "Unable to clone other buildscript") } - // Update old expressions that bake in at_time as a timestamp instead of as a variable. - // This will trump whatever value that held, which is fine because this only matters when we actually submit - // back the build expression, which by definition would be a write action on which we'd want to update the - // timestamp anyway. - err = expr.ForceAtTimeVar() + // Do not compare project URLs. + b2.SetProject("") + other2.SetProject("") + + myBytes, err := b2.Marshal() + if err != nil { + return false, errs.Wrap(err, "Unable to marshal this buildscript") + } + otherBytes, err := other2.Marshal() if err != nil { - return nil, errs.Wrap(err, "Could not set default timestamp") + return false, errs.Wrap(err, "Unable to marshal other buildscript") } - return &BuildScript{expr, atTime}, nil + return string(myBytes) == string(otherBytes), nil } -// MarshalBuildExpression translates our buildscript into a build expression -// The actual logic for this lives under the MarshalJSON methods below, named that way because that's what the json -// marshaller is expecting to find. -func (b *BuildScript) MarshalBuildExpression() ([]byte, error) { - bytes, err := json.MarshalIndent(b.buildexpression, "", " ") +func (b *BuildScript) Clone() (*BuildScript, error) { + bb, err := deep.Copy(b) if err != nil { - return nil, errs.Wrap(err, "Could not marshal build script to build expression") + return nil, errs.Wrap(err, "unable to clone buildscript") } - return bytes, nil + return bb, nil } -// Requirements returns the requirements in the Buildscript -// It returns an error if the requirements are not found or if they are malformed. -func (b *BuildScript) Requirements() ([]types.Requirement, error) { - return b.buildexpression.Requirements() +// FuncCall is the exportable version of funcCall, because we do not want to expose low level buildscript functionality +// outside of the buildscript package. +type FuncCall struct { + fc *funcCall } -// RequirementNotFoundError aliases the buildexpression error type, which can otherwise not be checked as its internal -type RequirementNotFoundError = buildexpression.RequirementNotFoundError - -// UpdateRequirement updates the Buildscripts requirements based on the operation and requirement. -func (b *BuildScript) UpdateRequirement(operation types.Operation, requirement types.Requirement) error { - return b.buildexpression.UpdateRequirement(operation, requirement) +func (f *FuncCall) MarshalJSON() ([]byte, error) { + return f.fc.MarshalJSON() } -func (b *BuildScript) UpdatePlatform(operation types.Operation, platformID strfmt.UUID) error { - return b.buildexpression.UpdatePlatform(operation, platformID) +// Argument returns the value of the given argument, or nil if it does not exist +// You will still need to cast the value to the correct type. +func (f *FuncCall) Argument(name string) any { + for _, a := range f.fc.Arguments { + if a.Assignment == nil || a.Assignment.Key != name { + continue + } + return exportValue(a.Assignment.Value) + } + return nil } -func (b *BuildScript) AtTime() *time.Time { - return b.atTime -} +// SetArgument will update the given argument, or add it if it does not exist +func (f *FuncCall) SetArgument(k string, v *value) { + for i, a := range f.fc.Arguments { + if a.Assignment == nil || a.Assignment.Key != k { + continue + } + f.fc.Arguments[i].Assignment.Value = v + return + } -func (b *BuildScript) SetAtTime(t time.Time) { - b.atTime = &t + // Arg doesn't exist; append it instead + f.fc.Arguments = append(f.fc.Arguments, &value{Assignment: &assignment{Key: k, Value: v}}) + + return } -func (b *BuildScript) Marshal() ([]byte, error) { - raw, err := raw.UnmarshalBuildExpression(b.buildexpression, b.atTime) - if err != nil { - return []byte(""), errs.Wrap(err, "Could not unmarshal build expression to raw") +// UnsetArgument will remove the given argument, if it exists +func (f *FuncCall) UnsetArgument(k string) { + for i, a := range f.fc.Arguments { + if a.Assignment == nil || a.Assignment.Key != k { + continue + } + f.fc.Arguments = append(f.fc.Arguments[:i], f.fc.Arguments[i+1:]...) + return } - return raw.Marshal() } -func (b *BuildScript) Equals(other *BuildScript) (bool, error) { - // Compare top-level at_time. - switch { - case b.atTime != nil && other.atTime != nil && b.atTime.String() != other.atTime.String(): - return false, nil - case (b.atTime == nil) != (other.atTime == nil): - return false, nil +// Value turns a standard type into a buildscript compatible type +// Intended for use with functions like SetArgument. +func Value[T string | int | float64 | []string | []float64](inputv T) *value { + v := &value{} + switch vt := any(inputv).(type) { + case string: + v.Str = &vt + case int: + v.Number = ptr.To(float64(vt)) + case float64: + v.Number = &vt + case []string: + strValues := make([]*value, len(vt)) + for i, s := range vt { + strValues[i] = &value{Str: &s} + } + v.List = &strValues + case []float64: + numValues := make([]*value, len(vt)) + for i, n := range vt { + numValues[i] = &value{Number: &n} + } + v.List = &numValues } - // Compare buildexpression JSON. - myJson, err := b.MarshalBuildExpression() - if err != nil { - return false, errs.New("Unable to marshal this buildscript to JSON: %s", errs.JoinMessage(err)) - } - otherJson, err := other.MarshalBuildExpression() - if err != nil { - return false, errs.New("Unable to marshal other buildscript to JSON: %s", errs.JoinMessage(err)) - } - return string(myJson) == string(otherJson), nil + return v } -func (b *BuildScript) Merge(b2 *BuildScript, strategies *mono_models.MergeStrategies) (*BuildScript, error) { - expr, err := buildexpression.Merge(b.buildexpression, b2.buildexpression, strategies) - if err != nil { - return nil, errs.Wrap(err, "Could not merge build expressions") +// exportValue takes a raw buildscript value and turns it into an externally consumable one +// Note not all value types are currently fully supported. For example assignments and objects currently are +// passed as the raw type, which can't be cast externally as they are private types. +// We'll want to update these as the use-cases for them become more clear. +func exportValue(v *value) any { + switch { + case v.FuncCall != nil: + if req := parseRequirement(v); req != nil { + return req + } + return &FuncCall{v.FuncCall} + case v.List != nil: + result := []any{} + for _, value := range *v.List { + result = append(result, exportValue(value)) + } + if v, ok := sliceutils.Cast[string](result); ok { + return v + } + if v, ok := sliceutils.Cast[float64](result); ok { + return v + } + return result + case v.Str != nil: + return *v.Str + case v.Number != nil: + return *v.Number + case v.Null != nil: + return nil + case v.Assignment != nil: + return v.Assignment + case v.Object != nil: + return v.Object } + return errors.New(fmt.Sprintf("unknown value type: %#v", v)) +} - // When merging buildscripts we want to use the most recent timestamp - atTime := b.atTime - if b.atTime != nil && b.atTime.After(*b2.atTime) { - atTime = b2.atTime +// FunctionCalls will return all function calls that match the given name, regardless of where they occur. +func (b *BuildScript) FunctionCalls(name string) []*FuncCall { + result := []*FuncCall{} + for _, f := range b.raw.FuncCalls() { + if f.Name == name { + result = append(result, &FuncCall{f}) + } } - - bs, err := unmarshalBuildExpressionTyped(expr, atTime) - - return bs, nil + return result } diff --git a/pkg/buildscript/buildscript_test.go b/pkg/buildscript/buildscript_test.go index 6376041ba7..a5fed3d3b9 100644 --- a/pkg/buildscript/buildscript_test.go +++ b/pkg/buildscript/buildscript_test.go @@ -1,57 +1,199 @@ package buildscript import ( + "fmt" + "path/filepath" "testing" "time" - "github.com/go-openapi/strfmt" + "github.com/ActiveState/cli/internal/environment" + "github.com/ActiveState/cli/internal/fileutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -// TestRoundTripFromBuildScript tests that if we read a buildscript from disk and then write it again it produces the -// exact same value. +var basicBuildScript = []byte( + checkoutInfoString(testProject, testTime) + ` +runtime = state_tool_artifacts( + src = sources +) +sources = solve( + at_time = TIME, + platforms = [ + "12345", + "67890" + ], + requirements = [ + Req(name = "python", namespace = "language", version = Eq(value = "3.10.10")) + ], + solver_version = null +) + +main = runtime`) + +var basicBuildExpression = []byte(`{ + "let": { + "in": "$runtime", + "runtime": { + "state_tool_artifacts": { + "src": "$sources" + } + }, + "sources": { + "solve": { + "at_time": "$at_time", + "platforms": [ + "12345", + "67890" + ], + "requirements": [ + { + "name": "python", + "namespace": "language", + "version_requirements": [ + { + "comparator": "eq", + "version": "3.10.10" + } + ] + } + ], + "solver_version": null + } + } + } +}`) + +// TestRoundTripFromBuildScript tests that if we read a build script from disk and then write it +// again it produces the exact same value. func TestRoundTripFromBuildScript(t *testing.T) { script, err := Unmarshal(basicBuildScript) require.NoError(t, err) - bs, err := script.Marshal() + data, err := script.Marshal() require.NoError(t, err) + t.Logf("marshalled:\n%s\n---", string(data)) - roundTripScript, err := Unmarshal(bs) + roundTripScript, err := Unmarshal(data) require.NoError(t, err) assert.Equal(t, script, roundTripScript) + equal, err := script.Equals(roundTripScript) + require.NoError(t, err) + assert.True(t, equal) } -// TestRoundTripFromBuildExpression tests that if we receive a build expression from the API and eventually write it -// back without any modifications it is still the same. +// TestRoundTripFromBuildExpression tests that if we construct a buildscript from a Platform build +// expression and then immediately construct another build expression from that build script, the +// build expressions are identical. func TestRoundTripFromBuildExpression(t *testing.T) { - bs, err := UnmarshalBuildExpression(basicBuildExpression, nil) + script := New() + err := script.UnmarshalBuildExpression(basicBuildExpression) require.NoError(t, err) - output, err := bs.MarshalBuildExpression() + + data, err := script.MarshalBuildExpression() require.NoError(t, err) - require.Equal(t, string(basicBuildExpression), string(output)) + + require.Equal(t, string(basicBuildExpression), string(data)) } -func TestExpressionToScript(t *testing.T) { - ts, err := time.Parse(strfmt.RFC3339Millis, atTime) +func TestRoundTripFromBuildExpressionWithLegacyAtTime(t *testing.T) { + wd, err := environment.GetRootPath() require.NoError(t, err) - bs, err := UnmarshalBuildExpression(basicBuildExpression, &ts) + initialTimeStamp := "2024-10-15T16:37:06Z" + updatedTimeStamp := "2024-10-15T16:37:07Z" + + data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "buildscript", "testdata", "buildexpression-roundtrip-legacy.json")) require.NoError(t, err) - as, err := bs.Marshal() + // The initial build expression does not use the new at_time format + assert.NotContains(t, string(data), "$at_time") + + script := New() + require.NoError(t, script.UnmarshalBuildExpression(data)) + + // Ensure that legacy at_time is preserved in the buildscript. + atTime := script.AtTime() + require.NotNil(t, atTime) + require.Equal(t, initialTimeStamp, atTime.Format(time.RFC3339)) + + data, err = script.MarshalBuildExpression() + require.NoError(t, err) + + // When the build expression is unmarshalled it should now use the new at_time format + assert.Contains(t, string(data), "$at_time") + assert.NotContains(t, string(data), initialTimeStamp) + + // Update the time in the build script but don't override the existing time + updatedTime, err := time.Parse(time.RFC3339, updatedTimeStamp) + require.NoError(t, err) + script.SetAtTime(updatedTime, false) + + // The updated time should be reflected in the build script + require.Equal(t, initialTimeStamp, script.AtTime().Format(time.RFC3339)) + + data, err = script.Marshal() require.NoError(t, err) - require.Equal(t, string(basicBuildScript), string(as)) + + // The marshalled build script should NOT contain the updated time + // in the Time block at the top of the script. + assert.Contains(t, string(data), initialTimeStamp) + assert.NotContains(t, string(data), fmt.Sprintf("Time: %s", updatedTime)) + + // Now override the time in the build script + script.SetAtTime(updatedTime, true) + require.Equal(t, updatedTimeStamp, script.AtTime().Format(time.RFC3339)) + + data, err = script.Marshal() + require.NoError(t, err) + + // The marshalled build script should NOW contain the updated time + // in the Time block at the top of the script. + assert.Contains(t, string(data), updatedTimeStamp) + assert.NotContains(t, string(data), fmt.Sprintf("Time: %s", initialTimeStamp)) + + data, err = script.MarshalBuildExpression() + require.NoError(t, err) + + // The build expression representation should now use the new at_time format + assert.Contains(t, string(data), "$at_time") +} + +// TestExpressionToScript tests that creating a build script from a given Platform build expression +// and at time produces the expected result. +func TestExpressionToScript(t *testing.T) { + ts, err := time.Parse(time.RFC3339, testTime) + require.NoError(t, err) + + script := New() + script.SetProject(testProject) + script.SetAtTime(ts, false) + require.NoError(t, script.UnmarshalBuildExpression(basicBuildExpression)) + + data, err := script.Marshal() + require.NoError(t, err) + + require.Equal(t, string(basicBuildScript), string(data)) } +// TestScriptToExpression tests that we can produce a valid Platform build expression from a build +// script on disk. func TestScriptToExpression(t *testing.T) { bs, err := Unmarshal(basicBuildScript) require.NoError(t, err) - as, err := bs.MarshalBuildExpression() + data, err := bs.MarshalBuildExpression() require.NoError(t, err) - require.Equal(t, string(basicBuildExpression), string(as)) + require.Equal(t, string(basicBuildExpression), string(data)) +} + +func TestOutdatedScript(t *testing.T) { + _, err := Unmarshal([]byte( + `at_time = "2000-01-01T00:00:00Z" + main = runtime + `)) + assert.Error(t, err) + assert.ErrorIs(t, err, ErrOutdatedAtTime) } diff --git a/pkg/buildscript/internal/buildexpression/buildexpression.go b/pkg/buildscript/internal/buildexpression/buildexpression.go deleted file mode 100644 index b217abd4d8..0000000000 --- a/pkg/buildscript/internal/buildexpression/buildexpression.go +++ /dev/null @@ -1,983 +0,0 @@ -package buildexpression - -import ( - "encoding/json" - "errors" - "fmt" - "sort" - "strings" - - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/ActiveState/cli/internal/sliceutils" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/go-openapi/strfmt" -) - -const ( - SolveFuncName = "solve" - SolveLegacyFuncName = "solve_legacy" - RequirementsKey = "requirements" - PlatformsKey = "platforms" - AtTimeKey = "at_time" - RequirementNameKey = "name" - RequirementNamespaceKey = "namespace" - RequirementVersionRequirementsKey = "version_requirements" - RequirementVersionKey = "version" - RequirementRevisionKey = "revision" - RequirementComparatorKey = "comparator" - - ctxLet = "let" - ctxIn = "in" - ctxAp = "ap" - ctxValue = "value" - ctxAssignments = "assignments" - ctxIsAp = "isAp" -) - -var funcNodeNotFoundError = errors.New("Could not find function node") - -type BuildExpression struct { - Let *Let - Assignments []*Value -} - -type Let struct { - // Let statements can be nested. - // Each let will contain its own assignments and an in statement. - Let *Let - Assignments []*Var - In *In -} - -type Var struct { - Name string - Value *Value -} - -type Value struct { - Ap *Ap - List *[]*Value - Str *string - Null *Null - Float *float64 - Int *int - - Assignment *Var - Object *[]*Var - Ident *string -} - -type Null struct { - Null string -} - -type Ap struct { - Name string - Arguments []*Value -} - -type In struct { - FuncCall *Ap - Name *string -} - -// Unmarshal creates a BuildExpression from a JSON byte array. -func Unmarshal(data []byte) (*BuildExpression, error) { - rawBuildExpression := make(map[string]interface{}) - err := json.Unmarshal(data, &rawBuildExpression) - if err != nil { - return nil, errs.Wrap(err, "Could not unmarshal build expression") - } - - if len(rawBuildExpression) != 1 { - return nil, errs.New("Build expression must have exactly one key") - } - - expr := &BuildExpression{} - var path []string - for key, value := range rawBuildExpression { - switch v := value.(type) { - case map[string]interface{}: - // At this level the key must either be a let, an ap, or an assignment. - if key == "let" { - let, err := newLet(path, v) - if err != nil { - return nil, errs.Wrap(err, "Could not parse 'let' key") - } - - expr.Let = let - } else if isAp(path, v) { - ap, err := newAp(path, v) - if err != nil { - return nil, errs.Wrap(err, "Could not parse '%s' key", key) - } - - expr.Assignments = append(expr.Assignments, &Value{Ap: ap}) - } else { - assignments, err := newAssignments(path, v) - if err != nil { - return nil, errs.Wrap(err, "Could not parse assignments") - } - - expr.Assignments = append(expr.Assignments, &Value{Assignment: &Var{Name: key, Value: &Value{Object: &assignments}}}) - } - default: - return nil, errs.New("Build expression's value must be a map[string]interface{}") - } - } - - err = expr.validateRequirements() - if err != nil { - return nil, errs.Wrap(err, "Could not validate requirements") - } - - err = expr.normalizeTimestamp() - if err != nil { - return nil, errs.Wrap(err, "Could not normalize timestamp") - } - - return expr, nil -} - -// New creates a minimal, empty buildexpression. -func New() (*BuildExpression, error) { - // At this time, there is no way to ask the Platform for an empty buildexpression, so build one - // manually. - expr, err := Unmarshal([]byte(` -{ - "let": { - "sources": { - "solve": { - "at_time": "$at_time", - "platforms": [], - "requirements": [], - "solver_version": null - } - }, - "runtime": { - "state_tool_artifacts_v1": { - "src": "$sources" - } - }, - "in": "$runtime" - } -}`)) - if err != nil { - return nil, errs.Wrap(err, "Unable to create initial buildexpression") - } - return expr, nil -} - -func newLet(path []string, m map[string]interface{}) (*Let, error) { - path = append(path, ctxLet) - defer func() { - _, _, err := sliceutils.Pop(path) - if err != nil { - multilog.Error("Could not pop context: %v", err) - } - }() - - inValue, ok := m["in"] - if !ok { - return nil, errs.New("Build expression's 'let' object has no 'in' key") - } - - in, err := newIn(path, inValue) - if err != nil { - return nil, errs.Wrap(err, "Could not parse 'in' key's value: %v", inValue) - } - - // Delete in so it doesn't get parsed as an assignment. - delete(m, "in") - - result := &Let{In: in} - let, ok := m["let"] - if ok { - letMap, ok := let.(map[string]interface{}) - if !ok { - return nil, errs.New("'let' key's value is not a map[string]interface{}") - } - - l, err := newLet(path, letMap) - if err != nil { - return nil, errs.Wrap(err, "Could not parse 'let' key") - } - result.Let = l - - // Delete let so it doesn't get parsed as an assignment. - delete(m, "let") - } - - assignments, err := newAssignments(path, m) - if err != nil { - return nil, errs.Wrap(err, "Could not parse assignments") - } - - result.Assignments = assignments - return result, nil -} - -func isAp(path []string, value map[string]interface{}) bool { - path = append(path, ctxIsAp) - defer func() { - _, _, err := sliceutils.Pop(path) - if err != nil { - multilog.Error("Could not pop context: %v", err) - } - }() - - _, hasIn := value["in"] - if hasIn && !sliceutils.Contains(path, ctxAssignments) { - return false - } - - return true -} - -func newValue(path []string, valueInterface interface{}) (*Value, error) { - path = append(path, ctxValue) - defer func() { - _, _, err := sliceutils.Pop(path) - if err != nil { - multilog.Error("Could not pop context: %v", err) - } - }() - - value := &Value{} - - switch v := valueInterface.(type) { - case map[string]interface{}: - // Examine keys first to see if this is a function call. - for key, val := range v { - if _, ok := val.(map[string]interface{}); !ok { - continue - } - - // If the length of the value is greater than 1, - // then it's not a function call. It's an object - // and will be set as such outside the loop. - if len(v) > 1 { - continue - } - - if isAp(path, val.(map[string]interface{})) { - f, err := newAp(path, v) - if err != nil { - return nil, errs.Wrap(err, "Could not parse '%s' function's value: %v", key, v) - } - value.Ap = f - } - } - - if value.Ap == nil { - // It's not a function call, but an object. - object, err := newAssignments(path, v) - if err != nil { - return nil, errs.Wrap(err, "Could not parse object: %v", v) - } - value.Object = &object - } - - case []interface{}: - values := []*Value{} - for _, item := range v { - value, err := newValue(path, item) - if err != nil { - return nil, errs.Wrap(err, "Could not parse list: %v", v) - } - values = append(values, value) - } - value.List = &values - - case string: - if sliceutils.Contains(path, ctxIn) { - value.Ident = &v - } else { - value.Str = ptr.To(v) - } - - case float64: - value.Float = ptr.To(v) - - case nil: - // An empty value is interpreted as JSON null. - value.Null = &Null{} - - default: - logging.Debug("Unknown type: %T at path %s", v, strings.Join(path, ".")) - // An empty value is interpreted as JSON null. - value.Null = &Null{} - } - - return value, nil -} - -func newAp(path []string, m map[string]interface{}) (*Ap, error) { - path = append(path, ctxAp) - defer func() { - _, _, err := sliceutils.Pop(path) - if err != nil { - multilog.Error("Could not pop context: %v", err) - } - }() - - // m is a mapping of function name to arguments. There should only be one - // set of arugments. Since the arguments are key-value pairs, it should be - // a map[string]interface{}. - if len(m) > 1 { - return nil, errs.New("Function call has more than one argument mapping") - } - - // Look in the given object for the function's name and argument mapping. - var name string - var argsInterface interface{} - for key, value := range m { - _, ok := value.(map[string]interface{}) - if !ok { - return nil, errs.New("Incorrect argument format") - } - - name = key - argsInterface = value - } - - args := []*Value{} - - switch v := argsInterface.(type) { - case map[string]interface{}: - for key, valueInterface := range v { - value, err := newValue(path, valueInterface) - if err != nil { - return nil, errs.Wrap(err, "Could not parse '%s' function's argument '%s': %v", name, key, valueInterface) - } - args = append(args, &Value{Assignment: &Var{Name: key, Value: value}}) - } - sort.SliceStable(args, func(i, j int) bool { return args[i].Assignment.Name < args[j].Assignment.Name }) - - case []interface{}: - for _, item := range v { - value, err := newValue(path, item) - if err != nil { - return nil, errs.Wrap(err, "Could not parse '%s' function's argument list item: %v", name, item) - } - args = append(args, value) - } - - default: - return nil, errs.New("Function '%s' expected to be object or list", name) - } - - return &Ap{Name: name, Arguments: args}, nil -} - -func newAssignments(path []string, m map[string]interface{}) ([]*Var, error) { - path = append(path, ctxAssignments) - defer func() { - _, _, err := sliceutils.Pop(path) - if err != nil { - multilog.Error("Could not pop context: %v", err) - } - }() - - assignments := []*Var{} - for key, valueInterface := range m { - value, err := newValue(path, valueInterface) - if err != nil { - return nil, errs.Wrap(err, "Could not parse '%s' key's value: %v", key, valueInterface) - } - assignments = append(assignments, &Var{Name: key, Value: value}) - - } - sort.SliceStable(assignments, func(i, j int) bool { - return assignments[i].Name < assignments[j].Name - }) - return assignments, nil -} - -func newIn(path []string, inValue interface{}) (*In, error) { - path = append(path, ctxIn) - defer func() { - _, _, err := sliceutils.Pop(path) - if err != nil { - multilog.Error("Could not pop context: %v", err) - } - }() - - in := &In{} - - switch v := inValue.(type) { - case map[string]interface{}: - f, err := newAp(path, v) - if err != nil { - return nil, errs.Wrap(err, "'in' object is not a function call") - } - in.FuncCall = f - - case string: - in.Name = ptr.To(strings.TrimPrefix(v, "$")) - - default: - return nil, errs.New("'in' value expected to be a function call or string") - } - - return in, nil -} - -// validateRequirements ensures that the requirements in the BuildExpression contain -// both the name and namespace fields. These fileds are used for requirement operations. -func (e *BuildExpression) validateRequirements() error { - requirements, err := e.getRequirementsNode() - if err != nil { - return errs.Wrap(err, "Could not get requirements node") - } - - for _, r := range requirements { - if r.Object == nil { - continue - } - - // The requirement object needs to have a name and value field. - // The value can be a string (in the case of name or namespace) - // or a list (in the case of version requirements). - for _, o := range *r.Object { - if o.Name == "" { - return errs.New("Requirement object missing name field") - } - - if o.Value == nil { - return errs.New("Requirement object missing value field") - } - - if o.Name == RequirementNameKey || o.Name == RequirementNamespaceKey { - if o.Value.Str == nil { - return errs.New("Requirement object value is not set to a string") - } - } - - if o.Name == RequirementVersionRequirementsKey { - if o.Value.List == nil { - return errs.New("Requirement object value is not set to a list") - } - } - } - } - return nil -} - -func (e *BuildExpression) Requirements() ([]types.Requirement, error) { - requirementsNode, err := e.getRequirementsNode() - if err != nil { - return nil, errs.Wrap(err, "Could not get requirements node") - } - - var requirements []types.Requirement - for _, r := range requirementsNode { - if r.Object == nil { - continue - } - - var req types.Requirement - for _, o := range *r.Object { - if o.Name == RequirementNameKey { - req.Name = *o.Value.Str - } - - if o.Name == RequirementNamespaceKey { - req.Namespace = *o.Value.Str - } - - if o.Name == RequirementVersionRequirementsKey { - req.VersionRequirement = getVersionRequirements(o.Value.List) - } - } - requirements = append(requirements, req) - } - - return requirements, nil -} - -func (e *BuildExpression) getRequirementsNode() ([]*Value, error) { - solveAp, err := e.getSolveNode() - if err != nil { - return nil, errs.Wrap(err, "Could not get solve node") - } - - var reqs []*Value - for _, arg := range solveAp.Arguments { - if arg.Assignment == nil { - continue - } - - if arg.Assignment.Name == RequirementsKey && arg.Assignment.Value != nil { - reqs = *arg.Assignment.Value.List - } - } - - return reqs, nil -} - -func getVersionRequirements(v *[]*Value) []types.VersionRequirement { - var reqs []types.VersionRequirement - - if v == nil { - return reqs - } - - for _, r := range *v { - if r.Object == nil { - continue - } - - versionReq := make(types.VersionRequirement) - for _, o := range *r.Object { - if o.Name == RequirementComparatorKey { - versionReq[RequirementComparatorKey] = *o.Value.Str - } - - if o.Name == RequirementVersionKey { - versionReq[RequirementVersionKey] = *o.Value.Str - } - } - reqs = append(reqs, versionReq) - } - return reqs -} - -// getSolveNode returns the solve node from the build expression. -// It returns an error if the solve node is not found. -// Currently, the solve node can have the name of "solve" or "solve_legacy". -// It expects the JSON representation of the build expression to be formatted as follows: -// -// { -// "let": { -// "runtime": { -// "solve": { -// } -// } -// } -// } -func (e *BuildExpression) getSolveNode() (*Ap, error) { - // First, try to find the solve node via lets. - if e.Let != nil { - solveAp, err := recurseLets(e.Let) - if err != nil { - return nil, errs.Wrap(err, "Could not recurse lets") - } - - return solveAp, nil - } - - // Search for solve node in the top level assignments. - for _, a := range e.Assignments { - if a.Assignment == nil { - continue - } - - if a.Assignment.Name == "" { - continue - } - - if a.Assignment.Value == nil { - continue - } - - if a.Assignment.Value.Ap == nil { - continue - } - - if a.Assignment.Value.Ap.Name == SolveFuncName || a.Assignment.Value.Ap.Name == SolveLegacyFuncName { - return a.Assignment.Value.Ap, nil - } - } - - return nil, funcNodeNotFoundError -} - -// recurseLets recursively searches for the solve node in the let statements. -// The solve node is specified by the name "runtime" and the function name "solve" -// or "solve_legacy". -func recurseLets(let *Let) (*Ap, error) { - for _, a := range let.Assignments { - if a.Value == nil { - continue - } - - if a.Value.Ap == nil { - continue - } - - if a.Name == "" { - continue - } - - if a.Value.Ap.Name == SolveFuncName || a.Value.Ap.Name == SolveLegacyFuncName { - return a.Value.Ap, nil - } - } - - // The highest level solve node is not found, so recurse into the next let. - if let.Let != nil { - return recurseLets(let.Let) - } - - return nil, funcNodeNotFoundError -} - -func (e *BuildExpression) getSolveNodeArguments() ([]*Value, error) { - solveAp, err := e.getSolveNode() - if err != nil { - return nil, errs.Wrap(err, "Could not get solve node") - } - - return solveAp.Arguments, nil -} - -func (e *BuildExpression) getSolveAtTimeValue() (*Value, error) { - solveAp, err := e.getSolveNode() - if err != nil { - return nil, errs.Wrap(err, "Could not get solve node") - } - - for _, arg := range solveAp.Arguments { - if arg.Assignment != nil && arg.Assignment.Name == AtTimeKey { - return arg.Assignment.Value, nil - } - } - - return nil, errs.New("Could not find %s", AtTimeKey) -} - -func (e *BuildExpression) getPlatformsNode() (*[]*Value, error) { - solveAp, err := e.getSolveNode() - if err != nil { - return nil, errs.Wrap(err, "Could not get solve node") - } - - for _, arg := range solveAp.Arguments { - if arg.Assignment == nil { - continue - } - - if arg.Assignment.Name == PlatformsKey && arg.Assignment.Value != nil { - return arg.Assignment.Value.List, nil - } - } - - return nil, errs.New("Could not find platforms node") -} - -func (e *BuildExpression) UpdateRequirement(operation types.Operation, requirement types.Requirement) error { - var err error - switch operation { - case types.OperationAdded: - err = e.addRequirement(requirement) - case types.OperationRemoved: - err = e.removeRequirement(requirement) - case types.OperationUpdated: - err = e.removeRequirement(requirement) - if err != nil { - break - } - err = e.addRequirement(requirement) - default: - return errs.New("Unsupported operation") - } - if err != nil { - return errs.Wrap(err, "Could not update BuildExpression's requirements") - } - - return nil -} - -func (e *BuildExpression) addRequirement(requirement types.Requirement) error { - obj := []*Var{ - {Name: RequirementNameKey, Value: &Value{Str: ptr.To(requirement.Name)}}, - {Name: RequirementNamespaceKey, Value: &Value{Str: ptr.To(requirement.Namespace)}}, - } - - if requirement.Revision != nil { - obj = append(obj, &Var{Name: RequirementRevisionKey, Value: &Value{Int: requirement.Revision}}) - } - - if requirement.VersionRequirement != nil { - values := []*Value{} - for _, r := range requirement.VersionRequirement { - values = append(values, &Value{Object: &[]*Var{ - {Name: RequirementComparatorKey, Value: &Value{Str: ptr.To(r[RequirementComparatorKey])}}, - {Name: RequirementVersionKey, Value: &Value{Str: ptr.To(r[RequirementVersionKey])}}, - }}) - } - obj = append(obj, &Var{Name: RequirementVersionRequirementsKey, Value: &Value{List: &values}}) - } - - requirementsNode, err := e.getRequirementsNode() - if err != nil { - return errs.Wrap(err, "Could not get requirements node") - } - - requirementsNode = append(requirementsNode, &Value{Object: &obj}) - - arguments, err := e.getSolveNodeArguments() - if err != nil { - return errs.Wrap(err, "Could not get solve node arguments") - } - - for _, arg := range arguments { - if arg.Assignment == nil { - continue - } - - if arg.Assignment.Name == RequirementsKey { - arg.Assignment.Value.List = &requirementsNode - } - } - - return nil -} - -type RequirementNotFoundError struct { - Name string - *locale.LocalizedError // for legacy non-user-facing error usages -} - -func (e *BuildExpression) removeRequirement(requirement types.Requirement) error { - requirementsNode, err := e.getRequirementsNode() - if err != nil { - return errs.Wrap(err, "Could not get requirements node") - } - - var found bool - for i, r := range requirementsNode { - if r.Object == nil { - continue - } - - for _, o := range *r.Object { - if o.Name == RequirementNameKey && *o.Value.Str == requirement.Name { - requirementsNode = append(requirementsNode[:i], requirementsNode[i+1:]...) - found = true - break - } - } - } - - if !found { - return &RequirementNotFoundError{ - requirement.Name, - locale.NewInputError("err_remove_requirement_not_found", "", requirement.Name), - } - } - - solveNode, err := e.getSolveNode() - if err != nil { - return errs.Wrap(err, "Could not get solve node") - } - - for _, arg := range solveNode.Arguments { - if arg.Assignment == nil { - continue - } - - if arg.Assignment.Name == RequirementsKey { - arg.Assignment.Value.List = &requirementsNode - } - } - - return nil -} - -func (e *BuildExpression) UpdatePlatform(operation types.Operation, platformID strfmt.UUID) error { - var err error - switch operation { - case types.OperationAdded: - err = e.addPlatform(platformID) - case types.OperationRemoved: - err = e.removePlatform(platformID) - default: - return errs.New("Unsupported operation") - } - if err != nil { - return errs.Wrap(err, "Could not update BuildExpression's platform") - } - - return nil -} - -func (e *BuildExpression) addPlatform(platformID strfmt.UUID) error { - platformsNode, err := e.getPlatformsNode() - if err != nil { - return errs.Wrap(err, "Could not get platforms node") - } - - *platformsNode = append(*platformsNode, &Value{Str: ptr.To(platformID.String())}) - - return nil -} - -func (e *BuildExpression) removePlatform(platformID strfmt.UUID) error { - platformsNode, err := e.getPlatformsNode() - if err != nil { - return errs.Wrap(err, "Could not get platforms node") - } - - var found bool - for i, p := range *platformsNode { - if p.Str == nil { - continue - } - - if *p.Str == platformID.String() { - *platformsNode = append((*platformsNode)[:i], (*platformsNode)[i+1:]...) - found = true - break - } - } - - if !found { - return errs.New("Could not find platform") - } - - return nil -} - -// ForceAtTimeVar will set the AtTime variable to `$at_time`, which is how we want build expressions to record their -// timestamp going forward. -func (e *BuildExpression) ForceAtTimeVar() error { - atTimeNode, err := e.getSolveAtTimeValue() - if err != nil { - return errs.Wrap(err, "Could not get %s node", AtTimeKey) - } - atTimeNode.Str = ptr.To("$" + AtTimeKey) - return nil -} - -// normalizeTimestamp normalizes the solve node's timestamp, if possible. -// Platform timestamps may differ from the strfmt.DateTime format. For example, Platform -// timestamps will have microsecond precision, while strfmt.DateTime will only have millisecond -// precision. This will affect comparisons between buildexpressions (which is normally done -// byte-by-byte). -func (e *BuildExpression) normalizeTimestamp() error { - atTimeNode, err := e.getSolveAtTimeValue() - if err != nil { - return errs.Wrap(err, "Could not get at time node") - } - - if atTimeNode.Str != nil && !strings.HasPrefix(*atTimeNode.Str, "$") { - atTime, err := strfmt.ParseDateTime(*atTimeNode.Str) - if err != nil { - return errs.Wrap(err, "Invalid timestamp: %s", *atTimeNode.Str) - } - atTimeNode.Str = ptr.To(atTime.String()) - } - - return nil -} - -func (e *BuildExpression) Copy() (*BuildExpression, error) { - bytes, err := json.Marshal(e) - if err != nil { - return nil, errs.Wrap(err, "Failed to marshal build expression during copy") - } - return Unmarshal(bytes) -} - -func (e *BuildExpression) MarshalJSON() ([]byte, error) { - m := make(map[string]interface{}) - - if e.Let != nil { - m["let"] = e.Let - } - - for _, value := range e.Assignments { - if value.Assignment == nil { - continue - } - - m[value.Assignment.Name] = value - } - - return json.Marshal(m) -} - -func (l *Let) MarshalJSON() ([]byte, error) { - m := make(map[string]interface{}) - - if l.Let != nil { - m["let"] = l.Let - } - - for _, v := range l.Assignments { - if v.Value == nil { - continue - } - - m[v.Name] = v.Value - } - - m["in"] = l.In - - return json.Marshal(m) -} - -func (a *Var) MarshalJSON() ([]byte, error) { - m := make(map[string]interface{}) - m[a.Name] = a.Value - return json.Marshal(m) -} - -func (v *Value) MarshalJSON() ([]byte, error) { - switch { - case v.Ap != nil: - return json.Marshal(v.Ap) - case v.List != nil: - return json.Marshal(v.List) - case v.Str != nil: - return json.Marshal(strings.Trim(*v.Str, `"`)) - case v.Null != nil: - return json.Marshal(nil) - case v.Assignment != nil: - return json.Marshal(v.Assignment) - case v.Float != nil: - return json.Marshal(*v.Float) - case v.Int != nil: - return json.Marshal(*v.Int) - case v.Object != nil: - m := make(map[string]interface{}) - for _, assignment := range *v.Object { - m[assignment.Name] = assignment.Value - } - return json.Marshal(m) - case v.Ident != nil: - return json.Marshal(v.Ident) - } - return json.Marshal([]*Value{}) -} - -func (f *Ap) MarshalJSON() ([]byte, error) { - m := make(map[string]interface{}) - args := make(map[string]interface{}) - for _, argument := range f.Arguments { - switch { - case argument.Assignment != nil: - args[argument.Assignment.Name] = argument.Assignment.Value - default: - return nil, fmt.Errorf("Cannot marshal %v (arg %v)", f, argument) - } - } - m[f.Name] = args - return json.Marshal(m) -} - -func (i *In) MarshalJSON() ([]byte, error) { - switch { - case i.FuncCall != nil: - return json.Marshal(i.FuncCall) - case i.Name != nil: - return json.Marshal("$" + *i.Name) - } - return nil, fmt.Errorf("Cannot marshal %v", i) -} diff --git a/pkg/buildscript/internal/buildexpression/buildexpression_test.go b/pkg/buildscript/internal/buildexpression/buildexpression_test.go deleted file mode 100644 index b429670d96..0000000000 --- a/pkg/buildscript/internal/buildexpression/buildexpression_test.go +++ /dev/null @@ -1,531 +0,0 @@ -package buildexpression - -import ( - "path/filepath" - "reflect" - "sort" - "testing" - - "github.com/ActiveState/cli/internal/environment" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestNew(t *testing.T) { - type args struct { - filename string - } - tests := []struct { - name string - args args - wantErr bool - }{ - { - name: "basic", - args: args{ - filename: "buildexpression.json", - }, - wantErr: false, - }, - { - name: "complex", - args: args{ - filename: "buildexpression-complex.json", - }, - wantErr: false, - }, - { - name: "unordered", - args: args{ - filename: "buildexpression-unordered.json", - }, - wantErr: false, - }, - { - name: "installer", - args: args{ - filename: "buildexpression-installer.json", - }, - wantErr: false, - }, - { - name: "installer-complex", - args: args{ - filename: "buildexpression-installer-complex.json", - }, - wantErr: false, - }, - { - name: "nested", - args: args{ - filename: "buildexpression-nested.json", - }, - wantErr: false, - }, - { - name: "alternate", - args: args{ - filename: "buildexpression-alternate.json", - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - wd, err := environment.GetRootPath() - assert.NoError(t, err) - - data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "buildscript", "internal", "buildexpression", "testdata", tt.args.filename)) - assert.NoError(t, err) - - _, err = Unmarshal(data) - if (err != nil) != tt.wantErr { - t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr) - return - } - }) - } -} - -func TestRequirements(t *testing.T) { - type args struct { - filename string - } - tests := []struct { - name string - args args - want []types.Requirement - wantErr bool - }{ - { - name: "basic", - args: args{ - filename: "buildexpression.json", - }, - want: []types.Requirement{ - { - Name: "jinja2-time", - Namespace: "language/python", - }, - { - Name: "jupyter-contrib-nbextensions", - Namespace: "language/python", - }, - { - Name: "python", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "3.10.10", - }, - }, - }, - { - Name: "copier", - Namespace: "language/python", - }, - { - Name: "jupyterlab", - Namespace: "language/python", - }, - }, - wantErr: false, - }, - { - name: "installer-complex", - args: args{ - filename: "buildexpression-installer-complex.json", - }, - want: []types.Requirement{ - { - Name: "perl", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "5.36.0", - }, - }, - }, - }, - wantErr: false, - }, - { - name: "alternate", - args: args{ - filename: "buildexpression-alternate.json", - }, - want: []types.Requirement{ - { - Name: "Path-Tiny", - Namespace: "language/perl", - }, - { - Name: "perl", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "5.36.1", - }, - }, - }, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - wd, err := environment.GetRootPath() - assert.NoError(t, err) - - data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "buildscript", "internal", "buildexpression", "testdata", tt.args.filename)) - assert.NoError(t, err) - - bx, err := Unmarshal(data) - assert.NoError(t, err) - - got, err := bx.Requirements() - assert.NoError(t, err) - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("BuildExpression.Requirements() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestUpdate(t *testing.T) { - type args struct { - requirement types.Requirement - operation types.Operation - filename string - } - tests := []struct { - name string - args args - want []types.Requirement - wantErr bool - }{ - { - name: "add", - args: args{ - requirement: types.Requirement{ - Name: "requests", - Namespace: "language/python", - }, - operation: types.OperationAdded, - filename: "buildexpression.json", - }, - want: []types.Requirement{ - { - Name: "jinja2-time", - Namespace: "language/python", - }, - { - Name: "jupyter-contrib-nbextensions", - Namespace: "language/python", - }, - { - Name: "python", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "3.10.10", - }, - }, - }, - { - Name: "copier", - Namespace: "language/python", - }, - { - Name: "jupyterlab", - Namespace: "language/python", - }, - { - Name: "requests", - Namespace: "language/python", - }, - }, - wantErr: false, - }, - { - name: "remove", - args: args{ - requirement: types.Requirement{ - Name: "jupyterlab", - Namespace: "language/python", - }, - operation: types.OperationRemoved, - filename: "buildexpression.json", - }, - want: []types.Requirement{ - { - Name: "jinja2-time", - Namespace: "language/python", - }, - { - Name: "jupyter-contrib-nbextensions", - Namespace: "language/python", - }, - { - Name: "python", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "3.10.10", - }, - }, - }, - { - Name: "copier", - Namespace: "language/python", - }, - }, - wantErr: false, - }, - { - name: "update", - args: args{ - requirement: types.Requirement{ - Name: "python", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "3.11.0", - }, - }, - }, - operation: types.OperationUpdated, - filename: "buildexpression.json", - }, - want: []types.Requirement{ - { - Name: "jinja2-time", - Namespace: "language/python", - }, - { - Name: "jupyter-contrib-nbextensions", - Namespace: "language/python", - }, - { - Name: "python", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "3.11.0", - }, - }, - }, - { - Name: "copier", - Namespace: "language/python", - }, - { - Name: "jupyterlab", - Namespace: "language/python", - }, - }, - wantErr: false, - }, - { - name: "remove not existing", - args: args{ - requirement: types.Requirement{ - Name: "requests", - Namespace: "language/python", - }, - operation: types.OperationRemoved, - filename: "buildexpression.json", - }, - want: []types.Requirement{ - { - Name: "jinja2-time", - Namespace: "language/python", - }, - { - Name: "jupyter-contrib-nbextensions", - Namespace: "language/python", - }, - { - Name: "python", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "3.10.10", - }, - }, - }, - { - Name: "copier", - Namespace: "language/python", - }, - { - Name: "jupyterlab", - Namespace: "language/python", - }, - }, - wantErr: true, - }, - { - name: "add-installer-complex", - args: args{ - requirement: types.Requirement{ - Name: "JSON", - Namespace: "language/perl", - }, - operation: types.OperationAdded, - filename: "buildexpression-installer-complex.json", - }, - want: []types.Requirement{ - { - Name: "perl", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "5.36.0", - }, - }, - }, - { - Name: "JSON", - Namespace: "language/perl", - }, - }, - wantErr: false, - }, - { - name: "add-alternate", - args: args{ - requirement: types.Requirement{ - Name: "JSON", - Namespace: "language/perl", - }, - operation: types.OperationAdded, - filename: "buildexpression-alternate.json", - }, - want: []types.Requirement{ - { - Name: "Path-Tiny", - Namespace: "language/perl", - }, - { - Name: "perl", - Namespace: "language", - VersionRequirement: []types.VersionRequirement{ - map[string]string{ - "comparator": string(types.ComparatorEQ), - "version": "5.36.1", - }, - }, - }, - { - Name: "JSON", - Namespace: "language/perl", - }, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - wd, err := environment.GetRootPath() - assert.NoError(t, err) - - data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "buildscript", "internal", "buildexpression", "testdata", tt.args.filename)) - assert.NoError(t, err) - - bx, err := Unmarshal(data) - assert.NoError(t, err) - - err = bx.UpdateRequirement(tt.args.operation, tt.args.requirement) - if err != nil { - if tt.wantErr { - return - } - - t.Errorf("BuildExpression.Update() error = %v, wantErr %v", err, tt.wantErr) - return - } - - got, err := bx.Requirements() - assert.NoError(t, err) - - sort.Slice(got, func(i, j int) bool { - return got[i].Name < got[j].Name - }) - - sort.Slice(tt.want, func(i, j int) bool { - return tt.want[i].Name < tt.want[j].Name - }) - - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("BuildExpression.Requirements() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestNullValue(t *testing.T) { - be, err := Unmarshal([]byte(` -{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "solver_version": null - } - } - } -} -`)) - require.NoError(t, err) - - var null *string - nullHandled := false - for _, assignment := range be.Let.Assignments { - if assignment.Name == "runtime" { - args := assignment.Value.Ap.Arguments - require.NotNil(t, args) - for _, arg := range args { - if arg.Assignment != nil && arg.Assignment.Name == "solver_version" { - assert.Equal(t, null, arg.Assignment.Value.Str) - nullHandled = true - } - } - } - } - assert.True(t, nullHandled, "JSON null not encountered") -} - -func TestCopy(t *testing.T) { - be, err := Unmarshal([]byte(` -{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "platforms": [], - "requirements": [], - "solver_version": null - } - } - } -} -`)) - require.NoError(t, err) - be2, err := be.Copy() - require.NoError(t, err) - require.Equal(t, be, be2) -} diff --git a/pkg/buildscript/internal/buildexpression/merge.go b/pkg/buildscript/internal/buildexpression/merge.go deleted file mode 100644 index 3cd5bfd15b..0000000000 --- a/pkg/buildscript/internal/buildexpression/merge.go +++ /dev/null @@ -1,122 +0,0 @@ -package buildexpression - -import ( - "encoding/json" - "reflect" - - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" -) - -func Merge(exprA *BuildExpression, exprB *BuildExpression, strategies *mono_models.MergeStrategies) (*BuildExpression, error) { - if !isAutoMergePossible(exprA, exprB) { - return nil, errs.New("Unable to merge buildexpressions") - } - if len(strategies.Conflicts) > 0 { - return nil, errs.New("Unable to merge buildexpressions due to conflicting requirements") - } - - // Update build expression requirements with merge results. - for _, req := range strategies.OverwriteChanges { - var op types.Operation - err := op.Unmarshal(req.Operation) - if err != nil { - return nil, errs.Wrap(err, "Unable to convert requirement operation to buildplan operation") - } - - var versionRequirements []types.VersionRequirement - for _, constraint := range req.VersionConstraints { - data, err := constraint.MarshalBinary() - if err != nil { - return nil, errs.Wrap(err, "Could not marshal requirement version constraints") - } - m := make(map[string]string) - err = json.Unmarshal(data, &m) - if err != nil { - return nil, errs.Wrap(err, "Could not unmarshal requirement version constraints") - } - versionRequirements = append(versionRequirements, m) - } - - bpReq := types.Requirement{ - Name: req.Requirement, - Namespace: req.Namespace, - VersionRequirement: versionRequirements, - } - - if err := exprB.UpdateRequirement(op, bpReq); err != nil { - return nil, errs.Wrap(err, "Unable to update buildexpression with merge results") - } - } - - return exprB, nil -} - -// isAutoMergePossible determines whether or not it is possible to auto-merge the given build -// expressions. -// This is only possible if the two build expressions differ ONLY in requirements. -func isAutoMergePossible(exprA *BuildExpression, exprB *BuildExpression) bool { - jsonA, err := getComparableJson(exprA) - if err != nil { - multilog.Error("Unable to get buildexpression minus requirements: %v", errs.JoinMessage(err)) - return false - } - jsonB, err := getComparableJson(exprB) - if err != nil { - multilog.Error("Unable to get buildxpression minus requirements: %v", errs.JoinMessage(err)) - return false - } - logging.Debug("Checking for possibility of auto-merging build expressions") - logging.Debug("JsonA: %v", jsonA) - logging.Debug("JsonB: %v", jsonB) - return reflect.DeepEqual(jsonA, jsonB) -} - -// getComparableJson returns a comparable JSON map[string]interface{} structure for the given build -// expression. The map will not have a "requirements" field, nor will it have an "at_time" field. -// String lists will also be sorted. -func getComparableJson(expr *BuildExpression) (map[string]interface{}, error) { - data, err := json.Marshal(expr) - if err != nil { - return nil, errs.New("Unable to unmarshal marshaled buildxpression") - } - - m := make(map[string]interface{}) - err = json.Unmarshal(data, &m) - if err != nil { - return nil, errs.New("Unable to unmarshal marshaled buildxpression") - } - - letValue, ok := m["let"] - if !ok { - return nil, errs.New("Build expression has no 'let' key") - } - letMap, ok := letValue.(map[string]interface{}) - if !ok { - return nil, errs.New("'let' key is not a JSON object") - } - deleteKey(&letMap, "requirements") - deleteKey(&letMap, "at_time") - - return m, nil -} - -// deleteKey recursively iterates over the given JSON map until it finds the given key and deletes -// it and its value. -func deleteKey(m *map[string]interface{}, key string) bool { - for k, v := range *m { - if k == key { - delete(*m, k) - return true - } - if m2, ok := v.(map[string]interface{}); ok { - if deleteKey(&m2, key) { - return true - } - } - } - return false -} diff --git a/pkg/buildscript/internal/buildexpression/merge_test.go b/pkg/buildscript/internal/buildexpression/merge_test.go deleted file mode 100644 index 09b231dce7..0000000000 --- a/pkg/buildscript/internal/buildexpression/merge_test.go +++ /dev/null @@ -1,278 +0,0 @@ -package buildexpression - -import ( - "encoding/json" - "testing" - - "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestMergeAdd(t *testing.T) { - exprA, err := Unmarshal([]byte(` -{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "platforms": [ - "12345", - "67890" - ], - "requirements": [ - { - "name": "perl", - "namespace": "language" - }, - { - "name": "DateTime", - "namespace": "language/perl" - } - ] - } - } - } -} -`)) - require.NoError(t, err) - - exprB, err := Unmarshal([]byte(` -{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "platforms": [ - "12345", - "67890" - ], - "requirements": [ - { - "name": "perl", - "namespace": "language" - }, - { - "name": "JSON", - "namespace": "language/perl" - } - ] - } - } - } -} -`)) - require.NoError(t, err) - - strategies := &mono_models.MergeStrategies{ - OverwriteChanges: []*mono_models.CommitChangeEditable{ - {Namespace: "language/perl", Requirement: "DateTime", Operation: mono_models.CommitChangeEditableOperationAdded}, - }, - } - - require.True(t, isAutoMergePossible(exprA, exprB)) - - mergedExpr, err := Merge(exprA, exprB, strategies) - require.NoError(t, err) - - v, err := json.MarshalIndent(mergedExpr, "", " ") - require.NoError(t, err) - - assert.Equal(t, - `{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "platforms": [ - "12345", - "67890" - ], - "requirements": [ - { - "name": "perl", - "namespace": "language" - }, - { - "name": "JSON", - "namespace": "language/perl" - }, - { - "name": "DateTime", - "namespace": "language/perl" - } - ] - } - } - } -}`, string(v)) -} - -func TestMergeRemove(t *testing.T) { - exprA, err := Unmarshal([]byte(` -{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "platforms": [ - "12345", - "67890" - ], - "requirements": [ - { - "name": "perl", - "namespace": "language" - }, - { - "name": "DateTime", - "namespace": "language/perl" - } - ] - } - } - } -} -`)) - require.NoError(t, err) - - exprB, err := Unmarshal([]byte(` -{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "platforms": [ - "12345", - "67890" - ], - "requirements": [ - { - "name": "perl", - "namespace": "language" - }, - { - "name": "JSON", - "namespace": "language/perl" - }, - { - "name": "DateTime", - "namespace": "language/perl" - } - ] - } - } - } -} -`)) - - strategies := &mono_models.MergeStrategies{ - OverwriteChanges: []*mono_models.CommitChangeEditable{ - {Namespace: "language/perl", Requirement: "JSON", Operation: mono_models.CommitChangeEditableOperationRemoved}, - }, - } - - require.True(t, isAutoMergePossible(exprA, exprB)) - - mergedExpr, err := Merge(exprA, exprB, strategies) - require.NoError(t, err) - - v, err := json.MarshalIndent(mergedExpr, "", " ") - require.NoError(t, err) - - assert.Equal(t, - `{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "platforms": [ - "12345", - "67890" - ], - "requirements": [ - { - "name": "perl", - "namespace": "language" - }, - { - "name": "DateTime", - "namespace": "language/perl" - } - ] - } - } - } -}`, string(v)) -} - -func TestMergeConflict(t *testing.T) { - exprA, err := Unmarshal([]byte(` -{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "platforms": [ - "12345", - "67890" - ], - "requirements": [ - { - "name": "perl", - "namespace": "language" - } - ] - } - } - } -} -`)) - require.NoError(t, err) - - exprB, err := Unmarshal([]byte(` -{ - "let": { - "in": "$runtime", - "runtime": { - "solve": { - "at_time": "$at_time", - "platforms": [ - "12345" - ], - "requirements": [ - { - "name": "perl", - "namespace": "language" - }, - { - "name": "JSON", - "namespace": "language/perl" - } - ] - } - } - } -} -`)) - require.NoError(t, err) - - assert.False(t, isAutoMergePossible(exprA, exprB)) // platforms do not match - - _, err = Merge(exprA, exprB, nil) - require.Error(t, err) -} - -func TestDeleteKey(t *testing.T) { - m := map[string]interface{}{"foo": map[string]interface{}{"bar": "baz", "quux": "foobar"}} - assert.True(t, deleteKey(&m, "quux"), "did not find quux") - _, exists := m["foo"].(map[string]interface{})["quux"] - assert.False(t, exists, "did not delete quux") -} diff --git a/pkg/buildscript/internal/raw/interpretation.go b/pkg/buildscript/internal/raw/interpretation.go deleted file mode 100644 index 19876d23db..0000000000 --- a/pkg/buildscript/internal/raw/interpretation.go +++ /dev/null @@ -1,32 +0,0 @@ -package raw - -import ( - "strings" - "time" - - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/go-openapi/strfmt" -) - -func (r *Raw) hydrate() error { - // Locate the AtTime key and define it at the top level for easier access, and to raise errors at hydrate (ie. unmarshal) time - for _, assignment := range r.Assignments { - key := assignment.Key - value := assignment.Value - if key != AtTimeKey { - continue - } - if value.Str == nil { - return nil - } - atTime, err := strfmt.ParseDateTime(strings.Trim(*value.Str, `"`)) - if err != nil { - return errs.Wrap(err, "Invalid timestamp: %s", *value.Str) - } - r.AtTime = ptr.To(time.Time(atTime)) - return nil - } - - return nil -} diff --git a/pkg/buildscript/internal/raw/marshal.go b/pkg/buildscript/internal/raw/marshal.go deleted file mode 100644 index 717a5f246c..0000000000 --- a/pkg/buildscript/internal/raw/marshal.go +++ /dev/null @@ -1,101 +0,0 @@ -package raw - -import ( - "encoding/json" - "errors" - "strings" - "time" - - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/ActiveState/cli/pkg/buildscript/internal/buildexpression" - "github.com/alecthomas/participle/v2" - "github.com/go-openapi/strfmt" -) - -// Marshal converts our Raw structure into a the ascript format -func (r *Raw) Marshal() ([]byte, error) { - be, err := r.MarshalBuildExpression() - if err != nil { - return nil, errs.Wrap(err, "Could not marshal build expression") - } - - expr, err := buildexpression.Unmarshal(be) - if err != nil { - return nil, errs.Wrap(err, "Could not unmarshal build expression") - } - - return []byte(marshalFromBuildExpression(expr, r.AtTime)), nil -} - -// MarshalBuildExpression converts our Raw structure into a build expression structure -func (r *Raw) MarshalBuildExpression() ([]byte, error) { - return json.MarshalIndent(r, "", " ") -} - -// Unmarshal converts our ascript format into a Raw structure -func Unmarshal(data []byte) (*Raw, error) { - parser, err := participle.Build[Raw]() - if err != nil { - return nil, errs.Wrap(err, "Could not create parser for build script") - } - - r, err := parser.ParseBytes(constants.BuildScriptFileName, data) - if err != nil { - var parseError participle.Error - if errors.As(err, &parseError) { - return nil, locale.WrapExternalError(err, "err_parse_buildscript_bytes", "Could not parse build script: {{.V0}}: {{.V1}}", parseError.Position().String(), parseError.Message()) - } - return nil, locale.WrapError(err, "err_parse_buildscript_bytes", "Could not parse build script: {{.V0}}", err.Error()) - } - - if err := r.hydrate(); err != nil { - return nil, errs.Wrap(err, "Could not hydrate raw build script") - } - - return r, nil -} - -// UnmarshalBuildExpression converts a build expression into our raw structure -func UnmarshalBuildExpression(expr *buildexpression.BuildExpression, atTime *time.Time) (*Raw, error) { - return Unmarshal([]byte(marshalFromBuildExpression(expr, atTime))) -} - -// marshalFromBuildExpression is a bit special in that it is sort of an unmarshaller and a marshaller at the same time. -// It takes a build expression and directly translates it into the string representation of a build script. -// We should update this so that this instead translates the build expression directly to the in-memory representation -// of a buildscript (ie. the Raw structure). But that is a large refactor in and of itself that'll follow later. -// For now we can use this to convert a build expression to a buildscript with an extra hop where we have to unmarshal -// the resulting buildscript string. -func marshalFromBuildExpression(expr *buildexpression.BuildExpression, atTime *time.Time) string { - buf := strings.Builder{} - - if atTime != nil { - buf.WriteString(assignmentString(&buildexpression.Var{ - Name: buildexpression.AtTimeKey, - Value: &buildexpression.Value{Str: ptr.To(atTime.Format(strfmt.RFC3339Millis))}, - })) - buf.WriteString("\n") - } - - for _, assignment := range expr.Let.Assignments { - if assignment.Name == buildexpression.RequirementsKey { - assignment = transformRequirements(assignment) - } - buf.WriteString(assignmentString(assignment)) - buf.WriteString("\n") - } - - buf.WriteString("\n") - buf.WriteString("main = ") - switch { - case expr.Let.In.FuncCall != nil: - buf.WriteString(apString(expr.Let.In.FuncCall)) - case expr.Let.In.Name != nil: - buf.WriteString(*expr.Let.In.Name) - } - - return buf.String() -} diff --git a/pkg/buildscript/internal/raw/raw_test.go b/pkg/buildscript/internal/raw/raw_test.go deleted file mode 100644 index 400493aaf4..0000000000 --- a/pkg/buildscript/internal/raw/raw_test.go +++ /dev/null @@ -1,288 +0,0 @@ -package raw - -import ( - "testing" - "time" - - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/go-openapi/strfmt" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestRawRepresentation(t *testing.T) { - raw, err := Unmarshal([]byte( - `at_time = "2000-01-01T00:00:00.000Z" -runtime = solve( - at_time = at_time, - platforms = ["linux", "windows"], - requirements = [ - Req(name = "python", namespace = "language"), - Req(name = "requests", namespace = "language/python", version = Eq(value = "3.10.10")) - ] -) - -main = runtime -`)) - require.NoError(t, err) - - atTimeStrfmt, err := strfmt.ParseDateTime("2000-01-01T00:00:00.000Z") - require.NoError(t, err) - atTime := time.Time(atTimeStrfmt) - - assert.Equal(t, &Raw{ - []*Assignment{ - {"at_time", &Value{Str: ptr.To(`"2000-01-01T00:00:00.000Z"`)}}, - {"runtime", &Value{ - FuncCall: &FuncCall{"solve", []*Value{ - {Assignment: &Assignment{"at_time", &Value{Ident: ptr.To(`at_time`)}}}, - {Assignment: &Assignment{ - "platforms", &Value{List: &[]*Value{ - {Str: ptr.To(`"linux"`)}, - {Str: ptr.To(`"windows"`)}, - }}, - }}, - {Assignment: &Assignment{ - "requirements", &Value{List: &[]*Value{ - {FuncCall: &FuncCall{ - Name: "Req", - Arguments: []*Value{ - {Assignment: &Assignment{ - "name", &Value{Str: ptr.To(`"python"`)}, - }}, - {Assignment: &Assignment{ - "namespace", &Value{Str: ptr.To(`"language"`)}, - }}, - }}}, - {FuncCall: &FuncCall{ - Name: "Req", - Arguments: []*Value{ - {Assignment: &Assignment{ - "name", &Value{Str: ptr.To(`"requests"`)}, - }}, - {Assignment: &Assignment{ - "namespace", &Value{Str: ptr.To(`"language/python"`)}, - }}, - {Assignment: &Assignment{ - "version", &Value{FuncCall: &FuncCall{ - Name: "Eq", - Arguments: []*Value{ - {Assignment: &Assignment{Key: "value", Value: &Value{Str: ptr.To(`"3.10.10"`)}}}, - }, - }}, - }}, - }, - }}, - }}, - }}, - }}, - }}, - {"main", &Value{Ident: ptr.To("runtime")}}, - }, - &atTime, - }, raw) -} - -func TestComplex(t *testing.T) { - raw, err := Unmarshal([]byte( - `at_time = "2000-01-01T00:00:00.000Z" -linux_runtime = solve( - at_time = at_time, - requirements=[ - Req(name = "python", namespace = "language") - ], - platforms=["67890"] -) - -win_runtime = solve( - at_time = at_time, - requirements=[ - Req(name = "perl", namespace = "language") - ], - platforms=["12345"] -) - -main = merge( - win_installer(win_runtime), - tar_installer(linux_runtime) -) -`)) - require.NoError(t, err) - - atTimeStrfmt, err := strfmt.ParseDateTime("2000-01-01T00:00:00.000Z") - require.NoError(t, err) - atTime := time.Time(atTimeStrfmt) - - assert.Equal(t, &Raw{ - []*Assignment{ - {"at_time", &Value{Str: ptr.To(`"2000-01-01T00:00:00.000Z"`)}}, - {"linux_runtime", &Value{ - FuncCall: &FuncCall{"solve", []*Value{ - {Assignment: &Assignment{"at_time", &Value{Ident: ptr.To(`at_time`)}}}, - {Assignment: &Assignment{ - "requirements", &Value{List: &[]*Value{ - {FuncCall: &FuncCall{ - Name: "Req", - Arguments: []*Value{ - {Assignment: &Assignment{ - "name", &Value{Str: ptr.To(`"python"`)}, - }}, - {Assignment: &Assignment{ - "namespace", &Value{Str: ptr.To(`"language"`)}, - }}, - }, - }}, - }}, - }}, - {Assignment: &Assignment{ - "platforms", &Value{List: &[]*Value{ - {Str: ptr.To(`"67890"`)}}, - }, - }}, - }}, - }}, - {"win_runtime", &Value{ - FuncCall: &FuncCall{"solve", []*Value{ - {Assignment: &Assignment{"at_time", &Value{Ident: ptr.To(`at_time`)}}}, - {Assignment: &Assignment{ - "requirements", &Value{List: &[]*Value{ - {FuncCall: &FuncCall{ - Name: "Req", - Arguments: []*Value{ - {Assignment: &Assignment{ - "name", &Value{Str: ptr.To(`"perl"`)}, - }}, - {Assignment: &Assignment{ - "namespace", &Value{Str: ptr.To(`"language"`)}, - }}, - }, - }}, - }}, - }}, - {Assignment: &Assignment{ - "platforms", &Value{List: &[]*Value{ - {Str: ptr.To(`"12345"`)}}, - }, - }}, - }}, - }}, - {"main", &Value{ - FuncCall: &FuncCall{"merge", []*Value{ - {FuncCall: &FuncCall{"win_installer", []*Value{{Ident: ptr.To("win_runtime")}}}}, - {FuncCall: &FuncCall{"tar_installer", []*Value{{Ident: ptr.To("linux_runtime")}}}}, - }}}}, - }, - &atTime, - }, raw) -} - -const buildscriptWithComplexVersions = `at_time = "2023-04-27T17:30:05.999Z" -runtime = solve( - at_time = at_time, - platforms = ["96b7e6f2-bebf-564c-bc1c-f04482398f38", "96b7e6f2-bebf-564c-bc1c-f04482398f38"], - requirements = [ - Req(name = "python", namespace = "language"), - Req(name = "requests", namespace = "language/python", version = Eq(value = "3.10.10")), - Req(name = "argparse", namespace = "language/python", version = And(left = Gt(value = "1.0"), right = Lt(value = "2.0"))) - ], - solver_version = 0 -) - -main = runtime` - -func TestComplexVersions(t *testing.T) { - raw, err := Unmarshal([]byte(buildscriptWithComplexVersions)) - require.NoError(t, err) - - atTimeStrfmt, err := strfmt.ParseDateTime("2023-04-27T17:30:05.999Z") - require.NoError(t, err) - atTime := time.Time(atTimeStrfmt) - - assert.Equal(t, &Raw{ - []*Assignment{ - {"at_time", &Value{Str: ptr.To(`"2023-04-27T17:30:05.999Z"`)}}, - {"runtime", &Value{ - FuncCall: &FuncCall{"solve", []*Value{ - {Assignment: &Assignment{ - "at_time", &Value{Ident: ptr.To(`at_time`)}, - }}, - {Assignment: &Assignment{ - "platforms", &Value{List: &[]*Value{ - {Str: ptr.To(`"96b7e6f2-bebf-564c-bc1c-f04482398f38"`)}, - {Str: ptr.To(`"96b7e6f2-bebf-564c-bc1c-f04482398f38"`)}, - }}, - }}, - {Assignment: &Assignment{ - "requirements", &Value{List: &[]*Value{ - {FuncCall: &FuncCall{ - Name: "Req", - Arguments: []*Value{ - {Assignment: &Assignment{ - "name", &Value{Str: ptr.To(`"python"`)}, - }}, - {Assignment: &Assignment{ - "namespace", &Value{Str: ptr.To(`"language"`)}, - }}, - }, - }}, - {FuncCall: &FuncCall{ - Name: "Req", - Arguments: []*Value{ - {Assignment: &Assignment{ - "name", &Value{Str: ptr.To(`"requests"`)}, - }}, - {Assignment: &Assignment{ - "namespace", &Value{Str: ptr.To(`"language/python"`)}, - }}, - {Assignment: &Assignment{ - "version", &Value{FuncCall: &FuncCall{ - Name: "Eq", - Arguments: []*Value{ - {Assignment: &Assignment{Key: "value", Value: &Value{Str: ptr.To(`"3.10.10"`)}}}, - }, - }}, - }}, - }, - }}, - {FuncCall: &FuncCall{ - Name: "Req", - Arguments: []*Value{ - {Assignment: &Assignment{ - "name", &Value{Str: ptr.To(`"argparse"`)}, - }}, - {Assignment: &Assignment{ - "namespace", &Value{Str: ptr.To(`"language/python"`)}, - }}, - {Assignment: &Assignment{ - "version", &Value{FuncCall: &FuncCall{ - Name: "And", - Arguments: []*Value{ - {Assignment: &Assignment{Key: "left", Value: &Value{FuncCall: &FuncCall{ - Name: "Gt", - Arguments: []*Value{ - {Assignment: &Assignment{Key: "value", Value: &Value{Str: ptr.To(`"1.0"`)}}}, - }, - }}}}, - {Assignment: &Assignment{Key: "right", Value: &Value{FuncCall: &FuncCall{ - Name: "Lt", - Arguments: []*Value{ - {Assignment: &Assignment{Key: "value", Value: &Value{Str: ptr.To(`"2.0"`)}}}, - }, - }}}}, - }, - }}, - }}, - }, - }}, - }}, - }}, - {Assignment: &Assignment{ - "solver_version", &Value{Number: ptr.To(float64(0))}, - }}, - }}, - }}, - {"main", &Value{Ident: ptr.To("runtime")}}, - }, - &atTime, - }, raw) -} diff --git a/pkg/buildscript/internal/raw/structure.go b/pkg/buildscript/internal/raw/structure.go deleted file mode 100644 index d33eae430b..0000000000 --- a/pkg/buildscript/internal/raw/structure.go +++ /dev/null @@ -1,57 +0,0 @@ -package raw - -import ( - "time" -) - -// Raw 's tagged fields will be initially filled in by Participle. -// expr will be constructed later and is this script's buildexpression. We keep a copy of the build -// expression here with any changes that have been applied before either writing it to disk or -// submitting it to the build planner. It's easier to operate on build expressions directly than to -// modify or manually populate the Participle-produced fields and re-generate a build expression. -type Raw struct { - Assignments []*Assignment `parser:"@@+"` - AtTime *time.Time -} - -type Assignment struct { - Key string `parser:"@Ident '='"` - Value *Value `parser:"@@"` -} - -type Value struct { - FuncCall *FuncCall `parser:"@@"` - List *[]*Value `parser:"| '[' (@@ (',' @@)* ','?)? ']'"` - Str *string `parser:"| @String"` - Number *float64 `parser:"| (@Float | @Int)"` - Null *Null `parser:"| @@"` - - Assignment *Assignment `parser:"| @@"` // only in FuncCall - Object *[]*Assignment `parser:"| '{' @@ (',' @@)* ','? '}'"` // only in List - Ident *string `parser:"| @Ident"` // only in FuncCall or Assignment -} - -type Null struct { - Null string `parser:"'null'"` -} - -type FuncCall struct { - Name string `parser:"@Ident"` - Arguments []*Value `parser:"'(' @@ (',' @@)* ','? ')'"` -} - -type In struct { - FuncCall *FuncCall `parser:"@@"` - Name *string `parser:"| @Ident"` -} - -var ( - reqFuncName = "Req" - eqFuncName = "Eq" - neFuncName = "Ne" - gtFuncName = "Gt" - gteFuncName = "Gte" - ltFuncName = "Lt" - lteFuncName = "Lte" - andFuncName = "And" -) diff --git a/pkg/buildscript/internal/raw/transforms.go b/pkg/buildscript/internal/raw/transforms.go deleted file mode 100644 index 688a248700..0000000000 --- a/pkg/buildscript/internal/raw/transforms.go +++ /dev/null @@ -1,224 +0,0 @@ -package raw - -import ( - "bytes" - "fmt" - "strconv" - "strings" - - "github.com/ActiveState/cli/pkg/buildscript/internal/buildexpression" - "github.com/thoas/go-funk" - "golang.org/x/text/cases" - "golang.org/x/text/language" -) - -func indent(s string) string { - return fmt.Sprintf("\t%s", strings.ReplaceAll(s, "\n", "\n\t")) -} - -// transformRequirements transforms a buildexpression list of requirements in object form into a -// list of requirements in function-call form, which is how requirements are represented in -// buildscripts. -// This is to avoid custom marshaling code and reuse existing marshaling code. -func transformRequirements(reqs *buildexpression.Var) *buildexpression.Var { - newReqs := &buildexpression.Var{ - Name: buildexpression.RequirementsKey, - Value: &buildexpression.Value{ - List: &[]*buildexpression.Value{}, - }, - } - - for _, req := range *reqs.Value.List { - *newReqs.Value.List = append(*newReqs.Value.List, transformRequirement(req)) - } - - return newReqs -} - -// transformRequirement transforms a buildexpression requirement in object form into a requirement -// in function-call form. -// For example, transform something like -// -// {"name": "", "namespace": "", -// "version_requirements": [{"comparator": "", "version": ""}]} -// -// into something like -// -// Req(name = "", namespace = "", version = (value = "")) -func transformRequirement(req *buildexpression.Value) *buildexpression.Value { - newReq := &buildexpression.Value{ - Ap: &buildexpression.Ap{ - Name: reqFuncName, - Arguments: []*buildexpression.Value{}, - }, - } - - for _, arg := range *req.Object { - name := arg.Name - value := arg.Value - - // Transform the version value from the requirement object. - if name == buildexpression.RequirementVersionRequirementsKey { - name = buildexpression.RequirementVersionKey - value = &buildexpression.Value{Ap: transformVersion(arg)} - } - - // Add the argument to the function transformation. - newReq.Ap.Arguments = append(newReq.Ap.Arguments, &buildexpression.Value{ - Assignment: &buildexpression.Var{Name: name, Value: value}, - }) - } - - return newReq -} - -// transformVersion transforms a buildexpression version_requirements list in object form into -// function-call form. -// For example, transform something like -// -// [{"comparator": "", "version": ""}, {"comparator": "", "version": ""}] -// -// into something like -// -// And((value = ""), (value = "")) -func transformVersion(requirements *buildexpression.Var) *buildexpression.Ap { - var aps []*buildexpression.Ap - for _, constraint := range *requirements.Value.List { - ap := &buildexpression.Ap{} - for _, o := range *constraint.Object { - switch o.Name { - case buildexpression.RequirementVersionKey: - ap.Arguments = []*buildexpression.Value{{ - Assignment: &buildexpression.Var{Name: "value", Value: &buildexpression.Value{Str: o.Value.Str}}, - }} - case buildexpression.RequirementComparatorKey: - ap.Name = cases.Title(language.English).String(*o.Value.Str) - } - } - aps = append(aps, ap) - } - - if len(aps) == 1 { - return aps[0] // e.g. Eq(value = "1.0") - } - - // e.g. And(left = Gt(value = "1.0"), right = Lt(value = "3.0")) - // Iterate backwards over the requirements array and construct a binary tree of 'And()' functions. - // For example, given [Gt(value = "1.0"), Ne(value = "2.0"), Lt(value = "3.0")], produce: - // And(left = Gt(value = "1.0"), right = And(left = Ne(value = "2.0"), right = Lt(value = "3.0"))) - var ap *buildexpression.Ap - for i := len(aps) - 2; i >= 0; i-- { - right := &buildexpression.Value{Ap: aps[i+1]} - if ap != nil { - right = &buildexpression.Value{Ap: ap} - } - args := []*buildexpression.Value{ - {Assignment: &buildexpression.Var{Name: "left", Value: &buildexpression.Value{Ap: aps[i]}}}, - {Assignment: &buildexpression.Var{Name: "right", Value: right}}, - } - ap = &buildexpression.Ap{Name: andFuncName, Arguments: args} - } - return ap -} - -func assignmentString(a *buildexpression.Var) string { - if a.Name == buildexpression.RequirementsKey { - a = transformRequirements(a) - } - return fmt.Sprintf("%s = %s", a.Name, valueString(a.Value)) -} - -func valueString(v *buildexpression.Value) string { - switch { - case v.Ap != nil: - return apString(v.Ap) - - case v.List != nil: - buf := bytes.Buffer{} - buf.WriteString("[\n") - for i, item := range *v.List { - buf.WriteString(indent(valueString(item))) - if i+1 < len(*v.List) { - buf.WriteString(",") - } - buf.WriteString("\n") - } - buf.WriteString("]") - return buf.String() - - case v.Str != nil: - if strings.HasPrefix(*v.Str, "$") { // variable reference - return strings.TrimLeft(*v.Str, "$") - } - return strconv.Quote(*v.Str) - - case v.Float != nil: - return strconv.FormatFloat(*v.Float, 'G', -1, 64) // 64-bit float with minimum digits on display - - case v.Null != nil: - return "null" - - case v.Assignment != nil: - return assignmentString(v.Assignment) - - case v.Object != nil: - buf := bytes.Buffer{} - buf.WriteString("{\n") - for i, pair := range *v.Object { - buf.WriteString(indent(assignmentString(pair))) - if i+1 < len(*v.Object) { - buf.WriteString(",") - } - buf.WriteString("\n") - } - buf.WriteString("}") - return buf.String() - - case v.Ident != nil: - return *v.Ident - } - - return "[\n]" // participle does not create v.List if it's empty -} - -// inlineFunctions contains buildscript function names whose arguments should all be written on a -// single line. By default, function arguments are written one per line. -var inlineFunctions = []string{ - reqFuncName, - eqFuncName, neFuncName, - gtFuncName, gteFuncName, - ltFuncName, lteFuncName, - andFuncName, -} - -func apString(f *buildexpression.Ap) string { - var ( - newline = "\n" - comma = "," - indent = indent - ) - - if funk.Contains(inlineFunctions, f.Name) { - newline = "" - comma = ", " - indent = func(s string) string { - return s - } - } - - buf := bytes.Buffer{} - buf.WriteString(fmt.Sprintf("%s(%s", f.Name, newline)) - - for i, argument := range f.Arguments { - buf.WriteString(indent(valueString(argument))) - - if i+1 < len(f.Arguments) { - buf.WriteString(comma) - } - - buf.WriteString(newline) - } - - buf.WriteString(")") - return buf.String() -} diff --git a/pkg/buildscript/marshal.go b/pkg/buildscript/marshal.go new file mode 100644 index 0000000000..4a006a5f55 --- /dev/null +++ b/pkg/buildscript/marshal.go @@ -0,0 +1,158 @@ +package buildscript + +import ( + "bytes" + "fmt" + "strconv" + "strings" + "time" + + "github.com/thoas/go-funk" +) + +const ( + mainKey = "main" + + reqFuncName = "Req" + revFuncName = "Revision" + eqFuncName = "Eq" + neFuncName = "Ne" + gtFuncName = "Gt" + gteFuncName = "Gte" + ltFuncName = "Lt" + lteFuncName = "Lte" + andFuncName = "And" +) + +// Marshal returns this structure in AScript, suitable for writing to disk. +func (b *BuildScript) Marshal() ([]byte, error) { + buf := strings.Builder{} + + buf.WriteString("```\n") + buf.WriteString("Project: " + b.project + "\n") + if b.atTime != nil { + buf.WriteString("Time: " + b.atTime.Format(time.RFC3339) + "\n") + } + buf.WriteString("```\n\n") + + var main *assignment + for _, assignment := range b.raw.Assignments { + if assignment.Key == mainKey { + main = assignment + continue // write at the end + } + buf.WriteString(assignmentString(assignment)) + buf.WriteString("\n") + } + + buf.WriteString("\n") + buf.WriteString(assignmentString(main)) + + return []byte(buf.String()), nil +} + +func assignmentString(a *assignment) string { + return fmt.Sprintf("%s = %s", a.Key, valueString(a.Value)) +} + +func indentByTab(s string) string { + return fmt.Sprintf("\t%s", strings.ReplaceAll(s, "\n", "\n\t")) +} + +func valueString(v *value) string { + switch { + case v.FuncCall != nil: + return funcCallString(v.FuncCall) + + case v.List != nil: + buf := bytes.Buffer{} + buf.WriteString("[\n") + for i, item := range *v.List { + buf.WriteString(indentByTab(valueString(item))) + if i+1 < len(*v.List) { + buf.WriteString(",") + } + buf.WriteString("\n") + } + buf.WriteString("]") + return buf.String() + + case v.Str != nil: + return strconv.Quote(*v.Str) + + case v.Number != nil: + return strconv.FormatFloat(*v.Number, 'G', -1, 64) // 64-bit float with minimum digits on display + + case v.Null != nil: + return "null" + + case v.Assignment != nil: + return assignmentString(v.Assignment) + + case v.Object != nil: + buf := bytes.Buffer{} + buf.WriteString("{\n") + for i, pair := range *v.Object { + buf.WriteString(indentByTab(assignmentString(pair))) + if i+1 < len(*v.Object) { + buf.WriteString(",") + } + buf.WriteString("\n") + } + buf.WriteString("}") + return buf.String() + + case v.Ident != nil: + return *v.Ident + } + + return "[\n]" // participle does not create v.List if it's empty +} + +// inlineFunctions contains build script function names whose arguments should all be written on a +// single line. By default, function arguments are written one per line. +var inlineFunctions = []string{ + reqFuncName, + eqFuncName, neFuncName, + gtFuncName, gteFuncName, + ltFuncName, lteFuncName, + andFuncName, +} + +func funcCallString(f *funcCall) string { + var ( + newline = "\n" + comma = "," + indent = indentByTab + ) + + if funk.Contains(inlineFunctions, f.Name) { + newline = "" + comma = ", " + indent = func(s string) string { + return s + } + } + + buf := bytes.Buffer{} + buf.WriteString(fmt.Sprintf("%s(%s", f.Name, newline)) + + buf.WriteString(argsToString(f.Arguments, newline, comma, indent)) + + buf.WriteString(")") + return buf.String() +} + +func argsToString(args []*value, newline, comma string, indent func(string) string) string { + buf := bytes.Buffer{} + for i, argument := range args { + buf.WriteString(indent(valueString(argument))) + + if i+1 < len(args) { + buf.WriteString(comma) + } + + buf.WriteString(newline) + } + return buf.String() +} diff --git a/pkg/buildscript/internal/raw/translate.go b/pkg/buildscript/marshal_buildexpression.go similarity index 59% rename from pkg/buildscript/internal/raw/translate.go rename to pkg/buildscript/marshal_buildexpression.go index 6d7cc68321..c161cfad24 100644 --- a/pkg/buildscript/internal/raw/translate.go +++ b/pkg/buildscript/marshal_buildexpression.go @@ -1,69 +1,61 @@ -package raw +package buildscript import ( "encoding/json" "strings" - "time" - - "github.com/go-openapi/strfmt" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/rtutils/ptr" ) const ( - AtTimeKey = "at_time" - RequirementNameKey = "name" - RequirementNamespaceKey = "namespace" - RequirementVersionRequirementsKey = "version_requirements" - RequirementVersionKey = "version" - RequirementComparatorKey = "comparator" + requirementNameKey = "name" + requirementNamespaceKey = "namespace" + requirementVersionRequirementsKey = "version_requirements" + requirementVersionKey = "version" + requirementRevisionIDKey = "revision_id" + requirementComparatorKey = "comparator" ) -// MarshalJSON marshals the Participle-produced Raw into an equivalent -// Users of buildscripts do not need to do this manually; the Expr field contains the -// equivalent -func (r *Raw) MarshalJSON() ([]byte, error) { +// MarshalBuildExpression returns this structure as a build expression in JSON format, suitable for sending to the Platform. +func (b *BuildScript) MarshalBuildExpression() ([]byte, error) { + raw, err := b.raw.clone() + if err != nil { + return nil, errs.Wrap(err, "Cannot clone raw build script") + } + m := make(map[string]interface{}) let := make(map[string]interface{}) - for _, assignment := range r.Assignments { + for _, assignment := range raw.Assignments { key := assignment.Key value := assignment.Value switch key { - case AtTimeKey: - if value.Str == nil { - return nil, errs.New("String timestamp expected for '%s'", key) - } - atTime, err := strfmt.ParseDateTime(strings.Trim(*value.Str, `"`)) - if err != nil { - return nil, errs.Wrap(err, "Invalid timestamp: %s", *value.Str) - } - r.AtTime = ptr.To(time.Time(atTime)) - continue // do not include this custom assignment in the let block - case "main": - key = "in" + case mainKey: + key = inKey // rename } let[key] = value } - m["let"] = let - return json.Marshal(m) + m[letKey] = let + return json.MarshalIndent(m, "", " ") } -func (a *Assignment) MarshalJSON() ([]byte, error) { +// Note: all of the MarshalJSON functions are named the way they are because Go's JSON package +// specifically looks for them. + +func (a *assignment) MarshalJSON() ([]byte, error) { m := make(map[string]interface{}) m[a.Key] = a.Value return json.Marshal(m) } -func (v *Value) MarshalJSON() ([]byte, error) { +func (v *value) MarshalJSON() ([]byte, error) { switch { case v.FuncCall != nil: return json.Marshal(v.FuncCall) case v.List != nil: return json.Marshal(v.List) case v.Str != nil: - return json.Marshal(strings.Trim(*v.Str, `"`)) + return json.Marshal(*v.Str) case v.Number != nil: return json.Marshal(*v.Number) case v.Null != nil: @@ -77,14 +69,19 @@ func (v *Value) MarshalJSON() ([]byte, error) { } return json.Marshal(m) case v.Ident != nil: - return json.Marshal("$" + *v.Ident) + name := *v.Ident + switch name { + case "TIME": + name = "at_time" // build expression uses this variable name + } + return json.Marshal("$" + name) } - return json.Marshal([]*Value{}) // participle does not create v.List if it's empty + return json.Marshal([]*value{}) // participle does not create v.List if it's empty } -func (f *FuncCall) MarshalJSON() ([]byte, error) { +func (f *funcCall) MarshalJSON() ([]byte, error) { if f.Name == reqFuncName { - return marshalReq(f.Arguments) + return marshalReq(f) } m := make(map[string]interface{}) @@ -104,7 +101,11 @@ func (f *FuncCall) MarshalJSON() ([]byte, error) { return json.Marshal(m) } -func marshalReq(args []*Value) ([]byte, error) { +// marshalReq translates a Req() function into its equivalent buildexpression requirement object. +// This is needed until buildexpressions support functions as requirements. Once they do, we can +// remove this method entirely. +func marshalReq(fn *funcCall) ([]byte, error) { + args := fn.Arguments requirement := make(map[string]interface{}) for _, arg := range args { @@ -115,30 +116,30 @@ func marshalReq(args []*Value) ([]byte, error) { switch { // Marshal the name argument (e.g. name = "") into {"name": ""} - case assignment.Key == RequirementNameKey && assignment.Value.Str != nil: - requirement[RequirementNameKey] = strings.Trim(*assignment.Value.Str, `"`) + case assignment.Key == requirementNameKey && assignment.Value.Str != nil: + requirement[requirementNameKey] = *assignment.Value.Str // Marshal the namespace argument (e.g. namespace = "") into // {"namespace": ""} - case assignment.Key == RequirementNamespaceKey && assignment.Value.Str != nil: - requirement[RequirementNamespaceKey] = strings.Trim(*assignment.Value.Str, `"`) + case assignment.Key == requirementNamespaceKey && assignment.Value.Str != nil: + requirement[requirementNamespaceKey] = *assignment.Value.Str // Marshal the version argument (e.g. version = (value = "")) into // {"version_requirements": [{"comparator": "", "version": ""}]} - case assignment.Key == RequirementVersionKey && assignment.Value.FuncCall != nil: - var requirements []*Value - var addRequirement func(*FuncCall) error // recursive function for adding to requirements list - addRequirement = func(funcCall *FuncCall) error { + case assignment.Key == requirementVersionKey && assignment.Value.FuncCall != nil: + requirements := make([]interface{}, 0) + var addRequirement func(*funcCall) error // recursive function for adding to requirements list + addRequirement = func(funcCall *funcCall) error { switch name := funcCall.Name; name { case eqFuncName, neFuncName, gtFuncName, gteFuncName, ltFuncName, lteFuncName: - req := make([]*Assignment, 0) - req = append(req, &Assignment{RequirementComparatorKey, &Value{Str: ptr.To(strings.ToLower(name))}}) + req := make(map[string]string) + req[requirementComparatorKey] = strings.ToLower(name) if len(funcCall.Arguments) == 0 || funcCall.Arguments[0].Assignment == nil || funcCall.Arguments[0].Assignment.Value.Str == nil || *funcCall.Arguments[0].Assignment.Value.Str == "value" { return errs.New(`Illegal argument for version comparator '%s': 'value = ""' expected`, name) } - req = append(req, &Assignment{RequirementVersionKey, &Value{Str: funcCall.Arguments[0].Assignment.Value.Str}}) - requirements = append(requirements, &Value{Object: &req}) + req[requirementVersionKey] = *funcCall.Arguments[0].Assignment.Value.Str + requirements = append(requirements, req) case andFuncName: if len(funcCall.Arguments) != 2 { return errs.New("Illegal arguments for version comparator '%s': 2 arguments expected, got %d", name, len(funcCall.Arguments)) @@ -161,7 +162,7 @@ func marshalReq(args []*Value) ([]byte, error) { if err != nil { return nil, errs.Wrap(err, "Could not marshal requirement") } - requirement[RequirementVersionRequirementsKey] = &Value{List: &requirements} + requirement[requirementVersionRequirementsKey] = requirements default: logging.Debug("Adding unknown argument: %v", assignment) diff --git a/pkg/buildscript/merge.go b/pkg/buildscript/merge.go new file mode 100644 index 0000000000..32db4da729 --- /dev/null +++ b/pkg/buildscript/merge.go @@ -0,0 +1,125 @@ +package buildscript + +import ( + "encoding/json" + "reflect" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/multilog" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" +) + +// Merge merges the requirements from another BuildScript into this one, according to the given +// merge strategy. +// BuildScript merges are only possible if the scripts differ ONLY in requirements AND/OR at times. +func (b *BuildScript) Merge(other *BuildScript, strategies *mono_models.MergeStrategies) error { + if !isAutoMergePossible(b, other) { + return errs.New("Unable to merge build scripts") + } + if len(strategies.Conflicts) > 0 { + return errs.New("Unable to merge build scripts due to conflicting requirements") + } + + // Update requirements with merge results. + for _, req := range strategies.OverwriteChanges { + var op types.Operation + err := op.Unmarshal(req.Operation) + if err != nil { + return errs.Wrap(err, "Unable to convert requirement operation to buildplan operation") + } + + var versionRequirements []types.VersionRequirement + for _, constraint := range req.VersionConstraints { + data, err := constraint.MarshalBinary() + if err != nil { + return errs.Wrap(err, "Could not marshal requirement version constraints") + } + m := make(map[string]string) + err = json.Unmarshal(data, &m) + if err != nil { + return errs.Wrap(err, "Could not unmarshal requirement version constraints") + } + versionRequirements = append(versionRequirements, m) + } + + bpReq := types.Requirement{ + Name: req.Requirement, + Namespace: req.Namespace, + VersionRequirement: versionRequirements, + } + + if err := b.UpdateRequirement(op, bpReq); err != nil { + return errs.Wrap(err, "Unable to update build script with merge results") + } + } + + // When merging build scripts we want to use the most recent timestamp + atTime := other.AtTime() + if atTime != nil && b.AtTime() != nil && atTime.After(*b.AtTime()) { + b.SetAtTime(*atTime, true) + } + + return nil +} + +// isAutoMergePossible determines whether or not it is possible to auto-merge the given build +// scripts. +// This is only possible if the two build scripts differ ONLY in requirements. +func isAutoMergePossible(scriptA *BuildScript, scriptB *BuildScript) bool { + jsonA, err := getComparableJson(scriptA) + if err != nil { + multilog.Error("Unable to get build script minus requirements: %v", errs.JoinMessage(err)) + return false + } + jsonB, err := getComparableJson(scriptB) + if err != nil { + multilog.Error("Unable to get build script minus requirements: %v", errs.JoinMessage(err)) + return false + } + logging.Debug("Checking for possibility of auto-merging build scripts") + logging.Debug("JsonA: %v", jsonA) + logging.Debug("JsonB: %v", jsonB) + return reflect.DeepEqual(jsonA, jsonB) +} + +// getComparableJson returns a comparable JSON map[string]interface{} structure for the given build +// script. The map will not have a "requirements" field. +func getComparableJson(script *BuildScript) (map[string]interface{}, error) { + data, err := script.MarshalBuildExpression() + if err != nil { + return nil, errs.New("Unable to unmarshal marshaled build expression") + } + + m := make(map[string]interface{}) + err = json.Unmarshal(data, &m) + if err != nil { + return nil, errs.New("Unable to unmarshal marshaled build expression") + } + + letMap, ok := m["let"].(map[string]interface{}) + if !ok { + return nil, errs.New("'let' key is not a JSON object") + } + deleteKey(&letMap, "requirements") + + return m, nil +} + +// deleteKey recursively iterates over the given JSON map until it finds the given key and deletes +// it and its value. +func deleteKey(m *map[string]interface{}, key string) bool { + for k, v := range *m { + if k == key { + delete(*m, k) + return true + } + if m2, ok := v.(map[string]interface{}); ok { + if deleteKey(&m2, key) { + return true + } + } + } + return false +} diff --git a/pkg/buildscript/merge_test.go b/pkg/buildscript/merge_test.go new file mode 100644 index 0000000000..5dddb14fd8 --- /dev/null +++ b/pkg/buildscript/merge_test.go @@ -0,0 +1,197 @@ +package buildscript + +import ( + "testing" + + "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const mergeATime = "2000-01-01T00:00:00Z" +const mergeBTime = "2000-01-02T00:00:00Z" + +func TestMergeAdd(t *testing.T) { + scriptA, err := Unmarshal([]byte( + checkoutInfoString(testProject, mergeATime) + ` +runtime = solve( + at_time = TIME, + platforms = [ + "12345", + "67890" + ], + requirements = [ + Req(name = "perl", namespace = "language"), + Req(name = "DateTime", namespace = "language/perl") + ] +) + +main = runtime +`)) + require.NoError(t, err) + + scriptB, err := Unmarshal([]byte( + checkoutInfoString(testProject, mergeBTime) + ` +runtime = solve( + at_time = TIME, + platforms = [ + "12345", + "67890" + ], + requirements = [ + Req(name = "perl", namespace = "language"), + Req(name = "JSON", namespace = "language/perl") + ] +) + +main = runtime +`)) + require.NoError(t, err) + + strategies := &mono_models.MergeStrategies{ + OverwriteChanges: []*mono_models.CommitChangeEditable{ + {Namespace: "language/perl", Requirement: "JSON", Operation: mono_models.CommitChangeEditableOperationAdded}, + }, + } + + require.True(t, isAutoMergePossible(scriptA, scriptB)) + + err = scriptA.Merge(scriptB, strategies) + require.NoError(t, err) + + v, err := scriptA.Marshal() + require.NoError(t, err) + + assert.Equal(t, + checkoutInfoString(testProject, mergeBTime)+` +runtime = solve( + at_time = TIME, + platforms = [ + "12345", + "67890" + ], + requirements = [ + Req(name = "perl", namespace = "language"), + Req(name = "DateTime", namespace = "language/perl"), + Req(name = "JSON", namespace = "language/perl") + ] +) + +main = runtime`, string(v)) +} + +func TestMergeRemove(t *testing.T) { + scriptA, err := Unmarshal([]byte( + checkoutInfoString(testProject, mergeBTime) + ` +runtime = solve( + at_time = TIME, + platforms = [ + "12345", + "67890" + ], + requirements = [ + Req(name = "perl", namespace = "language"), + Req(name = "JSON", namespace = "language/perl"), + Req(name = "DateTime", namespace = "language/perl") + ] +) + +main = runtime +`)) + require.NoError(t, err) + + scriptB, err := Unmarshal([]byte( + checkoutInfoString(testProject, mergeATime) + ` +runtime = solve( + at_time = TIME, + platforms = [ + "12345", + "67890" + ], + requirements = [ + Req(name = "perl", namespace = "language"), + Req(name = "DateTime", namespace = "language/perl") + ] +) + +main = runtime +`)) + + strategies := &mono_models.MergeStrategies{ + OverwriteChanges: []*mono_models.CommitChangeEditable{ + {Namespace: "language/perl", Requirement: "JSON", Operation: mono_models.CommitChangeEditableOperationRemoved}, + }, + } + + require.True(t, isAutoMergePossible(scriptA, scriptB)) + + err = scriptA.Merge(scriptB, strategies) + require.NoError(t, err) + + v, err := scriptA.Marshal() + require.NoError(t, err) + + assert.Equal(t, + checkoutInfoString(testProject, mergeBTime)+` +runtime = solve( + at_time = TIME, + platforms = [ + "12345", + "67890" + ], + requirements = [ + Req(name = "perl", namespace = "language"), + Req(name = "DateTime", namespace = "language/perl") + ] +) + +main = runtime`, string(v)) +} + +func TestMergeConflict(t *testing.T) { + scriptA, err := Unmarshal([]byte( + checkoutInfoString(testProject, mergeATime) + ` +runtime = solve( + at_time = TIME, + platforms = [ + "12345", + "67890" + ], + requirements = [ + Req(name = "perl", namespace = "language") + ] +) + +main = runtime +`)) + require.NoError(t, err) + + scriptB, err := Unmarshal([]byte( + checkoutInfoString(testProject, mergeATime) + ` +runtime = solve( + at_time = TIME, + platforms = [ + "12345" + ], + requirements = [ + Req(name = "perl", namespace = "language"), + Req(name = "JSON", namespace = "language/perl") + ] +) + +main = runtime +`)) + require.NoError(t, err) + + assert.False(t, isAutoMergePossible(scriptA, scriptB)) // platforms do not match + + err = scriptA.Merge(scriptB, nil) + require.Error(t, err) +} + +func TestDeleteKey(t *testing.T) { + m := map[string]interface{}{"foo": map[string]interface{}{"bar": "baz", "quux": "foobar"}} + assert.True(t, deleteKey(&m, "quux"), "did not find quux") + _, exists := m["foo"].(map[string]interface{})["quux"] + assert.False(t, exists, "did not delete quux") +} diff --git a/pkg/buildscript/mutations.go b/pkg/buildscript/mutations.go new file mode 100644 index 0000000000..c974641474 --- /dev/null +++ b/pkg/buildscript/mutations.go @@ -0,0 +1,171 @@ +package buildscript + +import ( + "errors" + + "github.com/go-openapi/strfmt" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" +) + +const requirementRevisionKey = "revision" + +func (b *BuildScript) UpdateRequirement(operation types.Operation, requirement types.Requirement) error { + var err error + switch operation { + case types.OperationAdded: + err = b.AddRequirement(requirement) + case types.OperationRemoved: + err = b.RemoveRequirement(requirement) + case types.OperationUpdated: + err = b.RemoveRequirement(requirement) + if err != nil { + break + } + err = b.AddRequirement(requirement) + default: + return errs.New("Unsupported operation") + } + if err != nil { + return errs.Wrap(err, "Could not update BuildScript's requirements") + } + return nil +} + +func (b *BuildScript) AddRequirement(requirement types.Requirement) error { + if err := b.RemoveRequirement(requirement); err != nil && !errors.As(err, ptr.To(&RequirementNotFoundError{})) { + return errs.Wrap(err, "Could not remove requirement") + } + + // Use object form for now, and then transform it into function form later. + obj := []*assignment{ + {requirementNameKey, &value{Str: &requirement.Name}}, + {requirementNamespaceKey, &value{Str: &requirement.Namespace}}, + } + + if requirement.Revision != nil { + obj = append(obj, &assignment{requirementRevisionKey, &value{Number: ptr.To(float64(*requirement.Revision))}}) + } + + if requirement.VersionRequirement != nil { + values := []*value{} + for _, req := range requirement.VersionRequirement { + values = append(values, &value{Object: &[]*assignment{ + {requirementComparatorKey, &value{Str: ptr.To(req[requirementComparatorKey])}}, + {requirementVersionKey, &value{Str: ptr.To(req[requirementVersionKey])}}, + }}) + } + obj = append(obj, &assignment{requirementVersionRequirementsKey, &value{List: &values}}) + } + + requirementsNode, err := b.getRequirementsNode() + if err != nil { + return errs.Wrap(err, "Could not get requirements node") + } + + list := *requirementsNode.List + list = append(list, transformRequirement(&value{Object: &obj})) + requirementsNode.List = &list + + return nil +} + +type RequirementNotFoundError struct { + Name string + *locale.LocalizedError // for legacy non-user-facing error usages +} + +// RemoveRequirement will remove any matching requirement. Note that it only operates on the Name and Namespace fields. +// It will not verify if revision or version match. +func (b *BuildScript) RemoveRequirement(requirement types.Requirement) error { + requirementsNode, err := b.getRequirementsNode() + if err != nil { + return errs.Wrap(err, "Could not get requirements node") + } + + match := false + for i, req := range *requirementsNode.List { + if req.FuncCall == nil || req.FuncCall.Name != reqFuncName { + continue + } + + for _, arg := range req.FuncCall.Arguments { + if arg.Assignment.Key == requirementNameKey { + match = *arg.Assignment.Value.Str == requirement.Name + if !match || requirement.Namespace == "" { + break + } + } + if requirement.Namespace != "" && arg.Assignment.Key == requirementNamespaceKey { + match = *arg.Assignment.Value.Str == requirement.Namespace + if !match { + break + } + } + } + + if match { + list := *requirementsNode.List + list = append(list[:i], list[i+1:]...) + requirementsNode.List = &list + break + } + } + + if !match { + return &RequirementNotFoundError{ + requirement.Name, + locale.NewInputError("err_remove_requirement_not_found", "", requirement.Name), + } + } + + return nil +} + +func (b *BuildScript) AddPlatform(platformID strfmt.UUID) error { + platformsNode, err := b.getPlatformsNode() + if err != nil { + return errs.Wrap(err, "Could not get platforms node") + } + + list := *platformsNode.List + list = append(list, &value{Str: ptr.To(platformID.String())}) + platformsNode.List = &list + + return nil +} + +type PlatformNotFoundError struct { + Id strfmt.UUID + *locale.LocalizedError // for legacy non-user-facing error usages +} + +func (b *BuildScript) RemovePlatform(platformID strfmt.UUID) error { + platformsNode, err := b.getPlatformsNode() + if err != nil { + return errs.Wrap(err, "Could not get platforms node") + } + + var found bool + for i, value := range *platformsNode.List { + if value.Str != nil && *value.Str == platformID.String() { + list := *platformsNode.List + list = append(list[:i], list[i+1:]...) + platformsNode.List = &list + found = true + break + } + } + + if !found { + return &PlatformNotFoundError{ + platformID, + locale.NewInputError("err_remove_platform_not_found", "", platformID.String()), + } + } + + return nil +} diff --git a/pkg/buildscript/mutations_test.go b/pkg/buildscript/mutations_test.go new file mode 100644 index 0000000000..6b61057075 --- /dev/null +++ b/pkg/buildscript/mutations_test.go @@ -0,0 +1,375 @@ +package buildscript + +import ( + "path/filepath" + "reflect" + "sort" + "testing" + + "github.com/go-openapi/strfmt" + "github.com/stretchr/testify/assert" + + "github.com/ActiveState/cli/internal/environment" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" +) + +// TestUpdateRequirements tests that build scripts can correctly read requirements from build +// expressions, modify them (add/update/remove), and return them in a structured format external to +// the internal, raw format. +func TestUpdateRequirements(t *testing.T) { + type args struct { + requirement DependencyRequirement + operation types.Operation + filename string + } + tests := []struct { + name string + args args + want []DependencyRequirement + wantErr bool + }{ + { + name: "add", + args: args{ + requirement: DependencyRequirement{types.Requirement{ + Name: "requests", + Namespace: "language/python", + }}, + operation: types.OperationAdded, + filename: "buildexpression.json", + }, + want: []DependencyRequirement{ + {types.Requirement{ + Name: "jinja2-time", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "jupyter-contrib-nbextensions", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "python", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "3.10.10", + }, + }, + }}, + {types.Requirement{ + Name: "copier", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "jupyterlab", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "requests", + Namespace: "language/python", + }}, + }, + wantErr: false, + }, + { + name: "remove", + args: args{ + requirement: DependencyRequirement{types.Requirement{ + Name: "jupyterlab", + Namespace: "language/python", + }}, + operation: types.OperationRemoved, + filename: "buildexpression.json", + }, + want: []DependencyRequirement{ + {types.Requirement{ + Name: "jinja2-time", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "jupyter-contrib-nbextensions", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "python", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "3.10.10", + }, + }, + }}, + {types.Requirement{ + Name: "copier", + Namespace: "language/python", + }}, + }, + wantErr: false, + }, + { + name: "update", + args: args{ + requirement: DependencyRequirement{types.Requirement{ + Name: "python", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "3.11.0", + }, + }, + }}, + operation: types.OperationUpdated, + filename: "buildexpression.json", + }, + want: []DependencyRequirement{ + {types.Requirement{ + Name: "jinja2-time", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "jupyter-contrib-nbextensions", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "python", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "3.11.0", + }, + }, + }}, + {types.Requirement{ + Name: "copier", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "jupyterlab", + Namespace: "language/python", + }}, + }, + wantErr: false, + }, + { + name: "remove not existing", + args: args{ + requirement: DependencyRequirement{types.Requirement{ + Name: "requests", + Namespace: "language/python", + }}, + operation: types.OperationRemoved, + filename: "buildexpression.json", + }, + want: []DependencyRequirement{ + {types.Requirement{ + Name: "jinja2-time", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "jupyter-contrib-nbextensions", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "python", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "3.10.10", + }, + }, + }}, + {types.Requirement{ + Name: "copier", + Namespace: "language/python", + }}, + {types.Requirement{ + Name: "jupyterlab", + Namespace: "language/python", + }}, + }, + wantErr: true, + }, + { + name: "add-installer-complex", + args: args{ + requirement: DependencyRequirement{types.Requirement{ + Name: "JSON", + Namespace: "language/perl", + }}, + operation: types.OperationAdded, + filename: "buildexpression-installer-complex.json", + }, + want: []DependencyRequirement{ + {types.Requirement{ + Name: "perl", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "5.36.0", + }, + }, + }}, + {types.Requirement{ + Name: "JSON", + Namespace: "language/perl", + }}, + }, + wantErr: false, + }, + { + name: "add-alternate", + args: args{ + requirement: DependencyRequirement{types.Requirement{ + Name: "JSON", + Namespace: "language/perl", + }}, + operation: types.OperationAdded, + filename: "buildexpression-alternate.json", + }, + want: []DependencyRequirement{ + {types.Requirement{ + Name: "Path-Tiny", + Namespace: "language/perl", + }}, + {types.Requirement{ + Name: "perl", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "5.36.1", + }, + }, + }}, + {types.Requirement{ + Name: "JSON", + Namespace: "language/perl", + }}, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wd, err := environment.GetRootPath() + assert.NoError(t, err) + + data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "buildscript", "testdata", tt.args.filename)) + assert.NoError(t, err) + + script := New() + assert.NoError(t, script.UnmarshalBuildExpression(data)) + + err = script.UpdateRequirement(tt.args.operation, tt.args.requirement.Requirement) + if err != nil { + if tt.wantErr { + return + } + + t.Errorf("BuildExpression.Update() error = %v, wantErr %v", err, tt.wantErr) + return + } + + got, err := script.Requirements() + assert.NoError(t, err) + + gotReqs := []DependencyRequirement{} + for _, g := range got { + gotReqs = append(gotReqs, g.(DependencyRequirement)) + } + + sort.Slice(gotReqs, func(i, j int) bool { return gotReqs[i].Name < gotReqs[j].Name }) + sort.Slice(tt.want, func(i, j int) bool { return tt.want[i].Name < tt.want[j].Name }) + + if !reflect.DeepEqual(gotReqs, tt.want) { + t.Errorf("BuildExpression.Requirements() = %v, want %v", gotReqs, tt.want) + } + }) + } +} + +// TestUpdatePlatform tests that build scripts can correctly read platforms from build +// expressions, modify them (add/remove), and return them in a structured format external to the +// internal, raw format. +func TestUpdatePlatform(t *testing.T) { + type args struct { + platform strfmt.UUID + operation types.Operation + filename string + } + tests := []struct { + name string + args args + want []strfmt.UUID + wantErr bool + }{ + { + name: "add", + args: args{ + platform: strfmt.UUID("78977bc8-0f32-519d-80f3-9043f059398c"), + operation: types.OperationAdded, + filename: "buildexpression.json", + }, + want: []strfmt.UUID{ + strfmt.UUID("78977bc8-0f32-519d-80f3-9043f059398c"), + strfmt.UUID("96b7e6f2-bebf-564c-bc1c-f04482398f38"), + }, + wantErr: false, + }, + { + name: "remove", + args: args{ + platform: strfmt.UUID("0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a"), + operation: types.OperationRemoved, + filename: "buildexpression-alternate.json", + }, + want: []strfmt.UUID{ + strfmt.UUID("46a5b48f-226a-4696-9746-ba4d50d661c2"), + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wd, err := environment.GetRootPath() + assert.NoError(t, err) + + data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "buildscript", "testdata", tt.args.filename)) + assert.NoError(t, err) + + script := New() + assert.NoError(t, script.UnmarshalBuildExpression(data)) + + if tt.args.operation == types.OperationAdded { + err = script.AddPlatform(tt.args.platform) + } else { + err = script.RemovePlatform(tt.args.platform) + } + if err != nil { + if tt.wantErr { + return + } + + t.Errorf("BuildExpression.Update() error = %v, wantErr %v", err, tt.wantErr) + return + } + + got, err := script.Platforms() + assert.NoError(t, err) + + sort.Slice(got, func(i, j int) bool { return got[i] < got[j] }) + sort.Slice(tt.want, func(i, j int) bool { return tt.want[i] < tt.want[j] }) + + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("BuildExpression.Platforms() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/buildscript/queries.go b/pkg/buildscript/queries.go new file mode 100644 index 0000000000..eec73943d0 --- /dev/null +++ b/pkg/buildscript/queries.go @@ -0,0 +1,326 @@ +package buildscript + +import ( + "strings" + + "github.com/ActiveState/cli/internal/logging" + "github.com/go-openapi/strfmt" + "github.com/thoas/go-funk" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" +) + +const ( + solveFuncName = "solve" + solveLegacyFuncName = "solve_legacy" + srcKey = "src" + mergeKey = "merge" + requirementsKey = "requirements" + platformsKey = "platforms" +) + +var errNodeNotFound = errs.New("Could not find node") +var errValueNotFound = errs.New("Could not find value") + +type Requirement interface { + IsRequirement() +} + +type DependencyRequirement struct { + types.Requirement +} + +func (r DependencyRequirement) IsRequirement() {} + +type RevisionRequirement struct { + Name string `json:"name"` + RevisionID strfmt.UUID `json:"revision_id"` +} + +func (r RevisionRequirement) IsRequirement() {} + +type UnknownRequirement struct { + Name string `json:"name"` + Value string `json:"value"` +} + +func (r UnknownRequirement) IsRequirement() {} + +// Returns the requirements for the given target. +// If no target is given, uses the default target (i.e. the name assigned to 'main'). +func (b *BuildScript) Requirements(targets ...string) ([]Requirement, error) { + requirementsNode, err := b.getRequirementsNode(targets...) + if err != nil { + return nil, errs.Wrap(err, "Could not get requirements node") + } + + return exportRequirements(requirementsNode), nil +} + +func exportRequirements(v *value) []Requirement { + if v.List == nil { + logging.Error("exportRequirements called with value that does not have a list") + return nil + } + var requirements []Requirement + for _, req := range *v.List { + if req.FuncCall == nil { + continue + } + + switch req.FuncCall.Name { + case reqFuncName, revFuncName: + requirements = append(requirements, parseRequirement(req)) + default: + requirements = append(requirements, UnknownRequirement{ + Name: req.FuncCall.Name, + Value: argsToString(req.FuncCall.Arguments, "", ", ", func(v string) string { return v }), + }) + } + + } + + return requirements +} + +// parseRequirement turns a raw *value representing a requirement into an externally consumable requirement type +// It accepts any value as input. If the value does not represent a requirement it simply won't be acted on and a nill +// will be returned. +func parseRequirement(req *value) Requirement { + if req.FuncCall == nil { + return nil + } + switch req.FuncCall.Name { + case reqFuncName: + var r DependencyRequirement + for _, arg := range req.FuncCall.Arguments { + switch arg.Assignment.Key { + case requirementNameKey: + r.Name = *arg.Assignment.Value.Str + case requirementNamespaceKey: + r.Namespace = *arg.Assignment.Value.Str + case requirementVersionKey: + r.VersionRequirement = getVersionRequirements(arg.Assignment.Value) + } + } + return r + case revFuncName: + var r RevisionRequirement + for _, arg := range req.FuncCall.Arguments { + switch arg.Assignment.Key { + case requirementNameKey: + r.Name = *arg.Assignment.Value.Str + case requirementRevisionIDKey: + r.RevisionID = strfmt.UUID(*arg.Assignment.Value.Str) + } + } + return r + default: + return nil + } +} + +// DependencyRequirements is identical to Requirements except that it only considers dependency type requirements, +// which are the most common. +// ONLY use this when you know you only need to care about dependencies. +func (b *BuildScript) DependencyRequirements(targets ...string) ([]types.Requirement, error) { + reqs, err := b.Requirements(targets...) + if err != nil { + return nil, errs.Wrap(err, "Could not get requirements") + } + var deps []types.Requirement + for _, req := range reqs { + if dep, ok := req.(DependencyRequirement); ok { + deps = append(deps, dep.Requirement) + } + } + return deps, nil +} + +func (b *BuildScript) getRequirementsNode(targets ...string) (*value, error) { + node, err := b.getSolveNode(targets...) + if err != nil { + return nil, errs.Wrap(err, "Could not get solve node") + } + + for _, arg := range node.FuncCall.Arguments { + if arg.Assignment != nil && arg.Assignment.Key == requirementsKey { + return arg.Assignment.Value, nil + } + } + + return nil, errNodeNotFound +} + +func getVersionRequirements(v *value) []types.VersionRequirement { + reqs := []types.VersionRequirement{} + + switch v.FuncCall.Name { + // e.g. Eq(value = "1.0") + case eqFuncName, neFuncName, gtFuncName, gteFuncName, ltFuncName, lteFuncName: + reqs = append(reqs, types.VersionRequirement{ + requirementComparatorKey: strings.ToLower(v.FuncCall.Name), + requirementVersionKey: *v.FuncCall.Arguments[0].Assignment.Value.Str, + }) + + // e.g. And(left = Gte(value = "1.0"), right = Lt(value = "2.0")) + case andFuncName: + for _, arg := range v.FuncCall.Arguments { + if arg.Assignment != nil && arg.Assignment.Value.FuncCall != nil { + reqs = append(reqs, getVersionRequirements(arg.Assignment.Value)...) + } + } + } + + return reqs +} + +func isSolveFuncName(name string) bool { + return name == solveFuncName || name == solveLegacyFuncName +} + +func (b *BuildScript) getTargetSolveNode(targets ...string) (*value, error) { + if len(targets) == 0 { + for _, assignment := range b.raw.Assignments { + if assignment.Key != mainKey { + continue + } + if assignment.Value.Ident != nil && *assignment.Value.Ident != "" { + targets = []string{*assignment.Value.Ident} + break + } + } + } + + var search func([]*assignment) *value + search = func(assignments []*assignment) *value { + var nextLet []*assignment + for _, a := range assignments { + if a.Key == letKey { + nextLet = *a.Value.Object // nested 'let' to search next + continue + } + + if funk.Contains(targets, a.Key) && a.Value.FuncCall != nil { + return a.Value + } + + if f := a.Value.FuncCall; len(targets) == 0 && f != nil && isSolveFuncName(f.Name) { + // This is coming from a complex build expression with no straightforward way to determine + // a default target. Fall back on a top-level solve node. + return a.Value + } + } + + // The highest level solve node is not found, so recurse into the next let. + if nextLet != nil { + return search(nextLet) + } + + return nil + } + + if node := search(b.raw.Assignments); node != nil { + return node, nil + } + return nil, errNodeNotFound +} + +func (b *BuildScript) getSolveNode(targets ...string) (*value, error) { + node, err := b.getTargetSolveNode(targets...) + if err != nil { + return nil, errs.Wrap(err, "Could not get target node") + } + + // If the target is the solve function, we're done. + if isSolveFuncName(node.FuncCall.Name) { + return node, nil + } + + // If the target is a merge call, then look at right and left branches (in reverse order since the + // right branch has precedence). + if node.FuncCall.Name == mergeKey { + for i := len(node.FuncCall.Arguments) - 1; i >= 0; i-- { + arg := node.FuncCall.Arguments[i] + if arg.Assignment == nil { + continue + } + a := arg.Assignment + if a.Value.Ident != nil { + if node, err := b.getSolveNode(*a.Value.Ident); err == nil { + return node, nil + } + // Note: ignore errors because either branch may not contain a solve node. + // We'll return an error if both branches do not contain a solve node. + } + } + return nil, errNodeNotFound + } + + // Otherwise, the "src" key contains a reference to the solve node. + // For example: + // + // runtime = state_tool_artifacts_v1(src = sources) + // sources = solve(at_time = ..., platforms = [...], requirements = [...], ...) + // + // Look over the build expression again for that referenced node. + for _, arg := range node.FuncCall.Arguments { + if arg.Assignment == nil { + continue + } + a := arg.Assignment + if a.Key == srcKey && a.Value.Ident != nil { + node, err := b.getSolveNode(*a.Value.Ident) + if err != nil { + return nil, errs.Wrap(err, "Could not get solve node from target") + } + return node, nil + } + } + + return nil, errNodeNotFound +} + +func (b *BuildScript) getSolveAtTimeValue(targets ...string) (*value, error) { + node, err := b.getSolveNode(targets...) + if err != nil { + return nil, errs.Wrap(err, "Could not get solve node") + } + + for _, arg := range node.FuncCall.Arguments { + if arg.Assignment != nil && arg.Assignment.Key == atTimeKey { + return arg.Assignment.Value, nil + } + } + + return nil, errValueNotFound +} + +func (b *BuildScript) Platforms(targets ...string) ([]strfmt.UUID, error) { + node, err := b.getPlatformsNode(targets...) + if err != nil { + return nil, errs.Wrap(err, "Could not get platform node") + } + + list := []strfmt.UUID{} + for _, value := range *node.List { + list = append(list, strfmt.UUID(*value.Str)) + } + return list, nil +} + +func (b *BuildScript) getPlatformsNode(targets ...string) (*value, error) { + node, err := b.getSolveNode(targets...) + if err != nil { + return nil, errs.Wrap(err, "Could not get solve node") + } + + for _, arg := range node.FuncCall.Arguments { + if arg.Assignment != nil && arg.Assignment.Key == platformsKey { + return arg.Assignment.Value, nil + } + } + + return nil, errNodeNotFound +} diff --git a/pkg/buildscript/queries_test.go b/pkg/buildscript/queries_test.go new file mode 100644 index 0000000000..1b135f82f1 --- /dev/null +++ b/pkg/buildscript/queries_test.go @@ -0,0 +1,183 @@ +package buildscript + +import ( + "path/filepath" + "reflect" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/ActiveState/cli/internal/environment" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" +) + +// TestRequirements tests that build scripts can correctly read requirements from build expressions +// and return them in a structured format external to the internal, raw format. +func TestRequirements(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + want []types.Requirement + wantErr bool + }{ + { + name: "basic", + args: args{ + filename: "buildexpression.json", + }, + want: []types.Requirement{ + { + Name: "jinja2-time", + Namespace: "language/python", + }, + { + Name: "jupyter-contrib-nbextensions", + Namespace: "language/python", + }, + { + Name: "python", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "3.10.10", + }, + }, + }, + { + Name: "copier", + Namespace: "language/python", + }, + { + Name: "jupyterlab", + Namespace: "language/python", + }, + }, + wantErr: false, + }, + { + name: "installer-complex", + args: args{ + filename: "buildexpression-installer-complex.json", + }, + want: []types.Requirement{ + { + Name: "perl", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "5.36.0", + }, + }, + }, + }, + wantErr: false, + }, + { + name: "alternate", + args: args{ + filename: "buildexpression-alternate.json", + }, + want: []types.Requirement{ + { + Name: "Path-Tiny", + Namespace: "language/perl", + }, + { + Name: "perl", + Namespace: "language", + VersionRequirement: []types.VersionRequirement{ + map[string]string{ + "comparator": string(types.ComparatorEQ), + "version": "5.36.1", + }, + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wd, err := environment.GetRootPath() + assert.NoError(t, err) + + data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "buildscript", "testdata", tt.args.filename)) + assert.NoError(t, err) + + script := New() + assert.NoError(t, script.UnmarshalBuildExpression(data)) + + got, err := script.Requirements() + assert.NoError(t, err) + + gotReqs := []types.Requirement{} + for _, g := range got { + gotReqs = append(gotReqs, g.(DependencyRequirement).Requirement) + } + + if !reflect.DeepEqual(gotReqs, tt.want) { + t.Errorf("BuildExpression.Requirements() = %v, want %v", gotReqs, tt.want) + } + }) + } +} + +const ValidZeroUUID = "00000000-0000-0000-0000-000000000000" + +// TestRevision tests that build scripts can correctly read revisions from build expressions +// and return them in a structured format external to the internal, raw format. +func TestRevision(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + want []RevisionRequirement + wantErr bool + }{ + { + name: "basic", + args: args{ + filename: "buildexpression_rev.json", + }, + want: []RevisionRequirement{ + { + Name: "revision-pkg", + RevisionID: ValidZeroUUID, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wd, err := environment.GetRootPath() + assert.NoError(t, err) + + data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "buildscript", "testdata", tt.args.filename)) + assert.NoError(t, err) + + script := New() + assert.NoError(t, script.UnmarshalBuildExpression(data)) + + got, err := script.Requirements() + assert.NoError(t, err) + + gotReqs := []RevisionRequirement{} + for _, g := range got { + gotReqs = append(gotReqs, g.(RevisionRequirement)) + } + + if !reflect.DeepEqual(gotReqs, tt.want) { + t.Errorf("BuildExpression.Requirements() = %v, want %v", gotReqs, tt.want) + } + }) + } +} diff --git a/pkg/buildscript/raw.go b/pkg/buildscript/raw.go new file mode 100644 index 0000000000..f60df48453 --- /dev/null +++ b/pkg/buildscript/raw.go @@ -0,0 +1,75 @@ +package buildscript + +import ( + "github.com/brunoga/deep" +) + +// Tagged fields will be filled in by Participle. +type rawBuildScript struct { + Info *string `parser:"(RawString @RawString RawString)?"` + Assignments []*assignment `parser:"@@+"` +} + +// clone is meant to facilitate making modifications to functions at marshal time. The idea is that these modifications +// are only intended to be made for the purpose of marshalling, meaning we do not want to mutate the original object. +// This is an antipattern, but addressing it requires significant refactoring that we're not committing to atm. +func (r *rawBuildScript) clone() (*rawBuildScript, error) { + return deep.Copy(r) +} + +func (r *rawBuildScript) FuncCalls() []*funcCall { + result := []*funcCall{} + for _, a := range r.Assignments { + result = append(result, a.Value.funcCalls()...) + } + return result +} + +// funcCalls will return all function calls recursively under the given value. +func (v *value) funcCalls() []*funcCall { + result := []*funcCall{} + switch { + case v.FuncCall != nil: + result = append(result, v.FuncCall) + for _, arg := range v.FuncCall.Arguments { + result = append(result, arg.funcCalls()...) + } + case v.List != nil: + for _, v := range *v.List { + result = append(result, v.funcCalls()...) + } + case v.Assignment != nil: + result = append(result, v.Assignment.Value.funcCalls()...) + case v.Object != nil: + for _, a := range *v.Object { + result = append(result, a.Value.funcCalls()...) + } + } + return result +} + +type assignment struct { + Key string `parser:"@Ident '='"` + Value *value `parser:"@@"` +} + +type value struct { + FuncCall *funcCall `parser:"@@"` + List *[]*value `parser:"| '[' (@@ (',' @@)* ','?)? ']'"` + Str *string `parser:"| @String"` + Number *float64 `parser:"| (@Float | @Int)"` + Null *null `parser:"| @@"` + + Assignment *assignment `parser:"| @@"` // only in FuncCall + Object *[]*assignment `parser:"| '{' @@ (',' @@)* ','? '}'"` // only in List + Ident *string `parser:"| @Ident"` // only in FuncCall or Assignment +} + +type null struct { + Null string `parser:"'null'"` +} + +type funcCall struct { + Name string `parser:"@Ident"` + Arguments []*value `parser:"'(' @@ (',' @@)* ','? ')'"` +} diff --git a/pkg/buildscript/raw_test.go b/pkg/buildscript/raw_test.go new file mode 100644 index 0000000000..a19a7e3f55 --- /dev/null +++ b/pkg/buildscript/raw_test.go @@ -0,0 +1,277 @@ +package buildscript + +import ( + "testing" + "time" + + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/go-openapi/strfmt" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const testProject = "https://platform.activestate.com/org/project?branch=main&commitID=00000000-0000-0000-0000-000000000000" +const testTime = "2000-01-01T00:00:00Z" + +func checkoutInfoString(project, time string) string { + return "```\n" + + "Project: " + project + "\n" + + "Time: " + time + "\n" + + "```\n" +} + +var testCheckoutInfo string + +func init() { + testCheckoutInfo = checkoutInfoString(testProject, testTime) +} + +func TestRawRepresentation(t *testing.T) { + script, err := Unmarshal([]byte( + testCheckoutInfo + ` +runtime = solve( + at_time = TIME, + platforms = ["linux", "windows"], + requirements = [ + Req(name = "python", namespace = "language"), + Req(name = "requests", namespace = "language/python", version = Eq(value = "3.10.10")) + ], + solver_version = null +) + +main = runtime +`)) + require.NoError(t, err) + + atTimeStrfmt, err := strfmt.ParseDateTime("2000-01-01T00:00:00Z") + require.NoError(t, err) + atTime := time.Time(atTimeStrfmt) + + assert.Equal(t, &rawBuildScript{ + Info: ptr.To(testCheckoutInfo[2 : len(testCheckoutInfo)-3]), + Assignments: []*assignment{ + {"runtime", &value{ + FuncCall: &funcCall{"solve", []*value{ + {Assignment: &assignment{"at_time", &value{Ident: ptr.To(`TIME`)}}}, + {Assignment: &assignment{ + "platforms", &value{List: &[]*value{ + {Str: ptr.To(`linux`)}, + {Str: ptr.To(`windows`)}, + }}, + }}, + {Assignment: &assignment{ + "requirements", &value{List: &[]*value{ + {FuncCall: &funcCall{ + Name: "Req", + Arguments: []*value{ + {Assignment: &assignment{"name", &value{Str: ptr.To("python")}}}, + {Assignment: &assignment{"namespace", &value{Str: ptr.To("language")}}}, + }}}, + {FuncCall: &funcCall{ + Name: "Req", + Arguments: []*value{ + {Assignment: &assignment{"name", &value{Str: ptr.To("requests")}}}, + {Assignment: &assignment{"namespace", &value{Str: ptr.To("language/python")}}}, + {Assignment: &assignment{ + "version", &value{FuncCall: &funcCall{ + Name: "Eq", + Arguments: []*value{ + {Assignment: &assignment{"value", &value{Str: ptr.To("3.10.10")}}}, + }, + }}, + }}, + }, + }}, + }}, + }}, + {Assignment: &assignment{"solver_version", &value{Null: &null{}}}}, + }}, + }}, + {"main", &value{Ident: ptr.To("runtime")}}, + }, + }, script.raw) + + assert.Equal(t, testProject, script.Project()) + assert.Equal(t, &atTime, script.AtTime()) +} + +func TestComplex(t *testing.T) { + script, err := Unmarshal([]byte( + testCheckoutInfo + ` +linux_runtime = solve( + at_time = TIME, + requirements=[ + Req(name = "python", namespace = "language") + ], + platforms=["67890"] +) + +win_runtime = solve( + at_time = TIME, + requirements=[ + Req(name = "perl", namespace = "language") + ], + platforms=["12345"] +) + +main = merge( + win_installer(win_runtime), + tar_installer(linux_runtime) +) +`)) + require.NoError(t, err) + + atTimeStrfmt, err := strfmt.ParseDateTime("2000-01-01T00:00:00Z") + require.NoError(t, err) + atTime := time.Time(atTimeStrfmt) + + assert.Equal(t, &rawBuildScript{ + Info: ptr.To(testCheckoutInfo[2 : len(testCheckoutInfo)-3]), + Assignments: []*assignment{ + {"linux_runtime", &value{ + FuncCall: &funcCall{"solve", []*value{ + {Assignment: &assignment{"at_time", &value{Ident: ptr.To(`TIME`)}}}, + {Assignment: &assignment{ + "requirements", &value{List: &[]*value{ + {FuncCall: &funcCall{ + Name: "Req", + Arguments: []*value{ + {Assignment: &assignment{"name", &value{Str: ptr.To("python")}}}, + {Assignment: &assignment{"namespace", &value{Str: ptr.To("language")}}}, + }, + }}, + }}, + }}, + {Assignment: &assignment{ + "platforms", &value{List: &[]*value{{Str: ptr.To(`67890`)}}}, + }}, + }}, + }}, + {"win_runtime", &value{ + FuncCall: &funcCall{"solve", []*value{ + {Assignment: &assignment{"at_time", &value{Ident: ptr.To(`TIME`)}}}, + {Assignment: &assignment{ + "requirements", &value{List: &[]*value{ + {FuncCall: &funcCall{ + Name: "Req", + Arguments: []*value{ + {Assignment: &assignment{"name", &value{Str: ptr.To("perl")}}}, + {Assignment: &assignment{"namespace", &value{Str: ptr.To("language")}}}, + }, + }}, + }}, + }}, + {Assignment: &assignment{ + "platforms", &value{List: &[]*value{{Str: ptr.To(`12345`)}}}, + }}, + }}, + }}, + {"main", &value{ + FuncCall: &funcCall{"merge", []*value{ + {FuncCall: &funcCall{"win_installer", []*value{{Ident: ptr.To("win_runtime")}}}}, + {FuncCall: &funcCall{"tar_installer", []*value{{Ident: ptr.To("linux_runtime")}}}}, + }}}}, + }, + }, script.raw) + + assert.Equal(t, testProject, script.Project()) + assert.Equal(t, &atTime, script.AtTime()) +} + +func TestComplexVersions(t *testing.T) { + checkoutInfo := checkoutInfoString(testProject, "2023-04-27T17:30:05.999Z") + script, err := Unmarshal([]byte( + checkoutInfo + ` +runtime = solve( + at_time = TIME, + platforms = ["96b7e6f2-bebf-564c-bc1c-f04482398f38", "96b7e6f2-bebf-564c-bc1c-f04482398f38"], + requirements = [ + Req(name = "python", namespace = "language"), + Req(name = "requests", namespace = "language/python", version = Eq(value = "3.10.10")), + Req(name = "argparse", namespace = "language/python", version = And(left = Gt(value = "1.0"), right = Lt(value = "2.0"))) + ], + solver_version = 0 +) + +main = runtime +`)) + require.NoError(t, err) + + atTimeStrfmt, err := strfmt.ParseDateTime("2023-04-27T17:30:05.999Z") + require.NoError(t, err) + atTime := time.Time(atTimeStrfmt) + + assert.Equal(t, &rawBuildScript{ + Info: ptr.To(checkoutInfo[2 : len(checkoutInfo)-3]), + Assignments: []*assignment{ + {"runtime", &value{ + FuncCall: &funcCall{"solve", []*value{ + {Assignment: &assignment{"at_time", &value{Ident: ptr.To(`TIME`)}}}, + {Assignment: &assignment{ + "platforms", &value{List: &[]*value{ + {Str: ptr.To(`96b7e6f2-bebf-564c-bc1c-f04482398f38`)}, + {Str: ptr.To(`96b7e6f2-bebf-564c-bc1c-f04482398f38`)}, + }}, + }}, + {Assignment: &assignment{ + "requirements", &value{List: &[]*value{ + {FuncCall: &funcCall{ + Name: "Req", + Arguments: []*value{ + {Assignment: &assignment{"name", &value{Str: ptr.To("python")}}}, + {Assignment: &assignment{"namespace", &value{Str: ptr.To("language")}}}, + }, + }}, + {FuncCall: &funcCall{ + Name: "Req", + Arguments: []*value{ + {Assignment: &assignment{"name", &value{Str: ptr.To("requests")}}}, + {Assignment: &assignment{"namespace", &value{Str: ptr.To("language/python")}}}, + {Assignment: &assignment{ + "version", &value{FuncCall: &funcCall{ + Name: "Eq", + Arguments: []*value{ + {Assignment: &assignment{Key: "value", Value: &value{Str: ptr.To("3.10.10")}}}, + }, + }}, + }}, + }, + }}, + {FuncCall: &funcCall{ + Name: "Req", + Arguments: []*value{ + {Assignment: &assignment{"name", &value{Str: ptr.To("argparse")}}}, + {Assignment: &assignment{"namespace", &value{Str: ptr.To("language/python")}}}, + {Assignment: &assignment{ + "version", &value{FuncCall: &funcCall{ + Name: "And", + Arguments: []*value{ + {Assignment: &assignment{Key: "left", Value: &value{FuncCall: &funcCall{ + Name: "Gt", + Arguments: []*value{ + {Assignment: &assignment{Key: "value", Value: &value{Str: ptr.To("1.0")}}}, + }, + }}}}, + {Assignment: &assignment{Key: "right", Value: &value{FuncCall: &funcCall{ + Name: "Lt", + Arguments: []*value{ + {Assignment: &assignment{Key: "value", Value: &value{Str: ptr.To("2.0")}}}, + }, + }}}}, + }, + }}, + }}, + }, + }}, + }}, + }}, + {Assignment: &assignment{"solver_version", &value{Number: ptr.To(float64(0))}}}, + }}, + }}, + {"main", &value{Ident: ptr.To("runtime")}}, + }, + }, script.raw) + + assert.Equal(t, testProject, script.Project()) + assert.Equal(t, &atTime, script.AtTime()) +} diff --git a/pkg/buildscript/shared_test.go b/pkg/buildscript/shared_test.go deleted file mode 100644 index 80a5342c45..0000000000 --- a/pkg/buildscript/shared_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package buildscript - -import "fmt" - -var atTime = "2000-01-01T00:00:00.000Z" - -var basicBuildScript = []byte(fmt.Sprintf( - `at_time = "%s" -runtime = state_tool_artifacts( - src = sources -) -sources = solve( - at_time = at_time, - platforms = [ - "12345", - "67890" - ], - requirements = [ - Req(name = "python", namespace = "language", version = Eq(value = "3.10.10")) - ] -) - -main = runtime`, atTime)) - -var basicBuildExpression = []byte(`{ - "let": { - "in": "$runtime", - "runtime": { - "state_tool_artifacts": { - "src": "$sources" - } - }, - "sources": { - "solve": { - "at_time": "$at_time", - "platforms": [ - "12345", - "67890" - ], - "requirements": [ - { - "name": "python", - "namespace": "language", - "version_requirements": [ - { - "comparator": "eq", - "version": "3.10.10" - } - ] - } - ] - } - } - } -}`) diff --git a/pkg/buildscript/internal/buildexpression/testdata/buildexpression-alternate.json b/pkg/buildscript/testdata/buildexpression-alternate.json similarity index 100% rename from pkg/buildscript/internal/buildexpression/testdata/buildexpression-alternate.json rename to pkg/buildscript/testdata/buildexpression-alternate.json diff --git a/pkg/buildscript/internal/buildexpression/testdata/buildexpression-complex.json b/pkg/buildscript/testdata/buildexpression-complex.json similarity index 100% rename from pkg/buildscript/internal/buildexpression/testdata/buildexpression-complex.json rename to pkg/buildscript/testdata/buildexpression-complex.json diff --git a/pkg/buildscript/internal/buildexpression/testdata/buildexpression-installer-complex.json b/pkg/buildscript/testdata/buildexpression-installer-complex.json similarity index 100% rename from pkg/buildscript/internal/buildexpression/testdata/buildexpression-installer-complex.json rename to pkg/buildscript/testdata/buildexpression-installer-complex.json diff --git a/pkg/buildscript/internal/buildexpression/testdata/buildexpression-installer.json b/pkg/buildscript/testdata/buildexpression-installer.json similarity index 100% rename from pkg/buildscript/internal/buildexpression/testdata/buildexpression-installer.json rename to pkg/buildscript/testdata/buildexpression-installer.json diff --git a/pkg/buildscript/internal/buildexpression/testdata/buildexpression-nested.json b/pkg/buildscript/testdata/buildexpression-nested.json similarity index 100% rename from pkg/buildscript/internal/buildexpression/testdata/buildexpression-nested.json rename to pkg/buildscript/testdata/buildexpression-nested.json diff --git a/pkg/buildscript/testdata/buildexpression-new-objects.json b/pkg/buildscript/testdata/buildexpression-new-objects.json new file mode 100644 index 0000000000..74207d4e9a --- /dev/null +++ b/pkg/buildscript/testdata/buildexpression-new-objects.json @@ -0,0 +1,35 @@ +{ + "let": { + "runtime": { + "state_tool_artifacts_v1": { + "build_flags": [], + "src": "$sources" + } + }, + "sources": { + "solve": { + "at_time": "$at_time", + "platforms": [ + "0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a", + "78977bc8-0f32-519d-80f3-9043f059398c", + "96b7e6f2-bebf-564c-bc1c-f04482398f38" + ], + "requirements": [ + { + "Req": { + "name": "python", + "namespace": "language", + "version": { + "Eq": { + "value": "3.10.10" + } + } + } + } + ], + "solver_version": null + } + }, + "in": "$runtime" + } +} \ No newline at end of file diff --git a/pkg/buildscript/testdata/buildexpression-roundtrip-legacy.json b/pkg/buildscript/testdata/buildexpression-roundtrip-legacy.json new file mode 100644 index 0000000000..08212c58af --- /dev/null +++ b/pkg/buildscript/testdata/buildexpression-roundtrip-legacy.json @@ -0,0 +1,43 @@ +{ + "let": { + "sources": { + "solve": { + "at_time": "2024-10-15T16:37:06.260Z", + "solver_version": null, + "platforms": [ + "46a5b48f-226a-4696-9746-ba4d50d661c2", + "78977bc8-0f32-519d-80f3-9043f059398c", + "7c998ec2-7491-4e75-be4d-8885800ef5f2" + ], + "requirements": [ + { + "name": "community_artifact", + "namespace": "internal" + }, + { + "name": "python", + "namespace": "language", + "version_requirements": [ + { + "comparator": "eq", + "version": "3.11.10" + } + ] + } + ] + } + }, + "artifacts": { + "community_artifacts": { + "src": "$sources" + } + }, + "runtime": { + "state_tool_artifacts": { + "src": "$artifacts", + "build_flags": [] + } + }, + "in": "$runtime" + } +} \ No newline at end of file diff --git a/pkg/buildscript/internal/buildexpression/testdata/buildexpression-unordered.json b/pkg/buildscript/testdata/buildexpression-unordered.json similarity index 100% rename from pkg/buildscript/internal/buildexpression/testdata/buildexpression-unordered.json rename to pkg/buildscript/testdata/buildexpression-unordered.json diff --git a/pkg/buildscript/internal/buildexpression/testdata/buildexpression.json b/pkg/buildscript/testdata/buildexpression.json similarity index 100% rename from pkg/buildscript/internal/buildexpression/testdata/buildexpression.json rename to pkg/buildscript/testdata/buildexpression.json diff --git a/pkg/buildscript/testdata/buildexpression_rev.json b/pkg/buildscript/testdata/buildexpression_rev.json new file mode 100644 index 0000000000..ebf042c9ab --- /dev/null +++ b/pkg/buildscript/testdata/buildexpression_rev.json @@ -0,0 +1,24 @@ +{ + "let": { + "runtime": { + "solve_legacy": { + "at_time": "$at_time", + "build_flags": [], + "camel_flags": [], + "platforms": [ + "96b7e6f2-bebf-564c-bc1c-f04482398f38" + ], + "requirements": [ + { + "Revision": { + "name": "revision-pkg", + "revision_id": "00000000-0000-0000-0000-000000000000" + } + } + ], + "solver_version": null + } + }, + "in": "$runtime" + } +} diff --git a/pkg/buildscript/unmarshal.go b/pkg/buildscript/unmarshal.go new file mode 100644 index 0000000000..5382e135e5 --- /dev/null +++ b/pkg/buildscript/unmarshal.go @@ -0,0 +1,87 @@ +package buildscript + +import ( + "errors" + "strings" + "time" + + "github.com/alecthomas/participle/v2" + "github.com/go-openapi/strfmt" + "gopkg.in/yaml.v2" + + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" +) + +const atTimeKey = "at_time" + +var ErrOutdatedAtTime = errs.New("outdated at_time on top") + +type checkoutInfo struct { + Project string `yaml:"Project"` + Time string `yaml:"Time"` +} + +// Unmarshal returns a structured form of the given AScript (on-disk format). +func Unmarshal(data []byte) (*BuildScript, error) { + parser, err := participle.Build[rawBuildScript](participle.Unquote()) + if err != nil { + return nil, errs.Wrap(err, "Could not create parser for build script") + } + + raw, err := parser.ParseBytes(constants.BuildScriptFileName, data) + if err != nil { + var parseError participle.Error + if errors.As(err, &parseError) { + return nil, locale.WrapExternalError(err, "err_parse_buildscript_bytes", "Could not parse build script: {{.V0}}: {{.V1}}", parseError.Position().String(), parseError.Message()) + } + return nil, locale.WrapError(err, "err_parse_buildscript_bytes", "Could not parse build script: {{.V0}}", err.Error()) + } + + // If 'at_time' is among the list of assignments, this is an outdated build script, so error out. + for _, assignment := range raw.Assignments { + if assignment.Key != atTimeKey { + continue + } + return nil, ErrOutdatedAtTime + } + + // Verify there are no duplicate key assignments. + // This is primarily to catch duplicate solve nodes for a given target. + seen := make(map[string]bool) + for _, assignment := range raw.Assignments { + if _, exists := seen[assignment.Key]; exists { + return nil, locale.NewInputError(locale.Tl("err_buildscript_duplicate_keys", "Build script has duplicate '{{.V0}}' assignments", assignment.Key)) + } + seen[assignment.Key] = true + } + + var project string + var atTime *time.Time + if raw.Info != nil { + info := checkoutInfo{} + + err := yaml.Unmarshal([]byte(strings.Trim(*raw.Info, "`\n")), &info) + if err != nil { + return nil, locale.NewInputError( + "err_buildscript_checkoutinfo", + "Could not parse checkout information in the buildscript. The parser produced the following error: {{.V0}}", err.Error()) + } + + project = info.Project + + atTimeVal, err := time.Parse(time.RFC3339, info.Time) + if err != nil { + // Older buildscripts used microsecond specificity + atDateTime, err := strfmt.ParseDateTime(info.Time) + if err != nil { + return nil, errs.Wrap(err, "Invalid timestamp: %s", info.Time) + } + atTimeVal = time.Time(atDateTime) + } + atTime = &atTimeVal + } + + return &BuildScript{raw, project, atTime}, nil +} diff --git a/pkg/buildscript/unmarshal_buildexpression.go b/pkg/buildscript/unmarshal_buildexpression.go new file mode 100644 index 0000000000..0323da3514 --- /dev/null +++ b/pkg/buildscript/unmarshal_buildexpression.go @@ -0,0 +1,418 @@ +package buildscript + +import ( + "encoding/json" + "errors" + "sort" + "strings" + "time" + + "golang.org/x/text/cases" + "golang.org/x/text/language" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/rtutils/ptr" + "github.com/ActiveState/cli/internal/sliceutils" + "github.com/go-openapi/strfmt" +) + +// At this time, there is no way to ask the Platform for an empty build expression. +const emptyBuildExpression = `{ + "let": { + "sources": { + "solve": { + "at_time": "$at_time", + "platforms": [], + "requirements": [], + "solver_version": null + } + }, + "runtime": { + "state_tool_artifacts": { + "src": "$sources" + } + }, + "in": "$runtime" + } +}` + +const ( + letKey = "let" + inKey = "in" +) + +// UnmarshalBuildExpression returns a BuildScript constructed from the given build expression in +// JSON format. +// Build scripts and build expressions are almost identical, with the exception of the atTime field. +// Build expressions ALWAYS set at_time to `$at_time`, which refers to the timestamp on the commit, +// while buildscripts encode this timestamp as part of their definition. For this reason we have +// to supply the timestamp as a separate argument. +func (b *BuildScript) UnmarshalBuildExpression(data []byte) error { + expr := make(map[string]interface{}) + err := json.Unmarshal(data, &expr) + if err != nil { + return errs.Wrap(err, "Could not unmarshal build expression") + } + + let, ok := expr[letKey].(map[string]interface{}) + if !ok { + return errs.New("Invalid build expression: 'let' value is not an object") + } + + var path []string + assignments, err := unmarshalAssignments(path, let) + if err != nil { + return errs.Wrap(err, "Could not parse assignments") + } + b.raw.Assignments = assignments + + // Extract the 'at_time' from the solve node, if it exists, and change its value to be a + // reference to "TIME", which is how we want to show it in AScript format. + if atTimeNode, err := b.getSolveAtTimeValue(); err == nil { + if atTimeNode.Str != nil && !strings.HasPrefix(*atTimeNode.Str, `$`) { + atTime, err := strfmt.ParseDateTime(*atTimeNode.Str) + if err != nil { + return errs.Wrap(err, "Invalid timestamp: %s", *atTimeNode.Str) + } + atTimeNode.Str = nil + atTimeNode.Ident = ptr.To("TIME") + // Preserve the original at_time found in the solve node. + b.SetAtTime(time.Time(atTime), true) + } else if atTimeNode.Ident != nil && *atTimeNode.Ident == "at_time" { + atTimeNode.Ident = ptr.To("TIME") + } + } else if err != nil && !errors.Is(err, errNodeNotFound) { + return errs.Wrap(err, "Could not get at_time node") + } + + b.raw.transformToRequirementFuncs() + + return nil +} + +const ( + ctxAssignments = "assignments" + ctxValue = "value" + ctxFuncCall = "funcCall" + ctxFuncDef = "funcDef" + ctxIn = "in" +) + +func unmarshalAssignments(path []string, m map[string]interface{}) ([]*assignment, error) { + path = append(path, ctxAssignments) + + assignments := []*assignment{} + for key, valueInterface := range m { + var value *value + var err error + if key != inKey { + value, err = unmarshalValue(path, valueInterface) + } else { + if value, err = unmarshalIn(path, valueInterface); err == nil { + key = mainKey // rename + } + } + if err != nil { + return nil, errs.Wrap(err, "Could not parse '%s' key's value: %v", key, valueInterface) + } + assignments = append(assignments, &assignment{key, value}) + } + + sort.SliceStable(assignments, func(i, j int) bool { + return assignments[i].Key < assignments[j].Key + }) + return assignments, nil +} + +func unmarshalValue(path []string, valueInterface interface{}) (*value, error) { + path = append(path, ctxValue) + + result := &value{} + + switch v := valueInterface.(type) { + case map[string]interface{}: + // Examine keys first to see if this is a function call. + for key, val := range v { + if _, ok := val.(map[string]interface{}); !ok { + continue + } + + // If the length of the value is greater than 1, + // then it's not a function call. It's an object + // and will be set as such outside the loop. + if len(v) > 1 { + continue + } + + if isFuncCall(path, val.(map[string]interface{})) { + f, err := unmarshalFuncCall(path, v) + if err != nil { + return nil, errs.Wrap(err, "Could not parse '%s' function's value: %v", key, v) + } + result.FuncCall = f + } + } + + // It's not a function call, but an object. + if result.FuncCall == nil { + object, err := unmarshalAssignments(path, v) + if err != nil { + return nil, errs.Wrap(err, "Could not parse object: %v", v) + } + result.Object = &object + } + + case []interface{}: + values := []*value{} + for _, item := range v { + value, err := unmarshalValue(path, item) + if err != nil { + return nil, errs.Wrap(err, "Could not parse list: %v", v) + } + values = append(values, value) + } + result.List = &values + + case string: + parentNode, hasParentNode := sliceutils.GetString(path, -2) + if (hasParentNode && parentNode == ctxIn) || strings.HasPrefix(v, "$") { + result.Ident = ptr.To(strings.TrimPrefix(v, "$")) + } else { + result.Str = ptr.To(v) + } + + case float64: + result.Number = ptr.To(v) + + case nil: + result.Null = &null{} + + default: + logging.Debug("Unknown type: %T at path %s", v, strings.Join(path, ".")) + result.Null = &null{} + } + + return result, nil +} + +func isFuncCall(path []string, value map[string]interface{}) bool { + path = append(path, ctxFuncDef) + + _, hasIn := value[inKey] + return !hasIn || sliceutils.Contains(path, ctxAssignments) +} + +func unmarshalFuncCall(path []string, fc map[string]interface{}) (*funcCall, error) { + path = append(path, ctxFuncCall) + + // m is a mapping of function name to arguments. There should only be one + // set of arguments. Since the arguments are key-value pairs, it should be + // a map[string]interface{}. + if len(fc) > 1 { + return nil, errs.New("Function call has more than one argument mapping") + } + + // Look in the given object for the function's name and argument mapping. + var name string + var argsInterface interface{} + for key, value := range fc { + if _, ok := value.(map[string]interface{}); !ok { + return nil, errs.New("Incorrect argument format") + } + + name = key + argsInterface = value + break // technically this is not needed since there's only one element in m + } + + args := []*value{} + + switch v := argsInterface.(type) { + case map[string]interface{}: + for key, valueInterface := range v { + uv, err := unmarshalValue(path, valueInterface) + if err != nil { + return nil, errs.Wrap(err, "Could not parse '%s' function's argument '%s': %v", name, key, valueInterface) + } + args = append(args, &value{Assignment: &assignment{key, uv}}) + } + sort.SliceStable(args, func(i, j int) bool { return args[i].Assignment.Key < args[j].Assignment.Key }) + + case []interface{}: + for _, item := range v { + value, err := unmarshalValue(path, item) + if err != nil { + return nil, errs.Wrap(err, "Could not parse '%s' function's argument list item: %v", name, item) + } + args = append(args, value) + } + + default: + return nil, errs.New("Function '%s' expected to be object or list", name) + } + + return &funcCall{Name: name, Arguments: args}, nil +} + +func unmarshalIn(path []string, inValue interface{}) (*value, error) { + path = append(path, ctxIn) + + in := &value{} + + switch v := inValue.(type) { + case map[string]interface{}: + f, err := unmarshalFuncCall(path, v) + if err != nil { + return nil, errs.Wrap(err, "'in' object is not a function call") + } + in.FuncCall = f + + case string: + in.Ident = ptr.To(strings.TrimPrefix(v, "$")) + + default: + return nil, errs.New("'in' value expected to be a function call or string") + } + + return in, nil +} + +// isObjectList returns whether or not the given value is a list containing objects +func isObjectList(value *value) bool { + return value.List != nil && len(*value.List) > 0 && (*value.List)[0].Object != nil +} + +// transformRequirements transforms a build expression list of requirements in object form into a +// list of requirements in function-call form, which is how requirements are represented in +// buildscripts. +func transformRequirements(reqs *value) *value { + newReqs := []*value{} + for _, req := range *reqs.List { + newReqs = append(newReqs, transformRequirement(req)) + } + return &value{List: &newReqs} +} + +// transformRequirement transforms a build expression requirement in object form into a requirement +// in function-call form. +// For example, transform something like +// +// {"name": "", "namespace": "", +// "version_requirements": [{"comparator": "", "version": ""}]} +// +// into something like +// +// Req(name = "", namespace = "", version = (value = "")) +func transformRequirement(req *value) *value { + args := []*value{} + + for _, arg := range *req.Object { + key := arg.Key + v := arg.Value + + // Transform the version value from the requirement object. + if key == requirementVersionRequirementsKey { + key = requirementVersionKey + v = &value{FuncCall: transformVersion(arg)} + } + + // Add the argument to the function transformation. + args = append(args, &value{Assignment: &assignment{key, v}}) + } + + return &value{FuncCall: &funcCall{reqFuncName, args}} +} + +// transformVersion transforms a build expression version_requirements list in object form into +// function-call form. +// For example, transform something like +// +// [{"comparator": "", "version": ""}, {"comparator": "", "version": ""}] +// +// into something like +// +// And((value = ""), (value = "")) +func transformVersion(requirements *assignment) *funcCall { + var funcs []*funcCall + for _, constraint := range *requirements.Value.List { + f := &funcCall{} + for _, o := range *constraint.Object { + switch o.Key { + case requirementVersionKey: + f.Arguments = []*value{ + {Assignment: &assignment{"value", o.Value}}, + } + case requirementComparatorKey: + f.Name = cases.Title(language.English).String(*o.Value.Str) + } + } + funcs = append(funcs, f) + } + + if len(funcs) == 1 { + return funcs[0] // e.g. Eq(value = "1.0") + } + + // e.g. And(left = Gt(value = "1.0"), right = Lt(value = "3.0")) + // Iterate backwards over the requirements array and construct a binary tree of 'And()' functions. + // For example, given [Gt(value = "1.0"), Ne(value = "2.0"), Lt(value = "3.0")], produce: + // And(left = Gt(value = "1.0"), right = And(left = Ne(value = "2.0"), right = Lt(value = "3.0"))) + var f *funcCall + for i := len(funcs) - 2; i >= 0; i-- { + right := &value{FuncCall: funcs[i+1]} + if f != nil { + right = &value{FuncCall: f} + } + args := []*value{ + {Assignment: &assignment{"left", &value{FuncCall: funcs[i]}}}, + {Assignment: &assignment{"right", right}}, + } + f = &funcCall{andFuncName, args} + } + return f +} + +type requirementFunction struct { + FunctionName string + RequirementArguments []string +} + +// requirementFunctions holds the function names and arguments that hold objects which need to be translated to +// requirement functions (eg. `solve(requirements=..)`). +var requirementFunctions = []requirementFunction{ + {solveFuncName, []string{requirementsKey}}, + {solveLegacyFuncName, []string{requirementsKey}}, + {"ingredient", []string{"build_deps", "runtime_deps", "test_deps"}}, +} + +// transformToRequirementFuncs will look object assignments that need to be converted to requirement functions +// this works off of the defined requirementFunctions above. +func (r *rawBuildScript) transformToRequirementFuncs() { + // Iterate over the function calls within the buildscript + for _, functionCall := range r.FuncCalls() { + + // Find a matching requirement function + for _, reqFunction := range requirementFunctions { + if functionCall.Name != reqFunction.FunctionName { + continue + } + + // Find a matching requirement argument + for _, arg := range functionCall.Arguments { + if arg.Assignment == nil { + continue + } + for _, reqArgument := range reqFunction.RequirementArguments { + if arg.Assignment.Key == reqArgument { + + // Convert the argument to requirement functions + if isObjectList(arg.Assignment.Value) { + arg.Assignment.Value.List = transformRequirements(arg.Assignment.Value).List + } + } + } + } + } + } +} diff --git a/pkg/buildscript/unmarshal_buildexpression_test.go b/pkg/buildscript/unmarshal_buildexpression_test.go new file mode 100644 index 0000000000..ef20550c0d --- /dev/null +++ b/pkg/buildscript/unmarshal_buildexpression_test.go @@ -0,0 +1,99 @@ +package buildscript + +import ( + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/ActiveState/cli/internal/environment" + "github.com/ActiveState/cli/internal/fileutils" +) + +// TestUnmarshalBuildExpression tests that we can successfully read and convert Platform +// build expressions into build scripts. +func TestUnmarshalBuildExpression(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "basic", + args: args{ + filename: "buildexpression.json", + }, + wantErr: false, + }, + { + name: "complex", + args: args{ + filename: "buildexpression-complex.json", + }, + wantErr: false, + }, + { + name: "unordered", + args: args{ + filename: "buildexpression-unordered.json", + }, + wantErr: false, + }, + { + name: "installer", + args: args{ + filename: "buildexpression-installer.json", + }, + wantErr: false, + }, + { + name: "installer-complex", + args: args{ + filename: "buildexpression-installer-complex.json", + }, + wantErr: false, + }, + { + name: "nested", + args: args{ + filename: "buildexpression-nested.json", + }, + wantErr: false, + }, + { + name: "alternate", + args: args{ + filename: "buildexpression-alternate.json", + }, + wantErr: false, + }, + { + name: "newObjects", + args: args{ + filename: "buildexpression-new-objects.json", + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wd, err := environment.GetRootPath() + assert.NoError(t, err) + + data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "buildscript", "testdata", tt.args.filename)) + assert.NoError(t, err) + + script := New() + { + err := script.UnmarshalBuildExpression(data) + if (err != nil) != tt.wantErr { + t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr) + return + } + } + }) + } +} diff --git a/pkg/platform/runtime/executors/execmeta/execmeta.go b/pkg/executors/execmeta/execmeta.go similarity index 100% rename from pkg/platform/runtime/executors/execmeta/execmeta.go rename to pkg/executors/execmeta/execmeta.go diff --git a/pkg/platform/runtime/executors/execmeta/execmeta_test.go b/pkg/executors/execmeta/execmeta_test.go similarity index 100% rename from pkg/platform/runtime/executors/execmeta/execmeta_test.go rename to pkg/executors/execmeta/execmeta_test.go diff --git a/pkg/platform/runtime/executors/executors.go b/pkg/executors/executors.go similarity index 85% rename from pkg/platform/runtime/executors/executors.go rename to pkg/executors/executors.go index 052e082f6a..092649e0ef 100644 --- a/pkg/platform/runtime/executors/executors.go +++ b/pkg/executors/executors.go @@ -6,13 +6,12 @@ import ( rt "runtime" "strings" + "github.com/ActiveState/cli/pkg/executors/execmeta" "github.com/ActiveState/cli/pkg/project" + "github.com/go-openapi/strfmt" "github.com/ActiveState/cli/internal/installation" "github.com/ActiveState/cli/internal/osutils" - "github.com/ActiveState/cli/pkg/platform/runtime/envdef" - "github.com/ActiveState/cli/pkg/platform/runtime/executors/execmeta" - "github.com/go-openapi/strfmt" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" @@ -20,11 +19,36 @@ import ( "github.com/ActiveState/cli/internal/logging" ) -type Targeter interface { - CommitUUID() strfmt.UUID - Name() string - Owner() string - Dir() string +type Target struct { + commitUUID strfmt.UUID + owner string + name string + dir string +} + +func NewTarget(commitUUID strfmt.UUID, owner, name, dir string) Target { + return Target{ + commitUUID: commitUUID, + owner: owner, + name: name, + dir: dir, + } +} + +func (t *Target) CommitUUID() strfmt.UUID { + return t.commitUUID +} + +func (t *Target) Owner() string { + return t.owner +} + +func (t *Target) Name() string { + return t.name +} + +func (t *Target) Dir() string { + return t.dir } type Executors struct { @@ -50,8 +74,8 @@ func (es *Executors) SetExecutorSrc(path string) { es.altExecSrcPath = path } -func (es *Executors) Apply(sockPath string, targeter Targeter, env map[string]string, exes envdef.ExecutablePaths) error { - logging.Debug("Creating executors at %s, exes: %v", es.executorPath, exes) +func (es *Executors) Apply(sockPath string, target Target, env map[string]string, exes []string) error { + logging.Debug("Creating executors at %s", es.executorPath) executors := make(map[string]string) // map[alias]dest for _, dest := range exes { @@ -66,11 +90,11 @@ func (es *Executors) Apply(sockPath string, targeter Targeter, env map[string]st return locale.WrapError(err, "err_mkdir", "Could not create directory: {{.V0}}", es.executorPath) } - ns := project.NewNamespace(targeter.Owner(), targeter.Name(), "") + ns := project.NewNamespace(target.Owner(), target.Name(), "") t := execmeta.Target{ - CommitUUID: targeter.CommitUUID().String(), + CommitUUID: target.CommitUUID().String(), Namespace: ns.String(), - Dir: targeter.Dir(), + Dir: target.Dir(), } m := execmeta.New(sockPath, osutils.EnvMapToSlice(env), t, executors) if err := m.WriteToDisk(es.executorPath); err != nil { @@ -159,8 +183,6 @@ func copyExecutor(destDir, executor, srcExec string) error { name := filepath.Base(executor) target := filepath.Clean(filepath.Join(destDir, name)) - logging.Debug("Creating executor for %s at %s", name, target) - if fileutils.TargetExists(target) { b, err := fileutils.ReadFile(target) if err != nil { diff --git a/pkg/platform/runtime/executors/executors_test.go b/pkg/executors/executors_test.go similarity index 92% rename from pkg/platform/runtime/executors/executors_test.go rename to pkg/executors/executors_test.go index 0ed2b45475..a97142bf1d 100644 --- a/pkg/platform/runtime/executors/executors_test.go +++ b/pkg/executors/executors_test.go @@ -10,7 +10,6 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/pkg/platform/runtime/target" ) func TestExecutor(t *testing.T) { @@ -24,8 +23,9 @@ func TestExecutor(t *testing.T) { err = fileutils.WriteFile(dummyExecSrc, dummyExecData) require.NoError(t, err, errs.JoinMessage(err)) - target := target.NewCustomTarget("owner", "project", "1234abcd-1234-abcd-1234-abcd1234abcd", "dummy/path", target.NewExecTrigger("test")) + target := NewTarget("1234abcd-1234-abcd-1234-abcd1234abcd", "owner", "project", "dummy/path") execDir := filepath.Join(tmpDir, "exec") + execInit := New(execDir) execInit.altExecSrcPath = dummyExecSrc diff --git a/pkg/localcommit/localcommit.go b/pkg/localcommit/localcommit.go index dcd1c15532..9ef8a3e516 100644 --- a/pkg/localcommit/localcommit.go +++ b/pkg/localcommit/localcommit.go @@ -15,10 +15,13 @@ import ( var proj *project.Project type ErrInvalidCommitID struct { - error CommitID string } +func (e ErrInvalidCommitID) Error() string { + return "invalid commit ID" +} + func setupProject(pjpath string) error { if proj != nil && proj.Dir() == pjpath { return nil @@ -38,7 +41,7 @@ func Get(pjpath string) (strfmt.UUID, error) { commitID := proj.LegacyCommitID() if !strfmt.IsUUID(commitID) { - return "", &ErrInvalidCommitID{errs.New("Invalid commit ID"), commitID} + return "", &ErrInvalidCommitID{commitID} } return strfmt.UUID(commitID), nil diff --git a/pkg/platform/api/api.go b/pkg/platform/api/api.go index 4b2bb90e29..1ef8fca422 100644 --- a/pkg/platform/api/api.go +++ b/pkg/platform/api/api.go @@ -10,6 +10,7 @@ import ( "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/runbits/rationalize" + "github.com/ActiveState/cli/pkg/platform/api/errors" "github.com/alecthomas/template" "github.com/ActiveState/cli/pkg/sysinfo" @@ -19,7 +20,6 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/retryhttp" "github.com/ActiveState/cli/internal/singleton/uniqid" - "github.com/ActiveState/cli/pkg/platform" ) // NewHTTPClient creates a new HTTP client that will retry requests and @@ -46,11 +46,11 @@ func (r *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { resp, err := r.transport.RoundTrip(req) if err != nil && resp != nil && resp.StatusCode == http.StatusForbidden && strings.EqualFold(resp.Header.Get("server"), "cloudfront") { - return nil, platform.NewCountryBlockedError() + return nil, api_errors.NewCountryBlockedError() } // This code block is for integration testing purposes only. - if os.Getenv(constants.PlatformApiPrintRequestsEnvVarName) != "" && + if os.Getenv(constants.DebugServiceRequestsEnvVarName) != "" && (condition.OnCI() || condition.BuiltOnDevMachine()) { logging.Debug("URL: %s\n", req.URL) logging.Debug("User-Agent: %s\n", resp.Request.Header.Get("User-Agent")) diff --git a/pkg/platform/api/buildplanner/request/commit.go b/pkg/platform/api/buildplanner/request/commit.go index 80c3404fdc..366a157cac 100644 --- a/pkg/platform/api/buildplanner/request/commit.go +++ b/pkg/platform/api/buildplanner/request/commit.go @@ -29,6 +29,7 @@ query ($commitID: String!, $organization: String!, $project: String!, $target: S __typename expr commitId + parentId atTime build(target: $target) { __typename diff --git a/pkg/platform/api/buildplanner/request/stagecommit.go b/pkg/platform/api/buildplanner/request/stagecommit.go index 286b63fbd2..16b5f9d30c 100644 --- a/pkg/platform/api/buildplanner/request/stagecommit.go +++ b/pkg/platform/api/buildplanner/request/stagecommit.go @@ -35,6 +35,168 @@ mutation ($organization: String!, $project: String!, $parentCommit: ID!, $descri __typename expr commitId + build { + __typename + ... on BuildCompleted { + buildLogIds { + ... on AltBuildId { + id + } + } + } + ... on BuildStarted { + buildLogIds { + ... on AltBuildId { + id + } + } + } + ... on Build { + status + terminals { + tag + nodeIds + } + sources: nodes { + ... on Source { + nodeId + ingredientID + ingredientVersionID + revision + name + namespace + version + licenses + } + } + steps: steps { + ... on Step { + stepId + inputs { + tag + nodeIds + } + outputs + } + } + artifacts: nodes { + ... on ArtifactSucceeded { + __typename + nodeId + displayName + mimeType + generatedBy + runtimeDependencies + status + logURL + url + checksum + } + ... on ArtifactUnbuilt { + __typename + nodeId + displayName + mimeType + generatedBy + runtimeDependencies + status + } + ... on ArtifactStarted { + __typename + nodeId + displayName + mimeType + generatedBy + runtimeDependencies + status + } + ... on ArtifactTransientlyFailed { + __typename + nodeId + displayName + mimeType + generatedBy + runtimeDependencies + status + logURL + errors + attempts + nextAttemptAt + } + ... on ArtifactPermanentlyFailed { + __typename + nodeId + displayName + mimeType + generatedBy + runtimeDependencies + status + logURL + errors + } + ... on ArtifactFailed { + __typename + nodeId + displayName + mimeType + generatedBy + runtimeDependencies + status + logURL + errors + } + } + resolvedRequirements { + requirement { + name + namespace + version_requirements: versionRequirements { + comparator + version + } + } + resolvedSource + } + } + ... on Error { + message + } + ... on PlanningError { + message + subErrors { + __typename + ... on GenericSolveError { + path + message + isTransient + validationErrors { + error + jsonPath + } + } + ... on RemediableSolveError { + path + message + isTransient + errorType + validationErrors { + error + jsonPath + } + suggestedRemediations { + remediationType + command + parameters + } + } + ... on TargetNotFound { + message + requestedTarget + possibleTargets + } + } + } + } } ... on Error { __typename @@ -69,7 +231,7 @@ mutation ($organization: String!, $project: String!, $parentCommit: ID!, $descri commitId message } - ...on ValidationError { + ... on ValidationError { __typename subErrors { __typename diff --git a/pkg/platform/api/buildplanner/response/build.go b/pkg/platform/api/buildplanner/response/build.go index 5a32a87645..063cdaf7c3 100644 --- a/pkg/platform/api/buildplanner/response/build.go +++ b/pkg/platform/api/buildplanner/response/build.go @@ -15,12 +15,16 @@ type ArtifactResponse struct { } type BuildResponse struct { - Type string `json:"__typename"` - Artifacts []ArtifactResponse `json:"artifacts"` - Status string `json:"status"` *Error *PlanningError - RawMessage json.RawMessage + Type string `json:"__typename"` + Artifacts []ArtifactResponse `json:"artifacts"` + Status string `json:"status"` + RawMessage json.RawMessage `json:"rawMessage"` +} + +func (b *BuildResponse) MarshalJSON() ([]byte, error) { + return b.RawMessage.MarshalJSON() } // UnmarshalJSON lets us record both the raw json message as well as unmarshal the parts we care about diff --git a/pkg/platform/api/buildplanner/response/commit.go b/pkg/platform/api/buildplanner/response/commit.go index 44c5128055..127613883b 100644 --- a/pkg/platform/api/buildplanner/response/commit.go +++ b/pkg/platform/api/buildplanner/response/commit.go @@ -103,7 +103,7 @@ func processPlanningError(message string, subErrors []*BuildExprError) error { func ProcessProjectError(project *ProjectResponse, fallbackMessage string) error { if project.Type == types.NotFoundErrorType { return errs.AddTips( - locale.NewInputError("err_buildplanner_project_not_found", "Unable to find project, received message: {{.V0}}", project.Message), + locale.NewInputError("err_buildplanner_project_not_found", "Unable to find project. Received message: {{.V0}}", project.Message), locale.T("tip_private_project_auth"), ) } @@ -143,6 +143,7 @@ type Commit struct { AtTime strfmt.DateTime `json:"atTime"` Expression json.RawMessage `json:"expr"` CommitID strfmt.UUID `json:"commitId"` + ParentID strfmt.UUID `json:"parentId"` Build *BuildResponse `json:"build"` *Error *ParseError diff --git a/pkg/platform/api/buildplanner/response/commiterror.go b/pkg/platform/api/buildplanner/response/commiterror.go index 484a7d0f82..e5efef0793 100644 --- a/pkg/platform/api/buildplanner/response/commiterror.go +++ b/pkg/platform/api/buildplanner/response/commiterror.go @@ -24,12 +24,12 @@ func ProcessCommitError(commit *Commit, fallbackMessage string) error { case types.NotFoundErrorType: return &CommitError{ commit.Type, commit.Message, - locale.NewInputError("err_buildplanner_commit_not_found", "Could not find commit, received message: {{.V0}}", commit.Message), + locale.NewInputError("err_buildplanner_commit_not_found", "Could not find commit. Received message: {{.V0}}", commit.Message), } case types.ParseErrorType: return &CommitError{ commit.Type, commit.Message, - locale.NewInputError("err_buildplanner_parse_error", "The platform failed to parse the build expression, received message: {{.V0}}. Path: {{.V1}}", commit.Message, commit.ParseError.Path), + locale.NewInputError("err_buildplanner_parse_error", "The platform failed to parse the build expression. Received message: {{.V0}}. Path: {{.V1}}", commit.Message, commit.ParseError.Path), } case types.ValidationErrorType: var subErrorMessages []string @@ -39,17 +39,17 @@ func ProcessCommitError(commit *Commit, fallbackMessage string) error { if len(subErrorMessages) > 0 { return &CommitError{ commit.Type, commit.Message, - locale.NewInputError("err_buildplanner_validation_error_sub_messages", "The platform encountered a validation error, received message: {{.V0}}, with sub errors: {{.V1}}", commit.Message, strings.Join(subErrorMessages, ", ")), + locale.NewInputError("err_buildplanner_validation_error_sub_messages", "The platform encountered a validation error. Received message: {{.V0}}, with sub errors: {{.V1}}", commit.Message, strings.Join(subErrorMessages, ", ")), } } return &CommitError{ commit.Type, commit.Message, - locale.NewInputError("err_buildplanner_validation_error", "The platform encountered a validation error, received message: {{.V0}}", commit.Message), + locale.NewInputError("err_buildplanner_validation_error", "The platform encountered a validation error. Received message: {{.V0}}", commit.Message), } case types.ForbiddenErrorType: return &CommitError{ commit.Type, commit.Message, - locale.NewInputError("err_buildplanner_forbidden", "Operation forbidden: {{.V0}}, received message: {{.V1}}", commit.Operation, commit.Message), + locale.NewInputError("err_buildplanner_forbidden", "Operation forbidden: {{.V0}}. Received message: {{.V1}}", commit.Operation, commit.Message), } case types.HeadOnBranchMovedErrorType: return errs.Wrap(&CommitError{ diff --git a/pkg/platform/api/buildplanner/response/shared.go b/pkg/platform/api/buildplanner/response/shared.go index 51d7b64e62..627bfcb949 100644 --- a/pkg/platform/api/buildplanner/response/shared.go +++ b/pkg/platform/api/buildplanner/response/shared.go @@ -23,10 +23,10 @@ func (e *BuildPlannerError) InputError() bool { return true } -// LocalizedError returns the error message to be displayed to the user. +// LocaleError returns the error message to be displayed to the user. // This function is added so that BuildPlannerErrors will be displayed // to the user -func (e *BuildPlannerError) LocalizedError() string { +func (e *BuildPlannerError) LocaleError() string { return e.Error() } diff --git a/pkg/platform/api/buildplanner/types/commit.go b/pkg/platform/api/buildplanner/types/commit.go index f95da2a9df..cdba27da7d 100644 --- a/pkg/platform/api/buildplanner/types/commit.go +++ b/pkg/platform/api/buildplanner/types/commit.go @@ -1,6 +1,8 @@ package types import ( + "encoding/json" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" ) @@ -28,6 +30,10 @@ func (o Operation) String() string { } } +func (o *Operation) MarshalJSON() ([]byte, error) { + return json.Marshal(o.String()) +} + func (o *Operation) Unmarshal(v string) error { switch v { case mono_models.CommitChangeEditableOperationAdded: diff --git a/pkg/platform/api/buildplanner/types/requirement.go b/pkg/platform/api/buildplanner/types/requirement.go index b21a28cc09..33a7a367c5 100644 --- a/pkg/platform/api/buildplanner/types/requirement.go +++ b/pkg/platform/api/buildplanner/types/requirement.go @@ -3,7 +3,7 @@ package types type Requirement struct { Name string `json:"name"` Namespace string `json:"namespace"` - VersionRequirement []VersionRequirement `json:"version_requirements,omitempty"` + VersionRequirement []VersionRequirement `json:"-"` Revision *int `json:"revision,omitempty"` } diff --git a/pkg/platform/errors.go b/pkg/platform/api/errors/errors.go similarity index 95% rename from pkg/platform/errors.go rename to pkg/platform/api/errors/errors.go index 9854b0a8f1..4128135bef 100644 --- a/pkg/platform/errors.go +++ b/pkg/platform/api/errors/errors.go @@ -1,4 +1,4 @@ -package platform +package api_errors import ( "github.com/ActiveState/cli/internal/locale" diff --git a/pkg/platform/api/graphql/model/publish.go b/pkg/platform/api/graphql/model/publish.go index 9599ba2455..f818ef95c4 100644 --- a/pkg/platform/api/graphql/model/publish.go +++ b/pkg/platform/api/graphql/model/publish.go @@ -1,10 +1,12 @@ package model type PublishResult struct { - Publish struct { - ErrorResponse - IngredientID string `json:"ingredientID"` - IngredientVersionID string `json:"ingredientVersionID"` - Revision int `json:"revision"` - } `json:"publish"` + ErrorResponse + IngredientID string `json:"ingredientID"` + IngredientVersionID string `json:"ingredientVersionID"` + Revision int `json:"revision"` +} + +type PublishResponse struct { + Result PublishResult `json:"publish"` } diff --git a/pkg/platform/api/graphql/request/publish.go b/pkg/platform/api/graphql/request/publish.go index 61d6090228..551bdb9e06 100644 --- a/pkg/platform/api/graphql/request/publish.go +++ b/pkg/platform/api/graphql/request/publish.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "errors" + "fmt" "os" "github.com/ActiveState/cli/internal/errs" @@ -14,10 +15,12 @@ import ( "gopkg.in/yaml.v3" ) +type DependencyType string + const ( - DependencyTypeRuntime = "runtime" - DependencyTypeBuild = "build" - DependencyTypeTest = "test" + DependencyTypeRuntime DependencyType = "runtime" + DependencyTypeBuild = "build" + DependencyTypeTest = "test" ) func Publish(vars PublishVariables, filepath string) (*PublishInput, error) { @@ -85,10 +88,10 @@ type PublishVariableFeature struct { } type Dependency struct { - Name string `yaml:"name" json:"name"` - Namespace string `yaml:"namespace" json:"namespace"` - VersionRequirements string `yaml:"versionRequirements,omitempty" json:"versionRequirements,omitempty"` - Type string `yaml:"type,omitempty" json:"type,omitempty"` + Name string `yaml:"name" json:"name"` + Namespace string `yaml:"namespace" json:"namespace"` + VersionRequirements string `yaml:"versionRequirements,omitempty" json:"versionRequirements,omitempty"` + Type DependencyType `yaml:"type,omitempty" json:"type,omitempty"` } // ExampleAuthorVariables is used for presenting sample data to the user, it's not used for graphql input @@ -101,6 +104,24 @@ type ExampleDepVariables struct { Dependencies []PublishVariableDep `yaml:"dependencies,omitempty"` } +// MarshalJSON automatically takes the name and namespace and turns it into the path argument that the API expects +func (p PublishVariables) MarshalJSON() ([]byte, error) { + if p.Path == "" { + if p.Name == "" || p.Namespace == "" { + return nil, errs.New("either Path of Name and Namespace are required") + } + p.Path = fmt.Sprintf("%s/%s", p.Namespace, p.Name) + } + // prevent recursion + type Alias PublishVariables + alias := &struct { + Alias + }{ + Alias: (Alias)(p), + } + return json.Marshal(alias) +} + func (p PublishVariables) MarshalYaml(includeExample bool) ([]byte, error) { v, err := yamlcomment.Marshal(p) if err != nil { diff --git a/pkg/platform/api/reqsimport/reqsimport.go b/pkg/platform/api/reqsimport/reqsimport.go index 3f7e0dfb6a..edd9550342 100644 --- a/pkg/platform/api/reqsimport/reqsimport.go +++ b/pkg/platform/api/reqsimport/reqsimport.go @@ -8,7 +8,6 @@ import ( "path" "time" - "github.com/ActiveState/cli/internal/language" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/pkg/platform/api" @@ -69,13 +68,6 @@ func (ri *ReqsImport) Changeset(data []byte, lang string) ([]*mono_models.Commit Data: string(data), Language: lang, } - if lang == "" { - // The endpoint requires a valid language name. It is not present in the requirements read and - // returned. When coupled with "unformatted=true", the language has no bearing on the - // translation, so just pick one. - reqPayload.Language = language.Python3.Requirement() - reqPayload.Unformatted = true - } respPayload := &TranslationRespMsg{} err := postJSON(ri.client, ri.opts.ReqsvcURL, reqPayload, respPayload) diff --git a/pkg/platform/api/svc/request/cache.go b/pkg/platform/api/svc/request/cache.go new file mode 100644 index 0000000000..4a2dfc524f --- /dev/null +++ b/pkg/platform/api/svc/request/cache.go @@ -0,0 +1,47 @@ +package request + +import "time" + +type GetCache struct { + key string +} + +func NewGetCache(key string) *GetCache { + return &GetCache{key: key} +} + +func (c *GetCache) Query() string { + return `query($key: String!) { + getCache(key: $key) + }` +} + +func (c *GetCache) Vars() (map[string]interface{}, error) { + return map[string]interface{}{ + "key": c.key, + }, nil +} + +type SetCache struct { + key string + value string + expiry time.Duration +} + +func NewSetCache(key, value string, expiry time.Duration) *SetCache { + return &SetCache{key: key, value: value, expiry: expiry} +} + +func (c *SetCache) Query() string { + return `mutation($key: String!, $value: String!, $expiry: Int!) { + setCache(key: $key, value: $value, expiry: $expiry) + }` +} + +func (c *SetCache) Vars() (map[string]interface{}, error) { + return map[string]interface{}{ + "key": c.key, + "value": c.value, + "expiry": c.expiry.Seconds(), + }, nil +} diff --git a/pkg/platform/api/svc/request/fetchlogtail.go b/pkg/platform/api/svc/request/fetchlogtail.go index ecf5efe695..bcd679bf74 100644 --- a/pkg/platform/api/svc/request/fetchlogtail.go +++ b/pkg/platform/api/svc/request/fetchlogtail.go @@ -8,7 +8,7 @@ func NewFetchLogTail() *FetchLogTail { } func (r *FetchLogTail) Query() string { - return `query() { + return `query { fetchLogTail }` } diff --git a/pkg/platform/api/svc/request/hashglobs.go b/pkg/platform/api/svc/request/hashglobs.go new file mode 100644 index 0000000000..29e9077fd1 --- /dev/null +++ b/pkg/platform/api/svc/request/hashglobs.go @@ -0,0 +1,30 @@ +package request + +type HashGlobs struct { + wd string + globs []string +} + +func NewHashGlobs(wd string, globs []string) *HashGlobs { + return &HashGlobs{wd: wd, globs: globs} +} + +func (c *HashGlobs) Query() string { + return `query($wd: String!, $globs: [String!]!) { + hashGlobs(wd: $wd, globs: $globs) { + hash + files { + pattern + path + hash + } + } +}` +} + +func (c *HashGlobs) Vars() (map[string]interface{}, error) { + return map[string]interface{}{ + "wd": c.wd, + "globs": c.globs, + }, nil +} diff --git a/pkg/platform/api/svc/request/jwt.go b/pkg/platform/api/svc/request/jwt.go index eb682537bc..69926fbb20 100644 --- a/pkg/platform/api/svc/request/jwt.go +++ b/pkg/platform/api/svc/request/jwt.go @@ -8,8 +8,8 @@ func NewJWTRequest() *JWTRequest { } func (m *JWTRequest) Query() string { - return `query() { - getJWT() { + return `query { + getJWT { token user { userID diff --git a/pkg/platform/authentication/auth.go b/pkg/platform/authentication/auth.go index cd51a65592..2b0c3a7936 100644 --- a/pkg/platform/authentication/auth.go +++ b/pkg/platform/authentication/auth.go @@ -368,7 +368,7 @@ func (s *Auth) Logout() error { err := s.cfg.Set(ApiTokenConfigKey, "") if err != nil { multilog.Error("Could not clear apiToken in config") - return locale.WrapError(err, "err_logout_cfg", "Could not update config, if this persists please try running '[ACTIONABLE]state clean config[/RESET]'.") + return locale.WrapError(err, "err_logout_cfg", "Could not update config. If this persists please try running '[ACTIONABLE]state clean config[/RESET]'.") } s.resetSession() diff --git a/pkg/platform/model/auth/auth.go b/pkg/platform/model/auth/auth.go index 25f8a7ec61..cb493a9e9d 100644 --- a/pkg/platform/model/auth/auth.go +++ b/pkg/platform/model/auth/auth.go @@ -1,6 +1,8 @@ package model import ( + "errors" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" @@ -31,9 +33,11 @@ func CheckDeviceAuthorization(deviceCode strfmt.UUID) (jwt *mms.JWT, apiKey *mms response, err := mono.Get().Oauth.AuthDeviceGet(getParams) if err != nil { + var errAuthDeviceGetBadRequest *oauth.AuthDeviceGetBadRequest + // Identify input or benign errors - if errs.Matches(err, &oauth.AuthDeviceGetBadRequest{}) { - errorToken := err.(*oauth.AuthDeviceGetBadRequest).Payload.Error + if errors.As(err, &errAuthDeviceGetBadRequest) { + errorToken := errAuthDeviceGetBadRequest.Payload.Error switch *errorToken { case oauth.AuthDeviceGetBadRequestBodyErrorAuthorizationPending, oauth.AuthDeviceGetBadRequestBodyErrorSlowDown: logging.Debug("Authorization still pending") diff --git a/pkg/platform/model/buildplanner/build.go b/pkg/platform/model/buildplanner/build.go index efc547a5ee..867e056396 100644 --- a/pkg/platform/model/buildplanner/build.go +++ b/pkg/platform/model/buildplanner/build.go @@ -1,6 +1,7 @@ package buildplanner import ( + "encoding/json" "errors" "regexp" "strconv" @@ -37,6 +38,10 @@ type Commit struct { buildscript *buildscript.BuildScript } +func (c *Commit) CommitUUID() strfmt.UUID { + return c.Commit.CommitID +} + func (c *Commit) BuildPlan() *buildplan.BuildPlan { return c.buildplan } @@ -49,22 +54,53 @@ func (c *client) Run(req gqlclient.Request, resp interface{}) error { return c.gqlClient.Run(req, resp) } +const fetchCommitCacheExpiry = time.Hour * 12 + func (b *BuildPlanner) FetchCommit(commitID strfmt.UUID, owner, project string, target *string) (*Commit, error) { - logging.Debug("FetchBuildResult, commitID: %s, owner: %s, project: %s", commitID, owner, project) + return b.fetchCommit(commitID, owner, project, target, true) +} + +func (b *BuildPlanner) FetchCommitNoPoll(commitID strfmt.UUID, owner, project string, target *string) (*Commit, error) { + return b.fetchCommit(commitID, owner, project, target, false) +} + +func (b *BuildPlanner) fetchCommit(commitID strfmt.UUID, owner, project string, target *string, poll bool) (*Commit, error) { + logging.Debug("FetchCommit, commitID: %s, owner: %s, project: %s", commitID, owner, project) resp := &response.ProjectCommitResponse{} - err := b.client.Run(request.ProjectCommit(commitID.String(), owner, project, target), resp) + + cacheKey := strings.Join([]string{"FetchCommit", commitID.String(), owner, project, ptr.From(target, "")}, "-") + respRaw, err := b.cache.GetCache(cacheKey) if err != nil { - err = processBuildPlannerError(err, "failed to fetch commit") - if !b.auth.Authenticated() { - err = errs.AddTips(err, locale.T("tip_private_project_auth")) + return nil, errs.Wrap(err, "failed to get cache") + } + if respRaw != "" { + if err := json.Unmarshal([]byte(respRaw), resp); err != nil { + return nil, errs.Wrap(err, "failed to unmarshal cache: %s", cacheKey) + } + } else { + err := b.client.Run(request.ProjectCommit(commitID.String(), owner, project, target), resp) + if err != nil { + err = processBuildPlannerError(err, "failed to fetch commit") + if !b.auth.Authenticated() { + err = errs.AddTips(err, locale.T("tip_private_project_auth")) + } + return nil, err + } + if resp.Project.Commit.Build.Status == raw.Completed { + respBytes, err := json.Marshal(resp) + if err != nil { + return nil, errs.Wrap(err, "failed to marshal cache") + } + if err := b.cache.SetCache(cacheKey, string(respBytes), fetchCommitCacheExpiry); err != nil { + return nil, errs.Wrap(err, "failed to set cache") + } } - return nil, err } // The BuildPlanner will return a build plan with a status of // "planning" if the build plan is not ready yet. We need to // poll the BuildPlanner until the build is ready. - if resp.Project.Commit.Build.Status == raw.Planning { + if poll && resp.Project.Commit.Build.Status == raw.Planning { resp.Project.Commit.Build, err = b.pollBuildPlanned(commitID.String(), owner, project, target) if err != nil { return nil, errs.Wrap(err, "failed to poll build plan") @@ -78,10 +114,11 @@ func (b *BuildPlanner) FetchCommit(commitID strfmt.UUID, owner, project string, return nil, errs.Wrap(err, "failed to unmarshal build plan") } - script, err := buildscript.UnmarshalBuildExpression(commit.Expression, ptr.To(time.Time(commit.AtTime))) - if err != nil { + script := buildscript.New() + if err := script.UnmarshalBuildExpression(commit.Expression); err != nil { return nil, errs.Wrap(err, "failed to parse build expression") } + script.SetAtTime(time.Time(commit.AtTime), false) return &Commit{commit, bp, script}, nil } diff --git a/pkg/platform/model/buildplanner/buildengine.go b/pkg/platform/model/buildplanner/buildengine.go deleted file mode 100644 index 20f7636e01..0000000000 --- a/pkg/platform/model/buildplanner/buildengine.go +++ /dev/null @@ -1,16 +0,0 @@ -package buildplanner - -import ( - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" -) - -func ParseBuildEngine(be string) types.BuildEngine { - switch be { - case types.Alternative.String(): - return types.Alternative - case types.Camel.String(): - return types.Camel - default: - return types.UnknownEngine - } -} diff --git a/pkg/platform/model/buildplanner/buildplanner.go b/pkg/platform/model/buildplanner/buildplanner.go index 064144f014..72468b839b 100644 --- a/pkg/platform/model/buildplanner/buildplanner.go +++ b/pkg/platform/model/buildplanner/buildplanner.go @@ -1,6 +1,8 @@ package buildplanner import ( + "time" + "github.com/ActiveState/cli/internal/gqlclient" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/pkg/platform/api" @@ -17,9 +19,25 @@ type client struct { type BuildPlanner struct { auth *authentication.Auth client *client + cache cacher +} + +type cacher interface { + GetCache(key string) (string, error) + SetCache(key, value string, expiry time.Duration) error +} + +type VoidCacher struct{} + +func (v VoidCacher) GetCache(key string) (string, error) { + return "", nil +} + +func (v VoidCacher) SetCache(key, value string, expiry time.Duration) error { + return nil } -func NewBuildPlannerModel(auth *authentication.Auth) *BuildPlanner { +func NewBuildPlannerModel(auth *authentication.Auth, cache cacher) *BuildPlanner { bpURL := api.GetServiceURL(api.ServiceBuildPlanner).String() logging.Debug("Using build planner at: %s", bpURL) @@ -29,10 +47,16 @@ func NewBuildPlannerModel(auth *authentication.Auth) *BuildPlanner { gqlClient.SetTokenProvider(auth) } + // To avoid error prone nil checks all over the place + if cache == nil { + cache = VoidCacher{} + } + return &BuildPlanner{ auth: auth, client: &client{ gqlClient: gqlClient, }, + cache: cache, } } diff --git a/pkg/platform/model/buildplanner/buildscript.go b/pkg/platform/model/buildplanner/buildscript.go index 7a29cc8852..e733a58481 100644 --- a/pkg/platform/model/buildplanner/buildscript.go +++ b/pkg/platform/model/buildplanner/buildscript.go @@ -1,22 +1,42 @@ package buildplanner import ( + "encoding/json" + "strings" "time" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/rtutils/ptr" "github.com/ActiveState/cli/pkg/buildscript" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/request" bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" ) func (b *BuildPlanner) GetBuildScript(commitID string) (*buildscript.BuildScript, error) { - logging.Debug("GetBuildExpression, commitID: %s", commitID) + logging.Debug("GetBuildScript, commitID: %s", commitID) resp := &bpResp.BuildExpressionResponse{} - err := b.client.Run(request.BuildExpression(commitID), resp) + + cacheKey := strings.Join([]string{"GetBuildScript", commitID}, "-") + respRaw, err := b.cache.GetCache(cacheKey) if err != nil { - return nil, processBuildPlannerError(err, "failed to fetch build expression") + return nil, errs.Wrap(err, "failed to get cache") + } + if respRaw != "" { + if err := json.Unmarshal([]byte(respRaw), resp); err != nil { + return nil, errs.Wrap(err, "failed to unmarshal cache: %s", cacheKey) + } + } else { + err := b.client.Run(request.BuildExpression(commitID), resp) + if err != nil { + return nil, processBuildPlannerError(err, "failed to fetch build expression") + } + respBytes, err := json.Marshal(resp) + if err != nil { + return nil, errs.Wrap(err, "failed to marshal cache") + } + if err := b.cache.SetCache(cacheKey, string(respBytes), fetchCommitCacheExpiry); err != nil { + return nil, errs.Wrap(err, "failed to set cache") + } } if resp.Commit == nil { @@ -31,8 +51,9 @@ func (b *BuildPlanner) GetBuildScript(commitID string) (*buildscript.BuildScript return nil, errs.New("Commit does not contain expression") } - script, err := buildscript.UnmarshalBuildExpression(resp.Commit.Expression, ptr.To(time.Time(resp.Commit.AtTime))) - if err != nil { + script := buildscript.New() + script.SetAtTime(time.Time(resp.Commit.AtTime), true) + if err := script.UnmarshalBuildExpression(resp.Commit.Expression); err != nil { return nil, errs.Wrap(err, "failed to parse build expression") } diff --git a/pkg/platform/model/buildplanner/commit.go b/pkg/platform/model/buildplanner/commit.go index 66710d43a0..3086d32930 100644 --- a/pkg/platform/model/buildplanner/commit.go +++ b/pkg/platform/model/buildplanner/commit.go @@ -1,8 +1,12 @@ package buildplanner import ( + "time" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/buildplan/raw" "github.com/ActiveState/cli/pkg/buildscript" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/request" "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" @@ -26,39 +30,64 @@ type StageCommitParams struct { Script *buildscript.BuildScript } -func (b *BuildPlanner) StageCommit(params StageCommitParams) (strfmt.UUID, error) { +func (b *BuildPlanner) StageCommit(params StageCommitParams) (*Commit, error) { logging.Debug("StageCommit, params: %+v", params) script := params.Script if script == nil { - return "", errs.New("Script is nil") + return nil, errs.New("Script is nil") } expression, err := script.MarshalBuildExpression() if err != nil { - return "", errs.Wrap(err, "Failed to marshal build expression") + return nil, errs.Wrap(err, "Failed to marshal build expression") } // With the updated build expression call the stage commit mutation request := request.StageCommit(params.Owner, params.Project, params.ParentCommit, params.Description, script.AtTime(), expression) resp := &response.StageCommitResult{} if err := b.client.Run(request, resp); err != nil { - return "", processBuildPlannerError(err, "failed to stage commit") + return nil, processBuildPlannerError(err, "failed to stage commit") } if resp.Commit == nil { - return "", errs.New("Staged commit is nil") + return nil, errs.New("Staged commit is nil") } if response.IsErrorResponse(resp.Commit.Type) { - return "", response.ProcessCommitError(resp.Commit, "Could not process error response from stage commit") + return nil, response.ProcessCommitError(resp.Commit, "Could not process error response from stage commit") } if resp.Commit.CommitID == "" { - return "", errs.New("Staged commit does not contain commitID") + return nil, errs.New("Staged commit does not contain commitID") + } + + if response.IsErrorResponse(resp.Commit.Build.Type) { + return &Commit{resp.Commit, nil, nil}, response.ProcessBuildError(resp.Commit.Build, "Could not process error response from stage commit") + } + + // The BuildPlanner will return a build plan with a status of + // "planning" if the build plan is not ready yet. We need to + // poll the BuildPlanner until the build is ready. + if resp.Commit.Build.Status == raw.Planning { + resp.Commit.Build, err = b.pollBuildPlanned(resp.Commit.CommitID.String(), params.Owner, params.Project, nil) + if err != nil { + return nil, errs.Wrap(err, "failed to poll build plan") + } + } + + bp, err := buildplan.Unmarshal(resp.Commit.Build.RawMessage) + if err != nil { + return nil, errs.Wrap(err, "failed to unmarshal build plan") + } + + stagedScript := buildscript.New() + stagedScript.SetAtTime(time.Time(resp.Commit.AtTime), false) + if err := stagedScript.UnmarshalBuildExpression(resp.Commit.Expression); err != nil { + return nil, errs.Wrap(err, "failed to parse build expression") } - return resp.Commit.CommitID, nil + return &Commit{resp.Commit, bp, stagedScript}, nil } func (b *BuildPlanner) RevertCommit(organization, project, parentCommitID, commitID string) (strfmt.UUID, error) { diff --git a/pkg/platform/model/buildplanner/project.go b/pkg/platform/model/buildplanner/project.go index 6f52dcc06d..9eb7dcb34d 100644 --- a/pkg/platform/model/buildplanner/project.go +++ b/pkg/platform/model/buildplanner/project.go @@ -32,14 +32,10 @@ func (b *BuildPlanner) CreateProject(params *CreateProjectParams) (strfmt.UUID, script := params.Script if script == nil { // Construct an initial buildexpression for the new project. - var err error - script, err = buildscript.New() - if err != nil { - return "", errs.Wrap(err, "Unable to create initial buildexpression") - } + script = buildscript.Create() // Add the platform. - if err := script.UpdatePlatform(types.OperationAdded, params.PlatformID); err != nil { + if err := script.AddPlatform(params.PlatformID); err != nil { return "", errs.Wrap(err, "Unable to add platform") } diff --git a/pkg/platform/model/buildplanner/publish.go b/pkg/platform/model/buildplanner/publish.go new file mode 100644 index 0000000000..4f23d06802 --- /dev/null +++ b/pkg/platform/model/buildplanner/publish.go @@ -0,0 +1,25 @@ +package buildplanner + +import ( + "github.com/ActiveState/cli/internal/errs" + graphModel "github.com/ActiveState/cli/pkg/platform/api/graphql/model" + "github.com/ActiveState/cli/pkg/platform/api/graphql/request" +) + +func (b *BuildPlanner) Publish(vars request.PublishVariables, filepath string) (*graphModel.PublishResult, error) { + pr, err := request.Publish(vars, filepath) + if err != nil { + return nil, errs.Wrap(err, "Could not create publish request") + } + res := graphModel.PublishResponse{} + + if err := b.client.Run(pr, &res); err != nil { + return nil, processBuildPlannerError(err, "Publish failed") + } + + if res.Result.Error != "" { + return nil, errs.New("API responded with error: %s", res.Result.Error) + } + + return &res.Result, nil +} diff --git a/pkg/platform/model/checkpoints.go b/pkg/platform/model/checkpoints.go index 7d86be6895..0dc6c550a8 100644 --- a/pkg/platform/model/checkpoints.go +++ b/pkg/platform/model/checkpoints.go @@ -3,6 +3,7 @@ package model import ( "strings" + "github.com/ActiveState/cli/pkg/buildscript" "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" "github.com/go-openapi/strfmt" @@ -60,7 +61,7 @@ func FetchLanguagesForCommit(commitID strfmt.UUID, auth *authentication.Auth) ([ languages := []Language{} for _, requirement := range checkpoint { if NamespaceMatch(requirement.Namespace, NamespaceLanguageMatch) { - version := MonoConstraintsToString(requirement.VersionConstraints) + version := MonoConstraintsToString(requirement.VersionConstraints, true) lang := Language{ Name: requirement.Requirement, Version: version, @@ -72,6 +73,27 @@ func FetchLanguagesForCommit(commitID strfmt.UUID, auth *authentication.Auth) ([ return languages, nil } +// FetchLanguagesForBuildScript fetches a list of language names for the given buildscript +func FetchLanguagesForBuildScript(script *buildscript.BuildScript) ([]Language, error) { + languages := []Language{} + reqs, err := script.DependencyRequirements() + if err != nil { + return nil, errs.Wrap(err, "failed to get dependency requirements") + } + + for _, requirement := range reqs { + if NamespaceMatch(requirement.Namespace, NamespaceLanguageMatch) { + lang := Language{ + Name: requirement.Name, + Version: VersionRequirementsToString(requirement.VersionRequirement, true), + } + languages = append(languages, lang) + } + } + + return languages, nil +} + // FetchCheckpointForCommit fetches the checkpoint for the given commit func FetchCheckpointForCommit(commitID strfmt.UUID, auth *authentication.Auth) ([]*gqlModel.Requirement, strfmt.DateTime, error) { logging.Debug("fetching checkpoint (%s)", commitID.String()) @@ -186,33 +208,12 @@ func CheckpointToPlatforms(requirements []*gqlModel.Requirement) []strfmt.UUID { return result } -// CheckpointToLanguage returns the language from a checkpoint -func CheckpointToLanguage(requirements []*gqlModel.Requirement, auth *authentication.Auth) (*Language, error) { - for _, req := range requirements { - if !NamespaceMatch(req.Namespace, NamespaceLanguageMatch) { - continue - } - lang, err := FetchLanguageByDetails(req.Requirement, req.VersionConstraint, auth) - if err != nil { - return nil, err - } - return lang, nil - } - - return nil, locale.NewError("err_fetch_languages") -} - func PlatformNameToPlatformID(name string) (string, error) { name = strings.ToLower(name) if name == "darwin" { name = "macos" } - id, err := hostPlatformToPlatformID(name) - return id, err -} - -func hostPlatformToPlatformID(os string) (string, error) { - switch strings.ToLower(os) { + switch strings.ToLower(name) { case strings.ToLower(sysinfo.Linux.String()): return constants.LinuxBit64UUID, nil case strings.ToLower(sysinfo.Mac.String()): @@ -220,7 +221,7 @@ func hostPlatformToPlatformID(os string) (string, error) { case strings.ToLower(sysinfo.Windows.String()): return constants.Win10Bit64UUID, nil default: - return "", locale.NewExternalError("err_unsupported_platform", "", os) + return "", ErrPlatformNotFound } } diff --git a/pkg/platform/model/inventory.go b/pkg/platform/model/inventory.go index ff513e95e5..aa4176e151 100644 --- a/pkg/platform/model/inventory.go +++ b/pkg/platform/model/inventory.go @@ -1,7 +1,7 @@ package model import ( - "fmt" + "errors" "regexp" "runtime" "sort" @@ -205,6 +205,7 @@ func searchIngredientsNamespace(ns string, name string, includeVersions bool, ex } params.SetLimit(&limit) params.SetHTTPClient(api.NewHTTPClient()) + params.WithTimeout(60 * time.Second) if ts != nil { dt := strfmt.DateTime(*ts) @@ -319,17 +320,12 @@ func FetchPlatformsForCommit(commitID strfmt.UUID, auth *authentication.Auth) ([ return platforms, nil } -func FilterPlatformIDs(hostPlatform, hostArch string, platformIDs []strfmt.UUID, cfg Configurable) ([]strfmt.UUID, error) { +func FilterPlatformIDs(hostPlatform, hostArch string, platformIDs []strfmt.UUID, preferredLibcVersion string) ([]strfmt.UUID, error) { runtimePlatforms, err := FetchPlatforms() if err != nil { return nil, err } - libcVersion, err := fetchLibcVersion(cfg) - if err != nil { - return nil, errs.Wrap(err, "failed to fetch libc version") - } - var pids []strfmt.UUID var fallback []strfmt.UUID libcMap := make(map[strfmt.UUID]float64) @@ -349,7 +345,7 @@ func FilterPlatformIDs(hostPlatform, hostArch string, platformIDs []strfmt.UUID, } if rtPf.LibcVersion != nil && rtPf.LibcVersion.Version != nil { - if libcVersion != "" && libcVersion != *rtPf.LibcVersion.Version { + if preferredLibcVersion != "" && preferredLibcVersion != *rtPf.LibcVersion.Version { continue } // Convert the libc version to a major-minor float and map it to the platform ID for @@ -383,7 +379,7 @@ func FilterPlatformIDs(hostPlatform, hostArch string, platformIDs []strfmt.UUID, } if len(pids) == 0 && len(fallback) == 0 { - return nil, &ErrNoMatchingPlatform{hostPlatform, hostArch, libcVersion} + return nil, &ErrNoMatchingPlatform{hostPlatform, hostArch, preferredLibcVersion} } else if len(pids) == 0 { pids = fallback } @@ -458,42 +454,66 @@ func FetchPlatformByUID(uid strfmt.UUID) (*Platform, error) { return nil, nil } -func FetchPlatformByDetails(name, version string, word int, auth *authentication.Auth) (*Platform, error) { +var ErrPlatformNotFound = errors.New("could not find platform matching provided criteria") + +func FetchPlatformByDetails(name, version string, bitwidth int) (*Platform, error) { + platformID, err := PlatformNameToPlatformID(name) + if err != nil { + return nil, errs.Wrap(err, "platform id from name failed") + } + runtimePlatforms, err := FetchPlatforms() if err != nil { return nil, err } - lower := strings.ToLower - + // Prioritize the platform that we record as default for _, rtPf := range runtimePlatforms { - if rtPf.Kernel == nil || rtPf.Kernel.Name == nil { + if rtPf.PlatformID.String() != platformID { continue } - if lower(*rtPf.Kernel.Name) != lower(name) { - continue + if IsPlatformMatch(rtPf, name, version, bitwidth) { + return rtPf, nil } + break + } - if rtPf.KernelVersion == nil || rtPf.KernelVersion.Version == nil { - continue - } - if lower(*rtPf.KernelVersion.Version) != lower(version) { - continue + // Return the first platform whose criteria match + for _, rtPf := range runtimePlatforms { + if IsPlatformMatch(rtPf, name, version, bitwidth) { + return rtPf, nil } + } - if rtPf.CPUArchitecture == nil { - continue - } - if rtPf.CPUArchitecture.BitWidth == nil || *rtPf.CPUArchitecture.BitWidth != strconv.Itoa(word) { - continue - } + return nil, ErrPlatformNotFound +} - return rtPf, nil +func IsPlatformMatch(platform *Platform, name, version string, bitwidth int) bool { + var platformID string + if version == "" && bitwidth == 0 { + var err error + platformID, err = PlatformNameToPlatformID(name) + if err != nil || platformID == "" { + return false + } + return platform.PlatformID.String() == platformID } - details := fmt.Sprintf("%s %d %s", name, word, version) + if platform.Kernel == nil || platform.Kernel.Name == nil || + !strings.EqualFold(*platform.Kernel.Name, name) { + return false + } + if version != "" && (platform.KernelVersion == nil || platform.KernelVersion.Version == nil || + !strings.EqualFold(*platform.KernelVersion.Version, version)) { + return false + } + if bitwidth != 0 && (platform.CPUArchitecture == nil || + platform.CPUArchitecture.BitWidth == nil || + !strings.EqualFold(*platform.CPUArchitecture.BitWidth, strconv.Itoa(bitwidth))) { + return false + } - return nil, locale.NewExternalError("err_unsupported_platform", "", details) + return true } func FetchLanguageForCommit(commitID strfmt.UUID, auth *authentication.Auth) (*Language, error) { @@ -507,21 +527,6 @@ func FetchLanguageForCommit(commitID strfmt.UUID, auth *authentication.Auth) (*L return &langs[0], nil } -func FetchLanguageByDetails(name, version string, auth *authentication.Auth) (*Language, error) { - languages, err := FetchLanguages(auth) - if err != nil { - return nil, err - } - - for _, language := range languages { - if language.Name == name && language.Version == version { - return &language, nil - } - } - - return nil, locale.NewInputError("err_language_not_found", "", name, version) -} - func FetchLanguageVersions(name string, auth *authentication.Auth) ([]string, error) { languages, err := FetchLanguages(auth) if err != nil { @@ -660,8 +665,8 @@ func FetchNormalizedName(namespace Namespace, name string, auth *authentication. return *res.Payload.NormalizedNames[0].Normalized, nil } -func FilterCurrentPlatform(hostPlatform string, platforms []strfmt.UUID, cfg Configurable) (strfmt.UUID, error) { - platformIDs, err := FilterPlatformIDs(hostPlatform, runtime.GOARCH, platforms, cfg) +func FilterCurrentPlatform(hostPlatform string, platforms []strfmt.UUID, preferredLibcVersion string) (strfmt.UUID, error) { + platformIDs, err := FilterPlatformIDs(hostPlatform, runtime.GOARCH, platforms, preferredLibcVersion) if err != nil { return "", errs.Wrap(err, "filterPlatformIDs failed") } diff --git a/pkg/platform/model/organizations.go b/pkg/platform/model/organizations.go index 1422fcba0a..6afba14bed 100644 --- a/pkg/platform/model/organizations.go +++ b/pkg/platform/model/organizations.go @@ -152,7 +152,7 @@ func processOrgErrorResponse(err error) error { func processInviteErrorResponse(err error) error { switch statusCode := api.ErrorCode(err); statusCode { case 400: - return locale.WrapExternalError(err, "err_api_invite_400", "Invalid request, did you enter a valid email address?") + return locale.WrapExternalError(err, "err_api_invite_400", "Invalid request. Did you enter a valid email address?") case 401: return locale.NewExternalError("err_api_not_authenticated") case 404: diff --git a/pkg/platform/model/projects.go b/pkg/platform/model/projects.go index e3650ac3af..9adb161b63 100644 --- a/pkg/platform/model/projects.go +++ b/pkg/platform/model/projects.go @@ -1,6 +1,7 @@ package model import ( + "errors" "fmt" "time" @@ -35,15 +36,16 @@ func LegacyFetchProjectByName(orgName string, projectName string) (*mono_models. return nil, errs.Wrap(err, "Could not get auth") } project, err := FetchProjectByName(orgName, projectName, auth) - if err == nil || !errs.Matches(err, &ErrProjectNotFound{}) { + var errProjectNotFound *ErrProjectNotFound + if err == nil || !errors.As(err, &errProjectNotFound) { return project, err } if !auth.Authenticated() { return nil, errs.AddTips( - locale.NewExternalError("err_api_project_not_found", "", orgName, projectName), + locale.NewInputError("err_api_project_not_found", "", orgName, projectName), locale.T("tip_private_project_auth")) } - return nil, errs.Pack(err, locale.NewExternalError("err_api_project_not_found", "", orgName, projectName)) + return nil, errs.Pack(err, locale.NewInputError("err_api_project_not_found", "", orgName, projectName)) } // FetchProjectByName fetches a project for an organization. @@ -197,8 +199,11 @@ func CreateEmptyProject(owner, name string, private bool, auth *authentication.A addParams.SetProject(&mono_models.Project{Name: name, Private: private}) pj, err := authClient.Projects.AddProject(addParams, auth.ClientAuth()) if err != nil { + var errAddProjectConflict *projects.AddProjectConflict + var errAddProjectNotFound *projects.AddProjectNotFound + msg := api.ErrorMessageFromPayload(err) - if errs.Matches(err, &projects.AddProjectConflict{}) || errs.Matches(err, &projects.AddProjectNotFound{}) { + if errors.As(err, &errAddProjectConflict) || errors.As(err, &errAddProjectNotFound) { return nil, locale.WrapInputError(err, msg) } return nil, locale.WrapError(err, msg) @@ -245,7 +250,7 @@ func CreateCopy(sourceOwner, sourceName, targetOwner, targetName string, makePri if _, err3 := authClient.Projects.DeleteProject(deleteParams, auth.ClientAuth()); err3 != nil { err = errs.Pack(err, locale.WrapError( err3, "err_fork_private_but_project_created", - "Your project was created but could not be made private, please head over to {{.V0}} to manually update your privacy settings.", + "Your project was created but could not be made private. Please head over to {{.V0}} to manually update your privacy settings.", api.GetPlatformURL(fmt.Sprintf("%s/%s", targetOwner, targetName)).String())) } } else { @@ -275,8 +280,10 @@ func MakeProjectPrivate(owner, name string, auth *authentication.Auth) error { _, err = authClient.Projects.EditProject(editParams, auth.ClientAuth()) if err != nil { + var errEditProjectBadRequest *projects.EditProjectBadRequest + msg := api.ErrorMessageFromPayload(err) - if errs.Matches(err, &projects.EditProjectBadRequest{}) { + if errors.As(err, &errEditProjectBadRequest) { return locale.WrapExternalError(err, msg) // user does not have permission } return locale.WrapError(err, msg) diff --git a/pkg/platform/model/svc.go b/pkg/platform/model/svc.go index 620a8fd0fc..375878b7eb 100644 --- a/pkg/platform/model/svc.go +++ b/pkg/platform/model/svc.go @@ -14,6 +14,7 @@ import ( "github.com/ActiveState/cli/internal/graph" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/profile" + "github.com/ActiveState/cli/internal/rtutils/ptr" "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" "github.com/ActiveState/cli/pkg/platform/api/svc/request" "github.com/ActiveState/graphql" @@ -199,6 +200,43 @@ func (m *SvcModel) GetJWT(ctx context.Context) (*mono_models.JWT, error) { return jwt, nil } +func (m *SvcModel) GetCache(key string) (result string, _ error) { + defer func() { logging.Debug("GetCache %s, result size: %d", key, len(result)) }() + defer profile.Measure("svc:GetCache", time.Now()) + + req := request.NewGetCache(key) + response := make(map[string]string) + if err := m.request(context.Background(), req, &response); err != nil { + return "", errs.Wrap(err, "Error sending GetCache request to state-svc") + } + if entry, ok := response["getCache"]; ok { + return entry, nil + } + return "", errs.New("svcModel.GetCache() did not return an expected value") +} + +func (m *SvcModel) SetCache(key, value string, expiry time.Duration) error { + logging.Debug("SetCache %s, value size: %d", key, len(value)) + defer profile.Measure("svc:SetCache", time.Now()) + + req := request.NewSetCache(key, value, expiry) + if err := m.request(context.Background(), req, ptr.To(make(map[string]string))); err != nil { + return errs.Wrap(err, "Error sending SetCache request to state-svc") + } + return nil +} + +func (m *SvcModel) HashGlobs(wd string, globs []string) (*graph.GlobResult, error) { + defer profile.Measure("svc:HashGlobs", time.Now()) + + req := request.NewHashGlobs(wd, globs) + res := graph.HashGlobsResponse{} + if err := m.request(context.Background(), req, &res); err != nil { + return nil, errs.Wrap(err, "Error sending HashGlobs request to state-svc") + } + return &res.Response, nil +} + func jsonFromMap(m map[string]interface{}) string { d, err := json.Marshal(m) if err != nil { diff --git a/pkg/platform/model/vcs.go b/pkg/platform/model/vcs.go index e351b6b03d..a964ea207b 100644 --- a/pkg/platform/model/vcs.go +++ b/pkg/platform/model/vcs.go @@ -1,6 +1,7 @@ package model import ( + "encoding/json" "errors" "fmt" "regexp" @@ -83,7 +84,7 @@ const ( NamespaceCamelFlagsMatch = `^camel-flags$` // NamespaceOrgMatch is the namespace used for org specific requirements - NamespaceOrgMatch = `^org\/` + NamespaceOrgMatch = `^private\/` // NamespaceBuildFlagsMatch is the namespace used for passing build flags NamespaceBuildFlagsMatch = `^build-flags$` @@ -134,7 +135,7 @@ var ( NamespaceBundle = NamespaceType{"bundle", "bundles", NamespaceBundlesMatch} NamespaceLanguage = NamespaceType{"language", "", NamespaceLanguageMatch} NamespacePlatform = NamespaceType{"platform", "", NamespacePlatformMatch} - NamespaceOrg = NamespaceType{"org", "org", NamespaceOrgMatch} + NamespaceOrg = NamespaceType{"org", "private", NamespaceOrgMatch} NamespaceRaw = NamespaceType{"raw", "", ""} NamespaceBlank = NamespaceType{"", "", ""} ) @@ -143,6 +144,10 @@ func (t NamespaceType) String() string { return t.name } +func (t NamespaceType) MarshalJSON() ([]byte, error) { + return json.Marshal(t.String()) +} + func (t NamespaceType) Prefix() string { return t.prefix } @@ -169,6 +174,18 @@ func (n Namespace) String() string { return n.value } +func ParseNamespace(ns string) Namespace { + if ns == "" { + return Namespace{NamespaceBlank, ns} + } + for _, n := range []NamespaceType{NamespacePackage, NamespaceBundle, NamespaceLanguage, NamespacePlatform, NamespaceOrg} { + if NamespaceMatch(ns, n.Matchable()) { + return Namespace{n, ns} + } + } + return Namespace{nsType: NamespaceRaw, value: ns} +} + func NewNamespacePkgOrBundle(language string, nstype NamespaceType) Namespace { if nstype == NamespaceBundle { return NewNamespaceBundle(language) @@ -181,7 +198,7 @@ func NewNamespacePackage(language string) Namespace { return Namespace{NamespacePackage, fmt.Sprintf("language/%s", language)} } -func NewRawNamespace(value string) Namespace { +func NewNamespaceRaw(value string) Namespace { return Namespace{NamespaceRaw, value} } @@ -204,19 +221,29 @@ func NewNamespacePlatform() Namespace { return Namespace{NamespacePlatform, "platform"} } -func NewOrgNamespace(orgName string) Namespace { +func NewNamespaceOrg(orgName, suffix string) Namespace { + ns := orgName + if suffix != "" { + ns += "/" + suffix + ns = strings.ReplaceAll(ns, "//", "/") + } return Namespace{ nsType: NamespaceOrg, - value: fmt.Sprintf("private/%s", orgName), + value: NamespaceOrg.prefix + "/" + ns, } } func LanguageFromNamespace(ns string) string { - values := strings.Split(ns, "/") - if len(values) != 2 { - return "" + matchables := []NamespaceMatchable{ + NamespacePackage.Matchable(), + NamespaceBundle.Matchable(), + } + for _, m := range matchables { + if NamespaceMatch(ns, m) { + return strings.Split(ns, "/")[1] + } } - return values[1] + return "" } // FilterSupportedIngredients filters a list of ingredients, returning only those that are currently supported (such that they can be built) by the Platform @@ -254,7 +281,7 @@ func BranchCommitID(ownerName, projectName, branchName string) (*strfmt.UUID, er if branch.CommitID == nil { return nil, locale.NewInputError( "err_project_no_commit", - "Your project does not have any commits yet, head over to {{.V0}} to set up your project.", api.GetPlatformURL(fmt.Sprintf("%s/%s", ownerName, projectName)).String()) + "Your project does not have any commits yet. Head over to {{.V0}} to set up your project.", api.GetPlatformURL(fmt.Sprintf("%s/%s", ownerName, projectName)).String()) } return branch.CommitID, nil @@ -542,7 +569,7 @@ func UpdateProjectBranchCommitWithModel(pjm *mono_models.Project, branchName str // CommitInitial creates a root commit for a new branch func CommitInitial(hostPlatform string, langName, langVersion string, auth *authentication.Auth) (strfmt.UUID, error) { - platformID, err := hostPlatformToPlatformID(hostPlatform) + platformID, err := PlatformNameToPlatformID(hostPlatform) if err != nil { return "", err } @@ -649,19 +676,6 @@ func (cs indexedCommits) countBetween(first, last string) (int, error) { return ct, nil } -func ResolveRequirementNameAndVersion(name, version string, word int, namespace Namespace, auth *authentication.Auth) (string, string, error) { - if namespace.Type() == NamespacePlatform { - platform, err := FetchPlatformByDetails(name, version, word, auth) - if err != nil { - return "", "", errs.Wrap(err, "Could not fetch platform") - } - name = platform.PlatformID.String() - version = "" - } - - return name, version, nil -} - func ChangesetFromRequirements(op Operation, reqs []*gqlModel.Requirement) Changeset { var changeset Changeset @@ -888,12 +902,20 @@ func GetCommitWithinCommitHistory(currentCommitID, targetCommitID strfmt.UUID, a // This function exists primarily as an existence check because the buildplanner API currently // accepts a query for a org/project#commitID even if commitID does not belong to org/project. // See DS-1705 (yes, DS, not DX). -func GetCommitWithinProjectHistory(commitID strfmt.UUID, owner, name string, auth *authentication.Auth) (*mono_models.Commit, error) { +func GetCommitWithinProjectHistory(commitID strfmt.UUID, owner, name string, localCommitID *strfmt.UUID, auth *authentication.Auth) (*mono_models.Commit, error) { commit, err := GetCommit(commitID, auth) if err != nil { return nil, errs.Wrap(err, "Unable to get commit") } + if localCommitID != nil { + if ok, err := CommitWithinCommitHistory(*localCommitID, commitID, auth); err == nil && ok { + return commit, nil + } else if err != nil { + return nil, errs.Wrap(err, "Unable to determine if commit exists in local history") + } + } + branches, err := BranchesForProject(owner, name) if err != nil { return nil, errs.Wrap(err, "Unable to get branches for project") diff --git a/pkg/platform/model/vcs_test.go b/pkg/platform/model/vcs_test.go index 15483e8180..944d4f85a4 100644 --- a/pkg/platform/model/vcs_test.go +++ b/pkg/platform/model/vcs_test.go @@ -161,3 +161,42 @@ func (suite *VCSTestSuite) TestVersionStringToConstraints() { func TestVCSTestSuite(t *testing.T) { suite.Run(t, new(VCSTestSuite)) } + +func TestParseNamespace(t *testing.T) { + tests := []struct { + ns string + want NamespaceType + }{ + { + "language/python", + NamespacePackage, + }, + { + "bundles/python", + NamespaceBundle, + }, + { + "language", + NamespaceLanguage, + }, + { + "platform", + NamespacePlatform, + }, + { + "private/org", + NamespaceOrg, + }, + { + "raw/foo/bar", + NamespaceRaw, + }, + } + for _, tt := range tests { + t.Run(tt.ns, func(t *testing.T) { + if got := ParseNamespace(tt.ns); got.Type().name != tt.want.name { + t.Errorf("ParseNamespace() = %v, want %v", got.Type().name, tt.want.name) + } + }) + } +} diff --git a/pkg/platform/model/version_constraints.go b/pkg/platform/model/version_constraints.go index ec0c81e645..62fa9ce5b7 100644 --- a/pkg/platform/model/version_constraints.go +++ b/pkg/platform/model/version_constraints.go @@ -16,7 +16,7 @@ type versionConstraints struct { version string } -func InventoryRequirementsToString(requirements inventory_models.Requirements) string { +func InventoryRequirementsToString(requirements inventory_models.Requirements, forAPI bool) string { if requirements == nil { return "" } @@ -25,10 +25,10 @@ func InventoryRequirementsToString(requirements inventory_models.Requirements) s for i, req := range requirements { constraints[i] = &versionConstraints{*req.Comparator, *req.Version} } - return versionConstraintsToString(constraints) + return versionConstraintsToString(constraints, forAPI) } -func GqlReqVersionConstraintsString(requirement *gqlModel.Requirement) string { +func GqlReqVersionConstraintsString(requirement *gqlModel.Requirement, forAPI bool) string { if requirement.VersionConstraints == nil { return "" } @@ -37,10 +37,10 @@ func GqlReqVersionConstraintsString(requirement *gqlModel.Requirement) string { for i, constraint := range requirement.VersionConstraints { constraints[i] = &versionConstraints{constraint.Comparator, constraint.Version} } - return versionConstraintsToString(constraints) + return versionConstraintsToString(constraints, forAPI) } -func BuildPlannerVersionConstraintsToString(requirements []types.VersionRequirement) string { +func VersionRequirementsToString(requirements []types.VersionRequirement, forAPI bool) string { if requirements == nil { return "" } @@ -50,10 +50,10 @@ func BuildPlannerVersionConstraintsToString(requirements []types.VersionRequirem constraints = append(constraints, &versionConstraints{constraint[types.VersionRequirementComparatorKey], constraint[types.VersionRequirementVersionKey]}) } - return versionConstraintsToString(constraints) + return versionConstraintsToString(constraints, forAPI) } -func MonoConstraintsToString(monoConstraints mono_models.Constraints) string { +func MonoConstraintsToString(monoConstraints mono_models.Constraints, forAPI bool) string { if monoConstraints == nil { return "" } @@ -62,10 +62,10 @@ func MonoConstraintsToString(monoConstraints mono_models.Constraints) string { for i, constraint := range monoConstraints { constraints[i] = &versionConstraints{constraint.Comparator, constraint.Version} } - return versionConstraintsToString(constraints) + return versionConstraintsToString(constraints, forAPI) } -func versionConstraintsToString(constraints []*versionConstraints) string { +func versionConstraintsToString(constraints []*versionConstraints, forAPI bool) string { if len(constraints) == 0 { return "" } @@ -78,7 +78,11 @@ func versionConstraintsToString(constraints []*versionConstraints) string { } switch req.comparator { case inventory_models.RequirementComparatorEq: - parts = append(parts, req.version) + if forAPI { + parts = append(parts, fmt.Sprintf("==%s", req.version)) + } else { + parts = append(parts, req.version) + } case inventory_models.RequirementComparatorGt: parts = append(parts, fmt.Sprintf(">%s", req.version)) case inventory_models.RequirementComparatorGte: diff --git a/pkg/platform/runtime/artifactcache/artifactcache.go b/pkg/platform/runtime/artifactcache/artifactcache.go deleted file mode 100644 index 92e455b767..0000000000 --- a/pkg/platform/runtime/artifactcache/artifactcache.go +++ /dev/null @@ -1,206 +0,0 @@ -package artifactcache - -import ( - "encoding/json" - "os" - "path/filepath" - "strconv" - "sync" - "time" - - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/installation/storage" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/internal/rollbar" - "github.com/go-openapi/strfmt" -) - -type cachedArtifact struct { - Id strfmt.UUID `json:"id"` - ArchivePath string `json:"archivePath"` - Size int64 `json:"size"` - LastAccessTime int64 `json:"lastAccessTime"` -} - -// ArtifactCache is a cache of downloaded artifacts from the ActiveState Platform. -// The State Tool prefers to use this cache instead of redownloading artifacts. -type ArtifactCache struct { - dir string - infoJson string - maxSize int64 // bytes - currentSize int64 // bytes - artifacts map[strfmt.UUID]*cachedArtifact - mutex sync.Mutex - timeSpentCopying time.Duration - sizeCopied int64 // bytes -} - -const MB int64 = 1024 * 1024 - -// New returns a new artifact cache in the State Tool's cache directory with the default maximum size of 1GB. -func New() (*ArtifactCache, error) { - var maxSize int64 = 1024 * MB - // TODO: size should be configurable and the user should be warned of an invalid size. - // https://activestatef.atlassian.net/browse/DX-984 - if sizeOverride, err := strconv.Atoi(os.Getenv(constants.ArtifactCacheSizeEnvVarName)); err != nil && sizeOverride > 0 { - maxSize = int64(sizeOverride) * MB - } - return newWithDirAndSize(storage.ArtifactCacheDir(), maxSize) -} - -func newWithDirAndSize(dir string, maxSize int64) (*ArtifactCache, error) { - err := fileutils.MkdirUnlessExists(dir) - if err != nil { - return nil, errs.Wrap(err, "Could not create artifact cache directory '%s'", dir) - } - - if !fileutils.IsDir(dir) { - return nil, errs.New("'%s' is not a directory; cannot use as artifact cache", dir) - } - - var artifacts []cachedArtifact - infoJson := filepath.Join(dir, constants.ArtifactCacheFileName) - if fileutils.FileExists(infoJson) { - data, err := fileutils.ReadFile(infoJson) - if err != nil { - return nil, errs.Wrap(err, "Could not read artifact cache's "+infoJson) - } - err = json.Unmarshal(data, &artifacts) - if err != nil { - return nil, errs.Wrap(err, "Unable to read cached artifacts from "+infoJson) - } - } - - var currentSize int64 = 0 - artifactMap := map[strfmt.UUID]*cachedArtifact{} - for _, artifact := range artifacts { - currentSize += artifact.Size - artifactMap[artifact.Id] = &cachedArtifact{artifact.Id, artifact.ArchivePath, artifact.Size, artifact.LastAccessTime} - } - - logging.Debug("Opened artifact cache at '%s' containing %d artifacts occupying %.1f/%.1f MB", dir, len(artifactMap), float64(currentSize)/float64(MB), float64(maxSize)/float64(MB)) - return &ArtifactCache{dir, infoJson, maxSize, currentSize, artifactMap, sync.Mutex{}, 0, 0}, nil -} - -// Get returns the path to the cached artifact with the given id along with true if it exists. -// Otherwise returns an empty string and false. -// Updates the access timestamp if possible so that this artifact is not removed anytime soon. -func (cache *ArtifactCache) Get(a strfmt.UUID) (string, bool) { - cache.mutex.Lock() - defer cache.mutex.Unlock() - - if artifact, found := cache.artifacts[a]; found { - logging.Debug("Fetched cached artifact '%s' as '%s'; updating access time", string(a), artifact.ArchivePath) - artifact.LastAccessTime = time.Now().Unix() - return artifact.ArchivePath, true - } - return "", false -} - -// Stores the given artifact in the cache. -// If the cache is too small, removes the least-recently accessed artifacts to make room. -func (cache *ArtifactCache) Store(a strfmt.UUID, archivePath string) error { - cache.mutex.Lock() - defer cache.mutex.Unlock() - - // Replace an existing artifact in the cache. - // This would really only happen if a checksum validation fails for the cached artifact (e.g. due - // to a bad actor replacing it) and the artifact is silently re-downloaded from the platform. - if existingArtifact, found := cache.artifacts[a]; found { - path := existingArtifact.ArchivePath - logging.Debug("Replacing cached artifact '%s'", path) - if fileutils.TargetExists(path) { - err := os.Remove(path) - if err != nil { - return errs.Wrap(err, "Unable to overwrite existing artifact '%s'", path) - } - } - delete(cache.artifacts, existingArtifact.Id) - cache.currentSize -= existingArtifact.Size - } - - stat, err := os.Stat(archivePath) - if err != nil { - return errs.Wrap(err, "Unable to stat artifact '%s'. Does it exist?", archivePath) - } - size := stat.Size() - - if size > cache.maxSize { - logging.Debug("Cannot avoid exceeding cache size; not storing artifact") - rollbar.Error("Artifact '%s' is %.1fMB, which exceeds the cache size of %.1fMB", a, float64(size)/float64(MB), float64(cache.maxSize)/float64(MB)) - return nil - } - - for cache.currentSize+size > cache.maxSize { - logging.Debug("Storing artifact in cache would exceed cache size; finding least-recently accessed artifact") - var lastAccessed *cachedArtifact - for _, artifact := range cache.artifacts { - if lastAccessed == nil || artifact.LastAccessTime < lastAccessed.LastAccessTime { - lastAccessed = artifact - } - } - - if lastAccessed == nil { - rollbar.Error("Cannot avoid exceeding cache size; not storing artifact.") - return nil // avoid infinite loop, but this really shouldn't happen... - } - - logging.Debug("Removing cached artifact '%s' last accessed on %s", lastAccessed.ArchivePath, time.Unix(lastAccessed.LastAccessTime, 0).Format(time.UnixDate)) - if fileutils.TargetExists(lastAccessed.ArchivePath) { - err := os.Remove(lastAccessed.ArchivePath) - if err != nil { - return errs.Wrap(err, "Unable to remove cached artifact '%s'", lastAccessed.ArchivePath) - } - } - delete(cache.artifacts, lastAccessed.Id) - cache.currentSize -= lastAccessed.Size - } - - targetPath := filepath.Join(cache.dir, string(a)) - startTime := time.Now() - err = fileutils.CopyFile(archivePath, targetPath) - cache.timeSpentCopying += time.Since(startTime) - cache.sizeCopied += size - if err != nil { - return errs.Wrap(err, "Unable to copy artifact '%s' into cache as '%s'", archivePath, targetPath) - } - - logging.Debug("Storing artifact '%s'", targetPath) - cached := &cachedArtifact{a, targetPath, size, time.Now().Unix()} - cache.artifacts[a] = cached - cache.currentSize += size - - return nil -} - -// Saves this cache's information to disk. -// You must call this function when you are done utilizing the cache. -func (cache *ArtifactCache) Save() error { - artifacts := make([]*cachedArtifact, len(cache.artifacts)) - i := 0 - for _, artifact := range cache.artifacts { - artifacts[i] = artifact - i++ - } - data, err := json.Marshal(artifacts) - if err != nil { - return errs.Wrap(err, "Unable to store cached artifacts into JSON") - } - - logging.Debug("Saving artifact cache at '%s'", cache.infoJson) - err = fileutils.WriteFile(cache.infoJson, data) - if err != nil { - return errs.Wrap(err, "Unable to write artifact cache's "+cache.infoJson) - } - - if cache.timeSpentCopying > 5*time.Second { - multilog.Log(logging.Debug, rollbar.Error)("Spent %.1f seconds copying %.1fMB of artifacts to cache", cache.timeSpentCopying.Seconds(), float64(cache.sizeCopied)/float64(MB)) - } - cache.timeSpentCopying = 0 // reset - cache.sizeCopied = 0 // reset - - return nil -} diff --git a/pkg/platform/runtime/artifactcache/testhelper.go b/pkg/platform/runtime/artifactcache/testhelper.go deleted file mode 100644 index 3123bf3e87..0000000000 --- a/pkg/platform/runtime/artifactcache/testhelper.go +++ /dev/null @@ -1,51 +0,0 @@ -package artifactcache - -import "github.com/go-openapi/strfmt" - -// This file exists solely to export private data from ArtifactCache in order to run integration -// tests in an outside package. - -type testArtifactCache struct { - cache *ArtifactCache -} - -// NewTestArtifactCache is only meant to be called from tests. Use New() instead. -func NewTestArtifactCache(dir string, maxSize int64) (*testArtifactCache, error) { - cache, err := newWithDirAndSize(dir, maxSize) - if err != nil { - return nil, err - } - return &testArtifactCache{cache}, nil -} - -func (ac *testArtifactCache) Dir() string { - return ac.cache.dir -} - -func (ac *testArtifactCache) InfoJson() string { - return ac.cache.infoJson -} - -func (ac *testArtifactCache) MaxSize() int64 { - return ac.cache.maxSize -} - -func (ac *testArtifactCache) CurrentSize() int64 { - return ac.cache.currentSize -} - -func (ac *testArtifactCache) Artifacts() map[strfmt.UUID]*cachedArtifact { - return ac.cache.artifacts -} - -func (ac *testArtifactCache) Get(a strfmt.UUID) (string, bool) { - return ac.cache.Get(a) -} - -func (ac *testArtifactCache) Store(a strfmt.UUID, s string) error { - return ac.cache.Store(a, s) -} - -func (ac *testArtifactCache) Save() error { - return ac.cache.Save() -} diff --git a/pkg/platform/runtime/envdef/doc.go b/pkg/platform/runtime/envdef/doc.go deleted file mode 100644 index ccb2c35a56..0000000000 --- a/pkg/platform/runtime/envdef/doc.go +++ /dev/null @@ -1,93 +0,0 @@ -// Package envdef implements a parser for the runtime environment for alternative builds -// -// Builds that are built with the alternative build environment, include -// runtime.json files that define which environment variables need to be set to -// install and use the provided artifacts. -// The schema of this file can be downloaded [here](https://drive.google.com/drive/u/0/my-drive) -// -// The same parser and interpreter also exists in [TheHomeRepot](https://github.com/ActiveState/TheHomeRepot/blob/master/service/build-wrapper/wrapper/runtime.py) -// -// Changes to the runtime environment definition schema should be synchronized -// between these two places. For now, this can be most easily accomplished by -// keeping the description of test cases in the [cli repo](https://github.com/ActiveState/cli/blob/master/pkg/platform/runtime/envdef/runtime_test_cases.json) -// and [TheHomeRepot](https://github.com/ActiveState/TheHomeRepot/blob/master/service/build-wrapper/runtime_test_cases.json) -// in sync. -// -// Examples: -// -// ## Define a PATH and LD_LIBRARY_PATH variable -// -// Assuming the runtime is installed to a directory `/home/user/.cache/installdir`, -// the following definition asks to set the PATH variables to -// `/home/user/.cache/installdir/bin:/home/user/.cache/installdir/usr/bin` and -// `LD_LIBRARY_PATH` to -// `/home/user/.cache/installdir/lib` -// The set `inherit` flag on the `PATH` variable ensures that the `PATH` value -// is prepended to the existing `PATH` that is already set in the environment. -// -// ```json -// { -// "env": [{ -// "env_name": "PATH", -// "values": ["${INSTALLDIR}/bin", "${INSTALLDIR}/usr/bin"], -// "join": "prepend", -// "inherit": true, -// "separator": ":" -// }, { -// "env_name": "LD_LIBRARY_PATH", -// "values": ["${INSTALLDIR}/lib"], -// "join": "prepend", -// "inherit": false, -// "separator": ":" -// }], -// "installdir": "installdir" -// } -// ``` -// -// The installdir is used during the unpacking step to identify the directory -// inside the artifact tarball that needs to be unpacked to `/home/user/.cache/installdir` -// -// ## Joining two definitions -// -// Assume we have a second environment definition file exists with the following contents: -// -// ```json -// { -// "env": [{ -// "env_name": "PATH", -// "values": ["${INSTALLDIR}/bin", "${INSTALLDIR}/usr/local/bin"], -// "join": "prepend", -// "inherit": true, -// "separator": ":" -// }, { -// "env_name": "LD_LIBRARY_PATH", -// "values": ["${INSTALLDIR}/lib", "${INSTALLDIR}/lib64"], -// "join": "prepend", -// "inherit": false, -// "separator": ":" -// }], -// "installdir": "installdir" -// } -// ``` -// -// Merging this environment definition into the previous one sets -// the `PATH` to `/home/user/.cache/installdir/bin:/home/user/.cache/installdir/usr/local/bin:/home/user/.cache/installdir/usr/bin`. -// Note, that duplicate values are filtered out. -// Likewise the `LD_LIBRARY_PATH` will end up as `/home/user/.cache/installdir/lib:/home/user/.cache/installdir/lib64` -// -// In this example, the values were joined by prepending the second definition -// to the first. -// Other join strategies are `append` and `disallowed`. -// -// The `disallowed` join strategy can be used if a variable should have only ONE -// value, and this value needs to be the same or undefined between all artifacts -// that depend on it. -// -// ## Usage -// -// - Environment definition files can be parsed from a file with the `NewEnvironmentDefinition()` function. -// - Two environment definitions `ed1` and `ed2` can be merged like so: -// ed1.Merge(ed2) -// - Once the installation directory is specified, the variable values can be expanded: -// ed.ExpandVariables("/home/user/.cache/installdir") -package envdef diff --git a/pkg/platform/runtime/runtime.go b/pkg/platform/runtime/runtime.go deleted file mode 100644 index 6dbfaa1a78..0000000000 --- a/pkg/platform/runtime/runtime.go +++ /dev/null @@ -1,428 +0,0 @@ -package runtime - -import ( - "errors" - "os" - "path/filepath" - "strings" - - buildscript_runbit "github.com/ActiveState/cli/internal/runbits/buildscript" - "github.com/ActiveState/cli/pkg/buildplan" - bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" - bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "golang.org/x/net/context" - - "github.com/ActiveState/cli/internal/analytics" - anaConsts "github.com/ActiveState/cli/internal/analytics/constants" - "github.com/ActiveState/cli/internal/analytics/dimensions" - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/installation/storage" - "github.com/ActiveState/cli/internal/instanceid" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/internal/osutils" - "github.com/ActiveState/cli/internal/output" - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/ActiveState/cli/pkg/platform/authentication" - "github.com/ActiveState/cli/pkg/platform/model" - "github.com/ActiveState/cli/pkg/platform/runtime/envdef" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/buildlog" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/events" - "github.com/ActiveState/cli/pkg/platform/runtime/store" - "github.com/ActiveState/cli/pkg/project" -) - -type Configurable interface { - GetString(key string) string - GetBool(key string) bool -} - -type Runtime struct { - disabled bool - target setup.Targeter - store *store.Store - analytics analytics.Dispatcher - svcm *model.SvcModel - auth *authentication.Auth - completed bool - cfg Configurable - out output.Outputer -} - -// NeedsCommitError is an error returned when the local runtime's build script has changes that need -// staging. This is not a fatal error. A runtime can still be used, but a warning should be emitted. -var NeedsCommitError = errors.New("runtime needs commit") - -// NeedsBuildscriptResetError is an error returned when the runtime is improperly referenced in the project (eg. missing buildscript) -var NeedsBuildscriptResetError = errors.New("needs runtime reset") - -func newRuntime(target setup.Targeter, an analytics.Dispatcher, svcModel *model.SvcModel, auth *authentication.Auth, cfg Configurable, out output.Outputer) (*Runtime, error) { - rt := &Runtime{ - target: target, - store: store.New(target.Dir()), - analytics: an, - svcm: svcModel, - auth: auth, - cfg: cfg, - out: out, - } - - err := rt.validateCache() - if err != nil { - return rt, err - } - - return rt, nil -} - -// New attempts to create a new runtime from local storage. -func New(target setup.Targeter, an analytics.Dispatcher, svcm *model.SvcModel, auth *authentication.Auth, cfg Configurable, out output.Outputer) (*Runtime, error) { - logging.Debug("Initializing runtime for: %s/%s@%s", target.Owner(), target.Name(), target.CommitUUID()) - - if strings.ToLower(os.Getenv(constants.DisableRuntime)) == "true" { - out.Notice(locale.T("notice_runtime_disabled")) - return &Runtime{disabled: true, target: target, analytics: an}, nil - } - recordAttempt(an, target) - an.Event(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeStart, &dimensions.Values{ - Trigger: ptr.To(target.Trigger().String()), - CommitID: ptr.To(target.CommitUUID().String()), - ProjectNameSpace: ptr.To(project.NewNamespace(target.Owner(), target.Name(), target.CommitUUID().String()).String()), - InstanceID: ptr.To(instanceid.ID()), - }) - - r, err := newRuntime(target, an, svcm, auth, cfg, out) - if err == nil { - an.Event(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeCache, &dimensions.Values{ - CommitID: ptr.To(target.CommitUUID().String()), - }) - } - - return r, err -} - -func (r *Runtime) NeedsUpdate() bool { - if strings.ToLower(os.Getenv(constants.DisableRuntime)) == "true" { - return false - } - if !r.store.MarkerIsValid(r.target.CommitUUID()) { - if r.target.ReadOnly() { - logging.Debug("Using forced cache") - } else { - return true - } - } - return false -} - -func (r *Runtime) validateCache() error { - if r.target.ProjectDir() == "" { - return nil - } - - err := r.validateBuildScript() - if err != nil { - return errs.Wrap(err, "Error validating build script") - } - - return nil -} - -// validateBuildScript asserts the local build script does not have changes that should be committed. -func (r *Runtime) validateBuildScript() error { - logging.Debug("Checking to see if local build script has changes that should be committed") - if !r.cfg.GetBool(constants.OptinBuildscriptsConfig) { - logging.Debug("Not opted into buildscripts") - return nil - } - - script, err := buildscript_runbit.ScriptFromProject(r.target) - if err != nil { - if errors.Is(err, buildscript_runbit.ErrBuildscriptNotExist) { - return errs.Pack(err, NeedsBuildscriptResetError) - } - return errs.Wrap(err, "Could not get buildscript from project") - } - - cachedCommitID, err := r.store.CommitID() - if err != nil { - logging.Debug("No commit ID to read; refresh needed") - return nil - } - - if cachedCommitID != r.target.CommitUUID().String() { - logging.Debug("Runtime commit ID does not match project commit ID; refresh needed") - return nil - } - - cachedScript, err := r.store.BuildScript() - if err != nil { - if errors.Is(err, store.ErrNoBuildScriptFile) { - logging.Warning("No buildscript file exists in store, unable to check if buildscript is dirty. This can happen if you cleared your cache.") - } else { - return errs.Wrap(err, "Could not retrieve buildscript from store") - } - } - - if cachedScript != nil { - equals, err := script.Equals(cachedScript) - if err != nil { - return errs.Wrap(err, "Could not compare buildscript") - } - - if script != nil && !equals { - return NeedsCommitError - } - } - - return nil -} - -func (r *Runtime) Disabled() bool { - return r.disabled -} - -func (r *Runtime) Target() setup.Targeter { - return r.target -} - -func (r *Runtime) Setup(eventHandler events.Handler) *setup.Setup { - return setup.New(r.target, eventHandler, r.auth, r.analytics, r.cfg, r.out, r.svcm) -} - -func (r *Runtime) Update(setup *setup.Setup, commit *bpModel.Commit) (rerr error) { - if r.disabled { - logging.Debug("Skipping update as it is disabled") - return nil // nothing to do - } - - logging.Debug("Updating %s#%s @ %s", r.target.Name(), r.target.CommitUUID(), r.target.Dir()) - - defer func() { - r.recordCompletion(rerr) - }() - - if err := setup.Update(commit); err != nil { - return errs.Wrap(err, "Update failed") - } - - // Reinitialize - rt, err := newRuntime(r.target, r.analytics, r.svcm, r.auth, r.cfg, r.out) - if err != nil { - return errs.Wrap(err, "Could not reinitialize runtime after update") - } - *r = *rt - - return nil -} - -// SolveAndUpdate updates the runtime by downloading all necessary artifacts from the Platform and installing them locally. -func (r *Runtime) SolveAndUpdate(eventHandler events.Handler) error { - if r.disabled { - logging.Debug("Skipping update as it is disabled") - return nil // nothing to do - } - - setup := r.Setup(eventHandler) - commit, err := setup.Solve() - if err != nil { - return errs.Wrap(err, "Could not solve") - } - - if err := r.Update(setup, commit); err != nil { - return errs.Wrap(err, "Could not update") - } - - return nil -} - -// HasCache tells us whether this runtime has any cached files. Note this does NOT tell you whether the cache is valid. -func (r *Runtime) HasCache() bool { - return fileutils.DirExists(r.target.Dir()) -} - -// Env returns a key-value map of the environment variables that need to be set for this runtime -// It's different from envDef in that it merges in the current active environment and points the PATH variable to the -// Executors directory if requested -func (r *Runtime) Env(inherit bool, useExecutors bool) (map[string]string, error) { - logging.Debug("Getting runtime env, inherit: %v, useExec: %v", inherit, useExecutors) - - envDef, err := r.envDef() - r.recordCompletion(err) - if err != nil { - return nil, errs.Wrap(err, "Could not grab environment definitions") - } - - env := envDef.GetEnv(inherit) - - execDir := filepath.Clean(setup.ExecDir(r.target.Dir())) - if useExecutors { - // Override PATH entry with exec path - pathEntries := []string{execDir} - if inherit { - pathEntries = append(pathEntries, os.Getenv("PATH")) - } - env["PATH"] = strings.Join(pathEntries, string(os.PathListSeparator)) - } else { - // Ensure we aren't inheriting the executor paths from something like an activated state - envdef.FilterPATH(env, execDir, storage.GlobalBinDir()) - } - - return env, nil -} - -func (r *Runtime) recordCompletion(err error) { - if r.completed { - logging.Debug("Not recording runtime completion as it was already recorded for this invocation") - return - } - r.completed = true - logging.Debug("Recording runtime completion, error: %v", err == nil) - - var action string - if err != nil { - action = anaConsts.ActRuntimeFailure - } else { - action = anaConsts.ActRuntimeSuccess - r.recordUsage() - } - - ns := project.Namespaced{ - Owner: r.target.Owner(), - Project: r.target.Name(), - } - - errorType := "unknown" - switch { - // IsInputError should always be first because it is technically possible for something like a - // download error to be cause by an input error. - case locale.IsInputError(err): - errorType = "input" - case errs.Matches(err, &setup.BuildError{}), errs.Matches(err, &buildlog.BuildError{}): - errorType = "build" - case errs.Matches(err, &bpResp.BuildPlannerError{}): - errorType = "buildplan" - case errs.Matches(err, &setup.ArtifactSetupErrors{}): - if setupErrors := (&setup.ArtifactSetupErrors{}); errors.As(err, &setupErrors) { - // Label the loop so we can break out of it when we find the first download - // or build error. - Loop: - for _, err := range setupErrors.Errors() { - switch { - case errs.Matches(err, &setup.ArtifactDownloadError{}): - errorType = "download" - break Loop // it only takes one download failure to report the runtime failure as due to download error - case errs.Matches(err, &setup.ArtifactInstallError{}): - errorType = "install" - // Note: do not break because there could be download errors, and those take precedence - case errs.Matches(err, &setup.BuildError{}), errs.Matches(err, &buildlog.BuildError{}): - errorType = "build" - break Loop // it only takes one build failure to report the runtime failure as due to build error - } - } - } - // Progress/event handler errors should come last because they can wrap one of the above errors, - // and those errors actually caused the failure, not these. - case errs.Matches(err, &setup.ProgressReportError{}) || errs.Matches(err, &buildlog.EventHandlerError{}): - errorType = "progress" - case errs.Matches(err, &setup.ExecutorSetupError{}): - errorType = "postprocess" - } - - var message string - if err != nil { - message = errs.JoinMessage(err) - } - - r.analytics.Event(anaConsts.CatRuntimeDebug, action, &dimensions.Values{ - CommitID: ptr.To(r.target.CommitUUID().String()), - // Note: ProjectID is set by state-svc since ProjectNameSpace is specified. - ProjectNameSpace: ptr.To(ns.String()), - Error: ptr.To(errorType), - Message: &message, - }) -} - -func (r *Runtime) recordUsage() { - if !r.target.Trigger().IndicatesUsage() { - logging.Debug("Not recording usage as %s is not a usage trigger", r.target.Trigger().String()) - return - } - - // Fire initial runtime usage event right away, subsequent events will be fired via the service so long as the process is running - dims := usageDims(r.target) - dimsJson, err := dims.Marshal() - if err != nil { - multilog.Critical("Could not marshal dimensions for runtime-usage: %s", errs.JoinMessage(err)) - } - if r.svcm != nil { - if err := r.svcm.ReportRuntimeUsage(context.Background(), os.Getpid(), osutils.Executable(), anaConsts.SrcStateTool, dimsJson); err != nil { - multilog.Critical("Could not report runtime usage: %s", errs.JoinMessage(err)) - } - } -} - -func recordAttempt(an analytics.Dispatcher, target setup.Targeter) { - if !target.Trigger().IndicatesUsage() { - logging.Debug("Not recording usage attempt as %s is not a usage trigger", target.Trigger().String()) - return - } - - an.Event(anaConsts.CatRuntimeUsage, anaConsts.ActRuntimeAttempt, usageDims(target)) -} - -func usageDims(target setup.Targeter) *dimensions.Values { - return &dimensions.Values{ - Trigger: ptr.To(target.Trigger().String()), - CommitID: ptr.To(target.CommitUUID().String()), - ProjectNameSpace: ptr.To(project.NewNamespace(target.Owner(), target.Name(), target.CommitUUID().String()).String()), - InstanceID: ptr.To(instanceid.ID()), - } -} - -func (r *Runtime) envDef() (*envdef.EnvironmentDefinition, error) { - if r.disabled { - return nil, errs.New("Called envDef() on a disabled runtime.") - } - env, err := r.store.EnvDef() - if err != nil { - return nil, errs.Wrap(err, "store.EnvDef failed") - } - return env, nil -} - -func (r *Runtime) ExecutablePaths() (envdef.ExecutablePaths, error) { - env, err := r.envDef() - if err != nil { - return nil, errs.Wrap(err, "Could not retrieve environment info") - } - return env.ExecutablePaths() -} - -func (r *Runtime) ExecutableDirs() (envdef.ExecutablePaths, error) { - env, err := r.envDef() - if err != nil { - return nil, errs.Wrap(err, "Could not retrieve environment info") - } - return env.ExecutableDirs() -} - -func IsRuntimeDir(dir string) bool { - return store.New(dir).HasMarker() -} - -func (r *Runtime) BuildPlan() (*buildplan.BuildPlan, error) { - runtimeStore := r.store - if runtimeStore == nil { - runtimeStore = store.New(r.target.Dir()) - } - plan, err := runtimeStore.BuildPlan() - if err != nil { - return nil, errs.Wrap(err, "Unable to fetch build plan") - } - return plan, nil -} diff --git a/pkg/platform/runtime/setup/buildlog/buildlog.go b/pkg/platform/runtime/setup/buildlog/buildlog.go deleted file mode 100644 index 8a204054c0..0000000000 --- a/pkg/platform/runtime/setup/buildlog/buildlog.go +++ /dev/null @@ -1,437 +0,0 @@ -package buildlog - -import ( - "context" - "fmt" - "os" - "strings" - "sync" - "time" - - "github.com/ActiveState/cli/pkg/buildplan" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/events" - "github.com/go-openapi/strfmt" - "github.com/gorilla/websocket" - - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/pkg/platform/api/buildlogstream" -) - -// verboseLogging is true if the user provided an environment variable for it -var verboseLogging = os.Getenv(constants.LogBuildVerboseEnvVarName) == "true" - -type recipeRequest struct { - RecipeID string `json:"recipeID"` -} - -type artifactRequest struct { - ArtifactID string `json:"artifactID"` -} - -// BuildLogConnector describes how to interact with a build log connection -type BuildLogConnector interface { - ReadJSON(interface{}) error - WriteJSON(interface{}) error -} - -type Events interface { - BuildStarting(total int) - BuildFinished() - ArtifactBuildStarting(artifactID strfmt.UUID) - ArtifactBuildCached(artifactID strfmt.UUID, logURI string) - ArtifactBuildCompleted(artifactID strfmt.UUID, logURI string) - ArtifactBuildFailed(artifactID strfmt.UUID, logURI string, errorMessage string) - ArtifactBuildProgress(artifact strfmt.UUID, timestamp string, message string, facility, pipeName, source string) - Heartbeat(time.Time) -} - -// BuildError designates a build log build error. -type BuildError struct { - *locale.LocalizedError -} - -type ArtifactBuildError struct { - *errs.WrapperError - Artifact *buildplan.Artifact - Message *ArtifactFailedMessage -} - -// EventHandlerError designates an error in the event handler for reporting progress. -type EventHandlerError struct { - *errs.WrapperError -} - -// BuildLog is an implementation of a build log -type BuildLog struct { - ch chan *buildplan.Artifact - errCh chan error - conn *websocket.Conn -} - -// New creates a new BuildLog instance that allows us to wait for incoming build log information -// artifactMap comprises all artifacts (from the runtime closure) that are in the recipe, alreadyBuilt is set of artifact IDs that have already been built in the past -func New(ctx context.Context, artifactMap buildplan.ArtifactIDMap, eventHandler events.Handler, recipeID strfmt.UUID, logFilePath string) (*BuildLog, error) { - conn, err := buildlogstream.Connect(ctx) - if err != nil { - return nil, errs.Wrap(err, "Could not connect to build-log streamer build updates") - } - bl, err := NewWithCustomConnections(artifactMap, conn, eventHandler, recipeID, logFilePath) - if err != nil { - conn.Close() - - return nil, err - } - bl.conn = conn - return bl, nil -} - -// NewWithCustomConnections creates a new BuildLog instance with all physical connections managed by the caller -func NewWithCustomConnections(artifactMap buildplan.ArtifactIDMap, - conn BuildLogConnector, eventHandler events.Handler, - recipeID strfmt.UUID, logFilePath string) (*BuildLog, error) { - - ch := make(chan *buildplan.Artifact) - errCh := make(chan error) - - if err := handleEvent(eventHandler, events.BuildStarted{logFilePath}); err != nil { - return nil, errs.Wrap(err, "Could not handle BuildStarted event") - } - - go func() { - defer close(ch) - defer close(errCh) - - // It is currently possible for the buildlogstreamer to send the same event twice. - // This happens, when nomad looses track of a build job and the HC re-schedules it. - // The following code is used to identify duplicate events. - uniqueEvents := make(map[string]struct{}) - observed := func(id ...string) bool { - idStr := strings.Join(id, ".") - _, ok := uniqueEvents[idStr] - if !ok { - uniqueEvents[idStr] = struct{}{} - } - return ok - } - - artifactsDone := make(map[strfmt.UUID]struct{}) - - // Set up log file - logMutex := &sync.Mutex{} - logfile, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - errCh <- errs.Wrap(err, "Could not open build log file") - return - } - defer logfile.Close() - writeLogFile := func(artifactID strfmt.UUID, msg string) error { - logMutex.Lock() - defer logMutex.Unlock() - name := artifactID.String() - if a, ok := artifactMap[artifactID]; ok { - name = a.Name() + " (" + artifactID.String() + ")" - } - if name != "" { - name = name + ": " - } - if _, err := logfile.WriteString(name + msg + "\n"); err != nil { - return errs.Wrap(err, "Could not write string to build log file") - } - if err := logfile.Sync(); err != nil { - return errs.Wrap(err, "Could not sync build log file") - } - return nil - } - - stillWaiting := func() []string { - result := []string{} - for id := range artifactMap { - if _, done := artifactsDone[id]; !done { - name := id.String() - if a, ok := artifactMap[id]; ok { - name = a.Name() + " (" + id.String() + ")" - } - result = append(result, name) - } - } - return result - } - - anyFailures := false - buildFinished := func() { - status := "Succeeded" - var event events.Eventer = events.BuildSuccess{} - if anyFailures { - status = "Failed" - event = events.BuildFailure{} - } - if err := writeLogFile("", "Build "+status); err != nil { - errCh <- errs.Wrap(err, "Could not write to build log file") - } - if err := handleEvent(eventHandler, event); err != nil { - errCh <- errs.Wrap(err, "Could not handle BuildSuccess/BuildFailure event") - } - } - - var artifactErr error - for { - var msg Message - err := conn.ReadJSON(&msg) - if err != nil { - // This should bubble up and logging it is just an extra measure to help with debugging - logging.Debug("Encountered error: %s", errs.JoinMessage(err)) - errCh <- err - return - } - if verboseLogging { - logging.Debug("Received response: %s", msg.MessageTypeValue()) - } - - switch msg.MessageType() { - case BuildStarted: - if observed(msg.MessageTypeValue()) { - break - } - if err := writeLogFile("", "Build Started"); err != nil { - errCh <- errs.Wrap(err, "Could not write to build log file") - } - case BuildFailed: - if observed(msg.MessageTypeValue()) { - break - } - m := msg.messager.(BuildFailedMessage) - if err := writeLogFile("", m.ErrorMessage); err != nil { - errCh <- errs.Wrap(err, "Could not write to build log file") - } - if err := handleEvent(eventHandler, events.BuildFailure{m.ErrorMessage}); err != nil { - errCh <- errs.Wrap(err, "Could not handle BuildFailure event") - } - errCh <- &BuildError{locale.WrapError(artifactErr, "err_logstream_build_failed", "Build failed with error message: {{.V0}}.", m.ErrorMessage)} - return - case BuildSucceeded: - if observed(msg.MessageTypeValue()) { - break - } - buildFinished() - return - case ArtifactStarted: - m := msg.messager.(ArtifactMessage) - // NOTE: fix to ignore current noop "final pkg artifact" - if m.ArtifactID == recipeID { - break - } - - _, ok := artifactMap[m.ArtifactID] - if !ok { - logging.Debug("Ignoring ArtifactStarted %s as we are not monitoring this artifact", m.ArtifactID) - break - } - - if observed(msg.MessageTypeValue(), m.ArtifactID.String()) { - break - } - - if err := writeLogFile(m.ArtifactID, "Artifact Build Started"); err != nil { - errCh <- errs.Wrap(err, "Could not write to build log file") - } - - if err := handleEvent(eventHandler, events.ArtifactBuildStarted{m.ArtifactID, m.CacheHit}); err != nil { - errCh <- errs.Wrap(err, "Could not handle ArtifactBuildStarted event") - } - - // if verbose build logging is requested: Also subscribe to log messages for this artifacts - // you don't want to do this by default as the log size can be quite large - if verboseLogging { - logging.Debug("requesting updates for artifact %s", m.ArtifactID.String()) - request := artifactRequest{ArtifactID: m.ArtifactID.String()} - if err := conn.WriteJSON(request); err != nil { - errCh <- errs.Wrap(err, "Could not start artifact log request") - return - } - } - case ArtifactSucceeded: - m := msg.messager.(ArtifactSucceededMessage) - - // NOTE: fix to ignore current noop "final pkg artifact" - if m.ArtifactID == recipeID { - break - } - - ad, ok := artifactMap[m.ArtifactID] - if !ok { - logging.Debug("Ignoring ArtifactSucceeded %s as we are not monitoring this artifact", m.ArtifactID) - break - } - - if observed(msg.MessageTypeValue(), m.ArtifactID.String()) { - break - } - - artifactsDone[m.ArtifactID] = struct{}{} - - if err := writeLogFile(m.ArtifactID, fmt.Sprintf(strings.TrimSpace(` -Artifact Build Succeeded. - Payload URI: %s - Log URI: %s - Used cache: %v -`), m.ArtifactURI, m.LogURI, m.CacheHit)); err != nil { - errCh <- errs.Wrap(err, "Could not write to build log file") - } - - if m.ArtifactURI == "" { - errCh <- errs.Wrap(err, "Received artifact succeeded event without artifact URL: %+v", m) - return - } - - ad.SetDownload(m.ArtifactURI, m.ArtifactChecksum) - - ch <- ad - - if err := handleEvent(eventHandler, events.ArtifactBuildSuccess{m.ArtifactID, m.LogURI}); err != nil { - errCh <- errs.Wrap(err, "Could not handle ArtifactBuildSuccess event") - return - } - - // Because we still use the recipe ID for buildlogstreamer we will end up waiting for artifacts that - // aren't actually required for our runtime. To address this we effectively send the success event - // and stop monitoring the buildlogstreamer when we've received events for all our artifacts. - // This can be dropped once buildlostreamer speaks buildplans. - if len(stillWaiting()) == 0 { - buildFinished() - return - } - case ArtifactFailed: - anyFailures = true - m := msg.messager.(ArtifactFailedMessage) - - ad, ok := artifactMap[m.ArtifactID] - if !ok { - logging.Debug("Ignoring ArtifactFailed %s as we are not monitoring this artifact", m.ArtifactID) - break - } - - if observed(msg.MessageTypeValue(), m.ArtifactID.String()) { - break - } - - artifactsDone[m.ArtifactID] = struct{}{} - - if err := writeLogFile(m.ArtifactID, fmt.Sprintf(strings.TrimSpace(` -Artifact Build Failed. - Error Message: %s - Log URI: %s -`), m.ErrorMessage, m.LogURI)); err != nil { - errCh <- errs.Wrap(err, "Could not write to build log file") - } - - artifactErr = locale.WrapError(artifactErr, "err_artifact_failed", "Failed to build \"{{.V0}}\", error reported: {{.V1}}.", ad.Name(), m.ErrorMessage) - - if err := handleEvent(eventHandler, events.ArtifactBuildFailure{m.ArtifactID, m.LogURI, m.ErrorMessage}); err != nil { - errCh <- errs.Wrap(err, "Could not handle ArtifactBuildFailure event") - return - } - - errCh <- &ArtifactBuildError{ - errs.New("artifact build failed"), - ad, - &m, - } - - if len(stillWaiting()) == 0 { - buildFinished() - return - } - - case ArtifactProgress: - m := msg.messager.(ArtifactProgressMessage) - - _, ok := artifactMap[m.ArtifactID] - if !ok { - break - } - - if _, ok := artifactsDone[m.ArtifactID]; ok { - // ignore progress reports for artifacts that have finished - break - } - - if err := writeLogFile(m.ArtifactID, "Log: "+m.Body.Message); err != nil { - errCh <- errs.Wrap(err, "Could not write to log file") - return - } - - if err := handleEvent(eventHandler, events.ArtifactBuildProgress{ - m.ArtifactID, - m.Timestamp, - m.Body.Facility, - m.PipeName, - m.Body.Message, - m.Source, - }); err != nil { - errCh <- errs.Wrap(err, "Could not handle ArtifactBuildFailure event") - return - } - case Heartbeat: - waiting := stillWaiting() - msg := fmt.Sprintf("Heartbeat (still waiting for %d more artifacts: %s)", len(waiting), strings.Join(waiting, ", ")) - if err := writeLogFile("", msg); err != nil { - errCh <- errs.Wrap(err, "Could not write to log file") - return - } - - } - } - }() - - logging.Debug("sending websocket request for %s", recipeID.String()) - request := recipeRequest{RecipeID: recipeID.String()} - if err := conn.WriteJSON(request); err != nil { - return nil, errs.Wrap(err, "Could not write websocket request") - } - - return &BuildLog{ - ch: ch, - errCh: errCh, - }, nil -} - -// Wait waits for the build log to close because the build is done and all downloadable artifacts are here -func (bl *BuildLog) Wait() error { - var rerr error - var errors []error - for err := range bl.errCh { - if rerr == nil { - rerr = errs.New("failed build") - } - rerr = errs.Pack(rerr, err) - } - if len(errors) > 0 { - return errors[0] - } - return nil -} - -func (bl *BuildLog) Close() error { - if bl.conn != nil { - if err := bl.conn.Close(); err != nil { - return errs.Wrap(err, "Failed to close websocket connection") - } - } - return nil -} - -// BuiltArtifactsChannel returns the channel to listen for downloadable artifacts on -func (bl *BuildLog) BuiltArtifactsChannel() <-chan *buildplan.Artifact { - return bl.ch -} - -func handleEvent(handler events.Handler, ev events.Eventer) error { - err := handler.Handle(ev) - if err != nil { - return &EventHandlerError{errs.Wrap(err, "Error handling event: %v", errs.JoinMessage(err))} - } - return nil -} diff --git a/pkg/platform/runtime/setup/implementations/alternative/artifact.go b/pkg/platform/runtime/setup/implementations/alternative/artifact.go deleted file mode 100644 index 6daff352ca..0000000000 --- a/pkg/platform/runtime/setup/implementations/alternative/artifact.go +++ /dev/null @@ -1,47 +0,0 @@ -package alternative - -import ( - "os" - "path/filepath" - - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/internal/unarchiver" - "github.com/ActiveState/cli/pkg/platform/runtime/envdef" - "github.com/ActiveState/cli/pkg/platform/runtime/store" - "github.com/go-openapi/strfmt" -) - -type ArtifactSetup struct { - artifactID strfmt.UUID - store *store.Store -} - -func NewArtifactSetup(artifactID strfmt.UUID, store *store.Store) *ArtifactSetup { - return &ArtifactSetup{artifactID, store} -} - -func (as *ArtifactSetup) EnvDef(tmpDir string) (*envdef.EnvironmentDefinition, error) { - path := filepath.Join(tmpDir, constants.RuntimeDefinitionFilename) - e, err := envdef.NewEnvironmentDefinition(path) - if err != nil { - return nil, errs.Wrap(err, "Could not load environment definitions for artifact.") - } - - // Remove the runtime.json file because we don't want it in the installdir - if err := os.Remove(path); err != nil { - multilog.Error("Could not remove environment definition file: %s", path) - } - - return e, nil -} - -func (as *ArtifactSetup) Move(tmpDir string) error { - return fileutils.MoveAllFilesRecursively(tmpDir, as.store.InstallPath(), func(string, string) {}) -} - -func (as *ArtifactSetup) Unarchiver() unarchiver.Unarchiver { - return unarchiver.NewTarGz() -} diff --git a/pkg/platform/runtime/setup/implementations/alternative/resolver.go b/pkg/platform/runtime/setup/implementations/alternative/resolver.go deleted file mode 100644 index a6e9df6d64..0000000000 --- a/pkg/platform/runtime/setup/implementations/alternative/resolver.go +++ /dev/null @@ -1,22 +0,0 @@ -package alternative - -import ( - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/pkg/buildplan" - "github.com/go-openapi/strfmt" -) - -type Resolver struct { - artifactsForNameResolving buildplan.ArtifactIDMap -} - -func NewResolver(artifactsForNameResolving buildplan.ArtifactIDMap) *Resolver { - return &Resolver{artifactsForNameResolving: artifactsForNameResolving} -} - -func (r *Resolver) ResolveArtifactName(id strfmt.UUID) string { - if artf, ok := r.artifactsForNameResolving[id]; ok { - return artf.Name() - } - return locale.T("alternative_unknown_pkg_name") -} diff --git a/pkg/platform/runtime/setup/implementations/alternative/runtime.go b/pkg/platform/runtime/setup/implementations/alternative/runtime.go deleted file mode 100644 index b207303de4..0000000000 --- a/pkg/platform/runtime/setup/implementations/alternative/runtime.go +++ /dev/null @@ -1,145 +0,0 @@ -package alternative - -import ( - "os" - "path/filepath" - "sort" - - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/pkg/buildplan" - "github.com/ActiveState/cli/pkg/platform/runtime/store" - "github.com/go-openapi/strfmt" - "github.com/thoas/go-funk" -) - -type Setup struct { - store *store.Store -} - -func NewSetup(store *store.Store) *Setup { - return &Setup{store: store} -} - -func (s *Setup) DeleteOutdatedArtifacts(changeset *buildplan.ArtifactChangeset, storedArtifacted, alreadyInstalled store.StoredArtifactMap) error { - if changeset == nil { - return nil - } - - del := map[strfmt.UUID]struct{}{} - for _, upd := range changeset.Updated { - del[upd.From.ArtifactID] = struct{}{} - } - for _, rem := range changeset.Removed { - del[rem.ArtifactID] = struct{}{} - } - - // sort files and dirs in keep for faster look-up - for _, artf := range alreadyInstalled { - sort.Strings(artf.Dirs) - sort.Strings(artf.Files) - } - - for _, artf := range storedArtifacted { - if _, deleteMe := del[artf.ArtifactID]; !deleteMe { - continue - } - - for _, file := range artf.Files { - if !fileutils.TargetExists(file) { - continue // don't care it's already deleted (might have been deleted by another artifact that supplied the same file) - } - if artifactsContainFile(file, alreadyInstalled) { - continue - } - if err := os.Remove(file); err != nil { - return locale.WrapError(err, "err_rm_artf", "Could not remove old package file at {{.V0}}.", file) - } - } - - dirs := artf.Dirs - sort.Slice(dirs, func(i, j int) bool { - return dirs[i] > dirs[j] - }) - - for _, dir := range dirs { - if !fileutils.DirExists(dir) { - continue - } - - deleteOk, err := dirCanBeDeleted(dir, alreadyInstalled) - if err != nil { - multilog.Error("Could not determine if directory %s could be deleted: %v", dir, err) - continue - } - if !deleteOk { - continue - } - - err = os.RemoveAll(dir) - if err != nil { - return locale.WrapError(err, "err_rm_artf_dir", "Could not remove empty artifact directory at {{.V0}}", dir) - } - } - - if err := s.store.DeleteArtifactStore(artf.ArtifactID); err != nil { - return errs.Wrap(err, "Could not delete artifact store") - } - } - - return nil -} - -// dirCanBeDeleted checks if the given directory is empty - ignoring files and sub-directories that -// are not in the cache. -func dirCanBeDeleted(dir string, cache map[strfmt.UUID]store.StoredArtifact) (bool, error) { - if artifactsContainDir(dir, cache) { - return false, nil - } - - entries, err := os.ReadDir(dir) - if err != nil { - return false, errs.Wrap(err, "Could not read directory.") - } - for _, entry := range entries { - if entry.IsDir() { - if artifactsContainDir(filepath.Join(dir, entry.Name()), cache) { - return false, nil - } - } else { - if artifactsContainFile(filepath.Join(dir, entry.Name()), cache) { - return false, nil - } - } - } - return true, nil -} - -func sortedStringSliceContains(slice []string, x string) bool { - i := sort.SearchStrings(slice, x) - return i != len(slice) && slice[i] == x -} - -func artifactsContainDir(dir string, artifactCache map[strfmt.UUID]store.StoredArtifact) bool { - for _, v := range artifactCache { - if funk.Contains(v.Dirs, dir) { - return true - } - } - return false -} - -func artifactsContainFile(file string, artifactCache map[strfmt.UUID]store.StoredArtifact) bool { - for _, v := range artifactCache { - if sortedStringSliceContains(v.Files, file) { - return true - } - } - return false -} - -func (s *Setup) ResolveArtifactName(a strfmt.UUID) string { - return locale.T("alternative_unknown_pkg_name") -} diff --git a/pkg/platform/runtime/setup/implementations/camel/resolver.go b/pkg/platform/runtime/setup/implementations/camel/resolver.go deleted file mode 100644 index c48eb8fe88..0000000000 --- a/pkg/platform/runtime/setup/implementations/camel/resolver.go +++ /dev/null @@ -1,16 +0,0 @@ -package camel - -import ( - "github.com/ActiveState/cli/internal/locale" - "github.com/go-openapi/strfmt" -) - -type Resolver struct{} - -func NewResolver() *Resolver { - return &Resolver{} -} - -func (r *Resolver) ResolveArtifactName(_ strfmt.UUID) string { - return locale.Tl("camel_bundle_name", "legacy bundle") -} diff --git a/pkg/platform/runtime/setup/implementations/camel/runtime.go b/pkg/platform/runtime/setup/implementations/camel/runtime.go deleted file mode 100644 index 42fd0370ad..0000000000 --- a/pkg/platform/runtime/setup/implementations/camel/runtime.go +++ /dev/null @@ -1,46 +0,0 @@ -package camel - -import ( - "os" - "path/filepath" - - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/pkg/buildplan" - "github.com/ActiveState/cli/pkg/platform/runtime/store" - "github.com/go-openapi/strfmt" -) - -type Setup struct { - store *store.Store -} - -func NewSetup(s *store.Store) *Setup { - return &Setup{s} -} - -// DeleteOutdatedArtifacts deletes the entire installation directory, unless alreadyInstalled is not zero, which can happen when the executors directory needs to be re-generated. -func (s *Setup) DeleteOutdatedArtifacts(_ *buildplan.ArtifactChangeset, _, alreadyInstalled store.StoredArtifactMap) error { - if len(alreadyInstalled) != 0 { - return nil - } - files, err := os.ReadDir(s.store.InstallPath()) - if err != nil { - return errs.Wrap(err, "Error reading previous camel installation") - } - for _, file := range files { - if file.Name() == constants.LocalRuntimeTempDirectory || file.Name() == constants.LocalRuntimeEnvironmentDirectory { - continue // do not delete files that do not belong to previous installation - } - err = os.RemoveAll(filepath.Join(s.store.InstallPath(), file.Name())) - if err != nil { - return errs.Wrap(err, "Error removing previous camel installation") - } - } - return nil -} - -func (s *Setup) ResolveArtifactName(_ strfmt.UUID) string { - return locale.Tl("camel_bundle_name", "bundle") -} diff --git a/pkg/platform/runtime/setup/setup.go b/pkg/platform/runtime/setup/setup.go deleted file mode 100644 index 03b11f6f28..0000000000 --- a/pkg/platform/runtime/setup/setup.go +++ /dev/null @@ -1,1032 +0,0 @@ -package setup - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net/url" - "os" - "path/filepath" - rt "runtime" - "strings" - "sync" - "time" - - "github.com/ActiveState/cli/internal/analytics" - anaConsts "github.com/ActiveState/cli/internal/analytics/constants" - "github.com/ActiveState/cli/internal/analytics/dimensions" - "github.com/ActiveState/cli/internal/condition" - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/graph" - "github.com/ActiveState/cli/internal/httputil" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/internal/output" - "github.com/ActiveState/cli/internal/proxyreader" - "github.com/ActiveState/cli/internal/rollbar" - "github.com/ActiveState/cli/internal/rtutils/ptr" - "github.com/ActiveState/cli/internal/runbits/buildscript" - "github.com/ActiveState/cli/internal/sliceutils" - "github.com/ActiveState/cli/internal/svcctl" - "github.com/ActiveState/cli/internal/unarchiver" - "github.com/ActiveState/cli/pkg/buildplan" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/ActiveState/cli/pkg/platform/authentication" - "github.com/ActiveState/cli/pkg/platform/model" - bpModel "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/platform/runtime/artifactcache" - "github.com/ActiveState/cli/pkg/platform/runtime/envdef" - "github.com/ActiveState/cli/pkg/platform/runtime/executors" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/buildlog" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/events" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/events/progress" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/implementations/alternative" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/implementations/camel" - "github.com/ActiveState/cli/pkg/platform/runtime/store" - "github.com/ActiveState/cli/pkg/platform/runtime/target" - "github.com/ActiveState/cli/pkg/platform/runtime/validate" - "github.com/ActiveState/cli/pkg/sysinfo" - "github.com/faiface/mainthread" - "github.com/gammazero/workerpool" - "github.com/go-openapi/strfmt" -) - -// MaxConcurrency is maximum number of parallel artifact installations -const MaxConcurrency = 5 - -// NotInstalledError is an error returned when the runtime is not completely installed yet. -var NotInstalledError = errs.New("Runtime is not completely installed.") - -// BuildError designates a recipe build error. -type BuildError struct { - *locale.LocalizedError -} - -// ArtifactDownloadError designates an error downloading an artifact. -type ArtifactDownloadError struct { - *errs.WrapperError -} - -// ArtifactCachedBuildFailed designates an error due to a build for an artifact that failed and has been cached -type ArtifactCachedBuildFailed struct { - *errs.WrapperError - Artifact *buildplan.Artifact -} - -// ArtifactInstallError designates an error installing a downloaded artifact. -type ArtifactInstallError struct { - *errs.WrapperError -} - -// ArtifactSetupErrors combines all errors that can happen while installing artifacts in parallel -type ArtifactSetupErrors struct { - errs []error -} - -type ExecutorSetupError struct { - *errs.WrapperError -} - -func (a *ArtifactSetupErrors) Error() string { - var errors []string - for _, err := range a.errs { - errors = append(errors, errs.JoinMessage(err)) - } - return "Not all artifacts could be installed, errors:\n" + strings.Join(errors, "\n") -} - -func (a *ArtifactSetupErrors) Unwrap() []error { - return a.errs -} - -// Errors returns the individual error messages collected from all failing artifact installations -func (a *ArtifactSetupErrors) Errors() []error { - return a.errs -} - -// UserError returns a message including all user-facing sub-error messages -func (a *ArtifactSetupErrors) LocalizedError() string { - var errStrings []string - for _, err := range a.errs { - errStrings = append(errStrings, locale.JoinedErrorMessage(err)) - } - return locale.Tl("setup_artifacts_err", "Not all artifacts could be installed:\n{{.V0}}", strings.Join(errStrings, "\n")) -} - -// ProgressReportError designates an error in the event handler for reporting progress. -type ProgressReportError struct { - *errs.WrapperError -} - -type RuntimeInUseError struct { - *locale.LocalizedError - Processes []*graph.ProcessInfo -} - -type Targeter interface { - CommitUUID() strfmt.UUID - Name() string - Owner() string - Dir() string - Trigger() target.Trigger - ProjectDir() string - - // ReadOnly communicates that this target should only use cached runtime information (ie. don't check for updates) - ReadOnly() bool - // InstallFromDir communicates that this target should only install artifacts from the given directory (i.e. offline installer) - InstallFromDir() *string -} - -type Configurable interface { - GetString(key string) string - GetBool(key string) bool -} - -type Setup struct { - auth *authentication.Auth - target Targeter - eventHandler events.Handler - store *store.Store - analytics analytics.Dispatcher - artifactCache *artifactcache.ArtifactCache - cfg Configurable - out output.Outputer - svcm *model.SvcModel -} - -type Setuper interface { - // DeleteOutdatedArtifacts deletes outdated artifact as best as it can - DeleteOutdatedArtifacts(*buildplan.ArtifactChangeset, store.StoredArtifactMap, store.StoredArtifactMap) error -} - -// ArtifactSetuper is the interface for an implementation of artifact setup functions -// These need to be specialized for each BuildEngine type -type ArtifactSetuper interface { - EnvDef(tmpInstallDir string) (*envdef.EnvironmentDefinition, error) - Unarchiver() unarchiver.Unarchiver -} - -type ArtifactResolver interface { - ResolveArtifactName(strfmt.UUID) string -} - -type artifactInstaller func(strfmt.UUID, string, ArtifactSetuper) error -type artifactUninstaller func() error - -// New returns a new Setup instance that can install a Runtime locally on the machine. -func New(target Targeter, eventHandler events.Handler, auth *authentication.Auth, an analytics.Dispatcher, cfg Configurable, out output.Outputer, svcm *model.SvcModel) *Setup { - cache, err := artifactcache.New() - if err != nil { - multilog.Error("Could not create artifact cache: %v", err) - } - return &Setup{auth, target, eventHandler, store.New(target.Dir()), an, cache, cfg, out, svcm} -} - -func (s *Setup) Solve() (*bpModel.Commit, error) { - defer func() { - s.solveUpdateRecover(recover()) - }() - - if s.target.InstallFromDir() != nil { - return nil, nil - } - - if err := s.handleEvent(events.SolveStart{}); err != nil { - return nil, errs.Wrap(err, "Could not handle SolveStart event") - } - - bpm := bpModel.NewBuildPlannerModel(s.auth) - commit, err := bpm.FetchCommit(s.target.CommitUUID(), s.target.Owner(), s.target.Name(), nil) - if err != nil { - return nil, errs.Wrap(err, "Failed to fetch build result") - } - - if err := s.eventHandler.Handle(events.SolveSuccess{}); err != nil { - return nil, errs.Wrap(err, "Could not handle SolveSuccess event") - } - - return commit, nil -} - -func (s *Setup) Update(commit *bpModel.Commit) (rerr error) { - defer func() { - s.solveUpdateRecover(recover()) - }() - defer func() { - var ev events.Eventer = events.Success{} - if rerr != nil { - ev = events.Failure{} - } - - err := s.handleEvent(ev) - if err != nil { - multilog.Error("Could not handle Success/Failure event: %s", errs.JoinMessage(err)) - } - }() - - bp := commit.BuildPlan() - - // Do not allow users to deploy runtimes to the root directory (this can easily happen in docker - // images). Note that runtime targets are fully resolved via fileutils.ResolveUniquePath(), so - // paths like "/." and "/opt/.." resolve to simply "/" at this time. - if rt.GOOS != "windows" && s.target.Dir() == "/" { - return locale.NewInputError("err_runtime_setup_root", "Cannot set up a runtime in the root directory. Please specify or run from a user-writable directory.") - } - - // Determine if this runtime is currently in use. - ctx, cancel := context.WithTimeout(context.Background(), model.SvcTimeoutMinimal) - defer cancel() - if procs, err := s.svcm.GetProcessesInUse(ctx, ExecDir(s.target.Dir())); err == nil { - if len(procs) > 0 { - list := []string{} - for _, proc := range procs { - list = append(list, fmt.Sprintf(" - %s (process: %d)", proc.Exe, proc.Pid)) - } - return &RuntimeInUseError{locale.NewInputError("runtime_setup_in_use_err", "", strings.Join(list, "\n")), procs} - } - } else { - multilog.Error("Unable to determine if runtime is in use: %v", errs.JoinMessage(err)) - } - - // Update all the runtime artifacts - artifacts, err := s.updateArtifacts(bp) - if err != nil { - return errs.Wrap(err, "Failed to update artifacts") - } - - if err := s.store.StoreBuildPlan(bp); err != nil { - return errs.Wrap(err, "Could not save recipe file.") - } - - if err := s.store.StoreBuildScript(commit.BuildScript()); err != nil { - return errs.Wrap(err, "Could not store buildscript file.") - } - - if s.target.ProjectDir() != "" && s.cfg.GetBool(constants.OptinBuildscriptsConfig) { - if err := buildscript_runbit.Update(s.target, commit.BuildScript()); err != nil { - return errs.Wrap(err, "Could not update build script") - } - } - - // Update executors - if err := s.updateExecutors(artifacts); err != nil { - return ExecutorSetupError{errs.Wrap(err, "Failed to update executors")} - } - - // Mark installation as completed - if err := s.store.MarkInstallationComplete(s.target.CommitUUID(), fmt.Sprintf("%s/%s", s.target.Owner(), s.target.Name())); err != nil { - return errs.Wrap(err, "Could not mark install as complete.") - } - - return nil -} - -// Panics are serious, and reproducing them in the runtime package is HARD. To help with this we dump -// the build plan when a panic occurs so we have something more to go on. -func (s *Setup) solveUpdateRecover(r interface{}) { - if r == nil { - return - } - - multilog.Critical("Panic during runtime update: %s", r) - panic(r) // We're just logging the panic while we have context, we're not meant to handle it here -} - -func (s *Setup) updateArtifacts(bp *buildplan.BuildPlan) ([]strfmt.UUID, error) { - mutex := &sync.Mutex{} - var installArtifactFuncs []func() error - - // Fetch and install each runtime artifact. - // Note: despite the name, we are "pre-installing" the artifacts to a temporary location. - // Once all artifacts are fetched, unpacked, and prepared, final installation occurs. - artifacts, uninstallFunc, err := s.fetchAndInstallArtifacts(bp, func(a strfmt.UUID, archivePath string, as ArtifactSetuper) (rerr error) { - defer func() { - if rerr != nil { - rerr = &ArtifactInstallError{errs.Wrap(rerr, "Unable to install artifact")} - if err := s.handleEvent(events.ArtifactInstallFailure{a, rerr}); err != nil { - rerr = errs.Wrap(rerr, "Could not handle ArtifactInstallFailure event") - return - } - } - if err := s.handleEvent(events.ArtifactInstallSuccess{a}); err != nil { - rerr = errs.Wrap(rerr, "Could not handle ArtifactInstallSuccess event") - return - } - }() - - // Set up target and unpack directories - targetDir := filepath.Join(s.store.InstallPath(), constants.LocalRuntimeTempDirectory) - if err := fileutils.MkdirUnlessExists(targetDir); err != nil { - return errs.Wrap(err, "Could not create temp runtime dir") - } - unpackedDir := filepath.Join(targetDir, a.String()) - - logging.Debug("Unarchiving %s to %s", archivePath, unpackedDir) - - // ensure that the unpack dir is empty - err := os.RemoveAll(unpackedDir) - if err != nil { - return errs.Wrap(err, "Could not remove previous temporary installation directory.") - } - - // Unpack artifact archive - numFiles, err := s.unpackArtifact(as.Unarchiver(), archivePath, unpackedDir, &progress.Report{ - ReportSizeCb: func(size int) error { - if err := s.handleEvent(events.ArtifactInstallStarted{a, size}); err != nil { - return errs.Wrap(err, "Could not handle ArtifactInstallStarted event") - } - return nil - }, - ReportIncrementCb: func(inc int) error { - if err := s.handleEvent(events.ArtifactInstallProgress{a, inc}); err != nil { - return errs.Wrap(err, "Could not handle ArtifactInstallProgress event") - } - return nil - }, - }) - if err != nil { - err := errs.Wrap(err, "Could not unpack artifact %s", archivePath) - return err - } - - // Set up constants used to expand environment definitions - cnst, err := envdef.NewConstants(s.store.InstallPath()) - if err != nil { - return errs.Wrap(err, "Could not get new environment constants") - } - - // Retrieve environment definitions for artifact - envDef, err := as.EnvDef(unpackedDir) - if err != nil { - return errs.Wrap(err, "Could not collect env info for artifact") - } - - // Expand environment definitions using constants - envDef = envDef.ExpandVariables(cnst) - err = envDef.ApplyFileTransforms(filepath.Join(unpackedDir, envDef.InstallDir), cnst) - if err != nil { - return locale.WrapError(err, "runtime_alternative_file_transforms_err", "", "Could not apply necessary file transformations after unpacking") - } - - mutex.Lock() - installArtifactFuncs = append(installArtifactFuncs, func() error { - return s.moveToInstallPath(a, unpackedDir, envDef, numFiles) - }) - mutex.Unlock() - - return nil - }) - if err != nil { - return artifacts, locale.WrapError(err, "err_runtime_setup") - } - - if os.Getenv(constants.RuntimeSetupWaitEnvVarName) != "" && (condition.OnCI() || condition.BuiltOnDevMachine()) { - // This code block is for integration testing purposes only. - // Under normal conditions, we should never access fmt or os.Stdin from this context. - fmt.Printf("Waiting for input because %s was set\n", constants.RuntimeSetupWaitEnvVarName) - ch := make([]byte, 1) - _, err = os.Stdin.Read(ch) // block until input is sent - if err != nil { - return artifacts, locale.WrapError(err, "err_runtime_setup") - } - } - - // Uninstall outdated artifacts. - // This must come before calling any installArtifactFuncs or else the runtime may become corrupt. - if uninstallFunc != nil { - err := uninstallFunc() - if err != nil { - return artifacts, locale.WrapError(err, "err_runtime_setup") - } - } - - // Move files to final installation path after successful download and unpack. - for _, f := range installArtifactFuncs { - err := f() - if err != nil { - return artifacts, locale.WrapError(err, "err_runtime_setup") - } - } - - // Clean up temp directory. - tempDir := filepath.Join(s.store.InstallPath(), constants.LocalRuntimeTempDirectory) - err = os.RemoveAll(tempDir) - if err != nil { - multilog.Log(logging.ErrorNoStacktrace, rollbar.Error)("Failed to remove temporary installation directory %s: %v", tempDir, err) - } - - return artifacts, nil -} - -func (s *Setup) updateExecutors(artifacts []strfmt.UUID) error { - execPath := ExecDir(s.target.Dir()) - if err := fileutils.MkdirUnlessExists(execPath); err != nil { - return locale.WrapError(err, "err_deploy_execpath", "Could not create exec directory.") - } - - edGlobal, err := s.store.UpdateEnviron(artifacts) - if err != nil { - return errs.Wrap(err, "Could not save combined environment file") - } - - exePaths, err := edGlobal.ExecutablePaths() - if err != nil { - return locale.WrapError(err, "err_deploy_execpaths", "Could not retrieve runtime executable paths") - } - - env, err := s.store.Environ(false) - if err != nil { - return locale.WrapError(err, "err_setup_get_runtime_env", "Could not retrieve runtime environment") - } - - execInit := executors.New(execPath) - if err := execInit.Apply(svcctl.NewIPCSockPathFromGlobals().String(), s.target, env, exePaths); err != nil { - return locale.WrapError(err, "err_deploy_executors", "Could not create executors") - } - - return nil -} - -// fetchAndInstallArtifacts returns all artifacts needed by the runtime, even if some or -// all of them were already installed. -// It may also return an artifact uninstaller function that should be run prior to final -// installation. -func (s *Setup) fetchAndInstallArtifacts(bp *buildplan.BuildPlan, installFunc artifactInstaller) ([]strfmt.UUID, artifactUninstaller, error) { - if s.target.InstallFromDir() != nil { - artifacts, err := s.fetchAndInstallArtifactsFromDir(installFunc) - return artifacts, nil, err - } - return s.fetchAndInstallArtifactsFromBuildPlan(bp, installFunc) -} - -func (s *Setup) fetchAndInstallArtifactsFromBuildPlan(bp *buildplan.BuildPlan, installFunc artifactInstaller) ([]strfmt.UUID, artifactUninstaller, error) { - // If the build is not ready or if we are installing the buildtime closure - // then we need to include the buildtime closure in the changed artifacts - // and the progress reporting. - includeBuildtimeClosure := strings.EqualFold(os.Getenv(constants.InstallBuildDependencies), "true") || !bp.IsBuildReady() - - platformID, err := model.FilterCurrentPlatform(sysinfo.OS().String(), bp.Platforms(), s.cfg) - if err != nil { - return nil, nil, locale.WrapError(err, "err_filter_current_platform") - } - - artifactFilters := []buildplan.FilterArtifact{ - buildplan.FilterStateArtifacts(), - buildplan.FilterPlatformArtifacts(platformID), - } - - // Compute and handle the change summary - allArtifacts := bp.Artifacts(artifactFilters...) - - // Detect failed artifacts early - for _, a := range allArtifacts { - var aErr error - if a.Status == types.ArtifactFailedPermanently || a.Status == types.ArtifactFailedTransiently { - errV := &ArtifactCachedBuildFailed{errs.New("artifact failed, status: %s", a.Status), a} - if aErr == nil { - aErr = errV - } else { - aErr = errs.Pack(aErr, errV) - } - } - if aErr != nil { - return nil, nil, aErr - } - } - - if len(allArtifacts) == 0 { - v, err := json.Marshal(bp.Artifacts()) - if err != nil { - return nil, nil, err - } - return nil, nil, errs.New("did not find any artifacts that match our platform (%s), full artifacts list: %s", platformID, v) - } - - resolver, err := selectArtifactResolver(bp) - if err != nil { - return nil, nil, errs.Wrap(err, "Failed to select artifact resolver") - } - - // build results don't have namespace info and will happily report internal only artifacts - downloadablePrebuiltArtifacts := sliceutils.Filter(allArtifacts, func(a *buildplan.Artifact) bool { - return a.Status == types.ArtifactSucceeded && a.URL != "" - }) - - // Analytics data to send. - dimensions := &dimensions.Values{ - CommitID: ptr.To(s.target.CommitUUID().String()), - } - - // send analytics build event, if a new runtime has to be built in the cloud - if bp.IsBuildInProgress() { - s.analytics.Event(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeBuild, dimensions) - } - - oldBuildPlan, err := s.store.BuildPlan() - if err != nil && !errors.As(err, ptr.To(&store.ErrVersionMarker{})) { - return nil, nil, errs.Wrap(err, "could not load existing build plan") - } - - var changedArtifacts *buildplan.ArtifactChangeset - if oldBuildPlan != nil { - changedArtifacts = ptr.To(bp.DiffArtifacts(oldBuildPlan, true)) - } - - storedArtifacts, err := s.store.Artifacts() - if err != nil { - return nil, nil, locale.WrapError(err, "err_stored_artifacts") - } - - alreadyInstalled := reusableArtifacts(allArtifacts, storedArtifacts) - - artifactNamesList := []string{} - for _, a := range allArtifacts { - artifactNamesList = append(artifactNamesList, a.Name()) - } - installedList := []string{} - for _, a := range alreadyInstalled { - installedList = append(installedList, resolver.ResolveArtifactName(a.ArtifactID)) - } - downloadList := []string{} - for _, a := range downloadablePrebuiltArtifacts { - downloadList = append(downloadList, resolver.ResolveArtifactName(a.ArtifactID)) - } - logging.Debug( - "Parsed artifacts.\nBuild ready: %v\nArtifact names: %v\nAlready installed: %v\nTo Download: %v", - bp.IsBuildReady(), artifactNamesList, installedList, downloadList, - ) - - filterNeedsInstall := func(a *buildplan.Artifact) bool { - _, alreadyInstalled := alreadyInstalled[a.ArtifactID] - return !alreadyInstalled - } - filters := []buildplan.FilterArtifact{filterNeedsInstall} - if !includeBuildtimeClosure { - filters = append(filters, buildplan.FilterRuntimeArtifacts()) - } - artifactsToInstall := allArtifacts.Filter(filters...) - if err != nil { - return nil, nil, errs.Wrap(err, "Failed to compute artifacts to build") - } - - // The log file we want to use for builds - logFilePath := logging.FilePathFor(fmt.Sprintf("build-%s.log", s.target.CommitUUID().String()+"-"+time.Now().Format("20060102150405"))) - - recipeID, err := bp.RecipeID() - if err != nil { - return nil, nil, errs.Wrap(err, "Could not get recipe ID from build plan") - } - - artifactNameMap := map[strfmt.UUID]string{} - for _, a := range allArtifacts { - artifactNameMap[a.ArtifactID] = a.Name() - } - - if err := s.eventHandler.Handle(events.Start{ - RecipeID: recipeID, - RequiresBuild: bp.IsBuildInProgress(), - Artifacts: artifactNameMap, - LogFilePath: logFilePath, - ArtifactsToBuild: allArtifacts.ToIDSlice(), - // Yes these have the same value; this is intentional. - // Separating these out just allows us to be more explicit and intentional in our event handling logic. - ArtifactsToDownload: artifactsToInstall.ToIDSlice(), - ArtifactsToInstall: artifactsToInstall.ToIDSlice(), - }); err != nil { - return nil, nil, errs.Wrap(err, "Could not handle Start event") - } - - var uninstallArtifacts artifactUninstaller = func() error { - setup, err := s.selectSetupImplementation(bp.Engine()) - if err != nil { - return errs.Wrap(err, "Failed to select setup implementation") - } - return s.deleteOutdatedArtifacts(setup, changedArtifacts, alreadyInstalled) - } - - // only send the download analytics event, if we have to install artifacts that are not yet installed - if len(artifactsToInstall) > 0 { - // if we get here, we download artifacts - s.analytics.Event(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeDownload, dimensions) - } - - buildReady := bp.IsBuildReady() - filterInstallable := func(a *buildplan.Artifact) bool { return a.URL != "" } - if !buildReady && len(artifactsToInstall.Filter(buildplan.FilterSuccessfulArtifacts(), filterInstallable)) == len(artifactsToInstall) { - // Even though the build may not be complete, all of the necessary artifacts are ready. - buildReady = true - } - err = s.installArtifactsFromBuild(buildReady, bp.Engine(), recipeID, artifactsToInstall, installFunc, logFilePath) - if err != nil { - return nil, nil, err - } - err = s.artifactCache.Save() - if err != nil { - multilog.Error("Could not save artifact cache updates: %v", err) - } - - artifactIDs := allArtifacts.ToIDSlice() - logging.Debug("Returning artifacts: %v", artifactIDs) - return artifactIDs, uninstallArtifacts, nil -} - -func aggregateErrors() (chan<- error, <-chan error) { - aggErr := make(chan error) - bgErrs := make(chan error) - go func() { - var errs []error - for err := range bgErrs { - errs = append(errs, err) - } - - if len(errs) > 0 { - aggErr <- &ArtifactSetupErrors{errs} - } else { - aggErr <- nil - } - }() - - return bgErrs, aggErr -} - -func (s *Setup) installArtifactsFromBuild(isReady bool, engine types.BuildEngine, recipeID strfmt.UUID, artifacts buildplan.Artifacts, installFunc artifactInstaller, logFilePath string) error { - // Artifacts are installed in two stages - // - The first stage runs concurrently in MaxConcurrency worker threads (download, unpacking, relocation) - // - The second stage moves all files into its final destination is running in a single thread (using the mainthread library) to avoid file conflicts - - var err error - if isReady { - logging.Debug("Installing via build result") - if err := s.handleEvent(events.BuildSkipped{}); err != nil { - return errs.Wrap(err, "Could not handle BuildSkipped event") - } - err = s.installFromBuildResult(engine, artifacts, installFunc) - if err != nil { - err = errs.Wrap(err, "Installing via build result failed") - } - } else { - logging.Debug("Installing via buildlog streamer") - err = s.installFromBuildLog(engine, recipeID, artifacts, installFunc, logFilePath) - if err != nil { - err = errs.Wrap(err, "Installing via buildlog streamer failed") - } - } - - return err -} - -// setupArtifactSubmitFunction returns a function that sets up an artifact and can be submitted to a workerpool -func (s *Setup) setupArtifactSubmitFunction( - engine types.BuildEngine, - ar *buildplan.Artifact, - installFunc artifactInstaller, - errors chan<- error, -) func() { - return func() { - as, err := s.selectArtifactSetupImplementation(engine, ar.ArtifactID) - if err != nil { - errors <- errs.Wrap(err, "Failed to select artifact setup implementation") - return - } - - unarchiver := as.Unarchiver() - archivePath, err := s.obtainArtifact(ar, unarchiver.Ext()) - if err != nil { - errors <- locale.WrapError(err, "artifact_download_failed", "", ar.Name(), ar.ArtifactID.String()) - return - } - - err = installFunc(ar.ArtifactID, archivePath, as) - if err != nil { - errors <- locale.WrapError(err, "artifact_setup_failed", "", ar.Name(), ar.ArtifactID.String()) - return - } - } -} - -func (s *Setup) installFromBuildResult(engine types.BuildEngine, artifacts buildplan.Artifacts, installFunc artifactInstaller) error { - logging.Debug("Installing artifacts from build result") - errs, aggregatedErr := aggregateErrors() - mainthread.Run(func() { - defer close(errs) - wp := workerpool.New(MaxConcurrency) - for _, a := range artifacts { - wp.Submit(s.setupArtifactSubmitFunction(engine, a, installFunc, errs)) - } - - wp.StopWait() - }) - - return <-aggregatedErr -} - -func (s *Setup) installFromBuildLog(engine types.BuildEngine, recipeID strfmt.UUID, artifacts buildplan.Artifacts, installFunc artifactInstaller, logFilePath string) error { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - buildLog, err := buildlog.New(ctx, artifacts.ToIDMap(), s.eventHandler, recipeID, logFilePath) - if err != nil { - return errs.Wrap(err, "Cannot establish connection with BuildLog") - } - defer func() { - if err := buildLog.Close(); err != nil { - logging.Debug("Failed to close build log: %v", errs.JoinMessage(err)) - } - }() - - errs, aggregatedErr := aggregateErrors() - - mainthread.Run(func() { - defer close(errs) - - var wg sync.WaitGroup - defer wg.Wait() - wg.Add(1) - go func() { - // wp.StopWait needs to be run in this go-routine after ALL tasks are scheduled, hence we need to add an extra wait group - defer wg.Done() - wp := workerpool.New(MaxConcurrency) - defer wp.StopWait() - - for a := range buildLog.BuiltArtifactsChannel() { - wp.Submit(s.setupArtifactSubmitFunction(engine, a, installFunc, errs)) - } - }() - - if err = buildLog.Wait(); err != nil { - errs <- err - } - }) - - return <-aggregatedErr -} - -func (s *Setup) moveToInstallPath(a strfmt.UUID, unpackedDir string, envDef *envdef.EnvironmentDefinition, numFiles int) error { - // clean up the unpacked dir - defer os.RemoveAll(unpackedDir) - - var files []string - var dirs []string - onMoveFile := func(fromPath, toPath string) { - if fileutils.IsDir(toPath) { - dirs = append(dirs, toPath) - } else { - files = append(files, toPath) - } - } - err := fileutils.MoveAllFilesRecursively( - filepath.Join(unpackedDir, envDef.InstallDir), - s.store.InstallPath(), onMoveFile, - ) - if err != nil { - err := errs.Wrap(err, "Move artifact failed") - return err - } - - if err := s.store.StoreArtifact(store.NewStoredArtifact(a, files, dirs, envDef)); err != nil { - return errs.Wrap(err, "Could not store artifact meta info") - } - - return nil -} - -// downloadArtifact downloads the given artifact -func (s *Setup) downloadArtifact(a *buildplan.Artifact, targetFile string) (rerr error) { - defer func() { - if rerr != nil { - if !errs.Matches(rerr, &ProgressReportError{}) { - rerr = &ArtifactDownloadError{errs.Wrap(rerr, "Unable to download artifact")} - } - - if err := s.handleEvent(events.ArtifactDownloadFailure{a.ArtifactID, rerr}); err != nil { - rerr = errs.Wrap(rerr, "Could not handle ArtifactDownloadFailure event") - return - } - } - - if err := s.handleEvent(events.ArtifactDownloadSuccess{a.ArtifactID}); err != nil { - rerr = errs.Wrap(rerr, "Could not handle ArtifactDownloadSuccess event") - return - } - }() - - if a.URL == "" { - return errs.New("Artifact URL is empty: %+v", a) - } - - artifactURL, err := url.Parse(a.URL) - if err != nil { - return errs.Wrap(err, "Could not parse artifact URL %s.", a.URL) - } - - b, err := httputil.GetWithProgress(artifactURL.String(), &progress.Report{ - ReportSizeCb: func(size int) error { - if err := s.handleEvent(events.ArtifactDownloadStarted{a.ArtifactID, size}); err != nil { - return ProgressReportError{errs.Wrap(err, "Could not handle ArtifactDownloadStarted event")} - } - return nil - }, - ReportIncrementCb: func(inc int) error { - if err := s.handleEvent(events.ArtifactDownloadProgress{a.ArtifactID, inc}); err != nil { - return errs.Wrap(err, "Could not handle ArtifactDownloadProgress event") - } - return nil - }, - }) - if err != nil { - return errs.Wrap(err, "Download %s failed", artifactURL.String()) - } - - if err := fileutils.WriteFile(targetFile, b); err != nil { - return errs.Wrap(err, "Writing download to target file %s failed", targetFile) - } - - return nil -} - -// verifyArtifact verifies the checksum of the downloaded artifact matches the checksum given by the -// platform, and returns an error if the verification fails. -func (s *Setup) verifyArtifact(archivePath string, a *buildplan.Artifact) error { - return validate.Checksum(archivePath, a.Checksum) -} - -// obtainArtifact obtains an artifact and returns the local path to that artifact's archive. -func (s *Setup) obtainArtifact(a *buildplan.Artifact, extension string) (string, error) { - if cachedPath, found := s.artifactCache.Get(a.ArtifactID); found { - if err := s.verifyArtifact(cachedPath, a); err == nil { - if err := s.handleEvent(events.ArtifactDownloadSkipped{a.ArtifactID}); err != nil { - return "", errs.Wrap(err, "Could not handle ArtifactDownloadSkipped event") - } - return cachedPath, nil - } - // otherwise re-download it; do not return an error - } - - targetDir := filepath.Join(s.store.InstallPath(), constants.LocalRuntimeTempDirectory) - if err := fileutils.MkdirUnlessExists(targetDir); err != nil { - return "", errs.Wrap(err, "Could not create temp runtime dir") - } - - archivePath := filepath.Join(targetDir, a.ArtifactID.String()+extension) - if err := s.downloadArtifact(a, archivePath); err != nil { - return "", errs.Wrap(err, "Could not download artifact %s", a.URL) - } - - err := s.verifyArtifact(archivePath, a) - if err != nil { - return "", errs.Wrap(err, "Artifact checksum validation failed") - } - - err = s.artifactCache.Store(a.ArtifactID, archivePath) - if err != nil { - multilog.Error("Could not store artifact in cache: %v", err) - } - - return archivePath, nil -} - -func (s *Setup) unpackArtifact(ua unarchiver.Unarchiver, tarballPath string, targetDir string, progress progress.Reporter) (int, error) { - f, i, err := ua.PrepareUnpacking(tarballPath, targetDir) - if err != nil { - return 0, errs.Wrap(err, "Prepare for unpacking failed") - } - defer f.Close() - - if err := progress.ReportSize(int(i)); err != nil { - return 0, errs.Wrap(err, "Could not report size") - } - - var numUnpackedFiles int - ua.SetNotifier(func(_ string, _ int64, isDir bool) { - if !isDir { - numUnpackedFiles++ - } - }) - proxy := proxyreader.NewProxyReader(progress, f) - return numUnpackedFiles, ua.Unarchive(proxy, i, targetDir) -} - -func (s *Setup) selectSetupImplementation(buildEngine types.BuildEngine) (Setuper, error) { - switch buildEngine { - case types.Alternative: - return alternative.NewSetup(s.store), nil - case types.Camel: - return camel.NewSetup(s.store), nil - default: - return nil, errs.New("Unknown build engine: %s", buildEngine) - } -} - -func selectArtifactResolver(bp *buildplan.BuildPlan) (ArtifactResolver, error) { - switch bp.Engine() { - case types.Alternative: - return alternative.NewResolver(bp.Artifacts().ToIDMap()), nil - case types.Camel: - return camel.NewResolver(), nil - default: - return nil, errs.New("Unknown build engine: %s", bp.Engine()) - } -} - -func (s *Setup) selectArtifactSetupImplementation(buildEngine types.BuildEngine, a strfmt.UUID) (ArtifactSetuper, error) { - switch buildEngine { - case types.Alternative: - return alternative.NewArtifactSetup(a, s.store), nil - case types.Camel: - return camel.NewArtifactSetup(a, s.store), nil - default: - return nil, errs.New("Unknown build engine: %s", buildEngine) - } -} - -func ExecDir(targetDir string) string { - return filepath.Join(targetDir, "exec") -} - -func reusableArtifacts(requestedArtifacts []*buildplan.Artifact, storedArtifacts store.StoredArtifactMap) store.StoredArtifactMap { - keep := make(store.StoredArtifactMap) - - for _, a := range requestedArtifacts { - if v, ok := storedArtifacts[a.ArtifactID]; ok { - keep[a.ArtifactID] = v - } - } - return keep -} - -func (s *Setup) fetchAndInstallArtifactsFromDir(installFunc artifactInstaller) ([]strfmt.UUID, error) { - artifactsDir := s.target.InstallFromDir() - if artifactsDir == nil { - return nil, errs.New("Cannot install from a directory that is nil") - } - - artifacts, err := fileutils.ListDir(*artifactsDir, false) - if err != nil { - return nil, errs.Wrap(err, "Cannot read from directory to install from") - } - logging.Debug("Found %d artifacts to install from '%s'", len(artifacts), *artifactsDir) - - installedArtifacts := make([]strfmt.UUID, len(artifacts)) - - errors, aggregatedErr := aggregateErrors() - mainthread.Run(func() { - defer close(errors) - - wp := workerpool.New(MaxConcurrency) - - for i, a := range artifacts { - // Each artifact is of the form artifactID.tar.gz, so extract the artifactID from the name. - filename := a.Path() - basename := filepath.Base(filename) - extIndex := strings.Index(basename, ".") - if extIndex == -1 { - extIndex = len(basename) - } - artifactID := strfmt.UUID(basename[0:extIndex]) - installedArtifacts[i] = artifactID - - // Submit the artifact for setup and install. - func(filename string, artifactID strfmt.UUID) { - wp.Submit(func() { - as := alternative.NewArtifactSetup(artifactID, s.store) // offline installer artifacts are in this format - err = installFunc(artifactID, filename, as) - if err != nil { - errors <- locale.WrapError(err, "artifact_setup_failed", "", artifactID.String(), "") - } - }) - }(filename, artifactID) // avoid referencing loop variables inside goroutine closures - } - - wp.StopWait() - }) - - return installedArtifacts, <-aggregatedErr -} - -func (s *Setup) handleEvent(ev events.Eventer) error { - err := s.eventHandler.Handle(ev) - if err != nil { - return &ProgressReportError{errs.Wrap(err, "Error handling event: %v", errs.JoinMessage(err))} - } - return nil -} - -func (s *Setup) deleteOutdatedArtifacts(setup Setuper, changedArtifacts *buildplan.ArtifactChangeset, alreadyInstalled store.StoredArtifactMap) error { - storedArtifacts, err := s.store.Artifacts() - if err != nil { - return locale.WrapError(err, "err_stored_artifacts") - } - - err = setup.DeleteOutdatedArtifacts(changedArtifacts, storedArtifacts, alreadyInstalled) - if err != nil { - // This multilog is technically redundant and may be dropped after we can collect data on this error for a while as rollbar is not surfacing the returned error - // https://github.com/ActiveState/cli/pull/2620#discussion_r1256103647 - multilog.Error("Could not delete outdated artifacts: %s", errs.JoinMessage(err)) - return errs.Wrap(err, "Could not delete outdated artifacts") - } - return nil -} diff --git a/pkg/platform/runtime/store/marker.go b/pkg/platform/runtime/store/marker.go deleted file mode 100644 index 82a63731f2..0000000000 --- a/pkg/platform/runtime/store/marker.go +++ /dev/null @@ -1,158 +0,0 @@ -package store - -import ( - "encoding/json" - "path/filepath" - "strings" - - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/logging" - "github.com/go-openapi/strfmt" -) - -type Marker struct { - CommitID string `json:"commitID"` - Namespace string `json:"namespace"` - Version string `json:"version"` -} - -func (s *Store) markerFile() string { - return filepath.Join(s.storagePath, constants.RuntimeInstallationCompleteMarker) -} - -func (s *Store) HasMarker() bool { - return fileutils.FileExists(s.markerFile()) -} - -// MarkerIsValid checks if stored runtime is complete and can be loaded -func (s *Store) MarkerIsValid(commitID strfmt.UUID) bool { - marker, err := s.parseMarker() - if err != nil { - logging.Debug("Unable to parse marker file %s: %v", marker, err) - return false - } - - if marker.CommitID != commitID.String() { - logging.Debug("Could not match commitID in %s, expected: %s, got: %s", marker, commitID.String(), marker.CommitID) - return false - } - - if marker.Version != constants.Version { - logging.Debug("Could not match State Tool version in %s, expected: %s, got: %s", marker, constants.Version, marker.Version) - return false - } - - return true -} - -// VersionMarkerIsValid checks if stored runtime was installed with the current state tool version -func (s *Store) VersionMarkerIsValid() bool { - marker, err := s.parseMarker() - if err != nil { - logging.Debug("Unable to parse marker file %s: %v", marker, err) - return false - } - - if marker.Version != constants.Version { - logging.Debug("Could not match State Tool version in %s, expected: %s, got: %s", marker, constants.Version, marker.Version) - return false - } - - return true -} - -func (s *Store) parseMarker() (*Marker, error) { - if !s.HasMarker() { - return nil, errs.New(`Marker file "%s" does not exist`, s.markerFile()) - } - - contents, err := fileutils.ReadFile(s.markerFile()) - if err != nil { - return nil, errs.Wrap(err, "Could not read marker file %s", s.markerFile()) - } - - if !json.Valid(contents) { - return s.updateMarker(contents) - } - - marker := &Marker{} - err = json.Unmarshal(contents, marker) - if err != nil { - return nil, errs.Wrap(err, "Could not unmasrshal marker file") - } - - return marker, nil -} - -// updateMarker updates old marker files to the new format and -// returns the stored marker data -func (s *Store) updateMarker(contents []byte) (*Marker, error) { - lines := strings.Split(string(contents), "\n") - if len(lines) == 0 { - // No marker data, nothing to transition - return nil, nil - } - - marker := &Marker{} - for i, line := range lines { - if i == 0 { - marker.CommitID = strings.TrimSpace(line) - } else if i == 1 { - marker.Version = strings.TrimSpace(line) - } - } - - data, err := json.Marshal(marker) - if err != nil { - return nil, errs.Wrap(err, "Could not marshal marker data") - } - - err = fileutils.WriteFile(s.markerFile(), data) - if err != nil { - return nil, errs.Wrap(err, "could not set completion marker") - } - - return marker, nil -} - -// MarkInstallationComplete writes the installation complete marker to the runtime directory -func (s *Store) MarkInstallationComplete(commitID strfmt.UUID, namespace string) error { - markerFile := s.markerFile() - markerDir := filepath.Dir(markerFile) - err := fileutils.MkdirUnlessExists(markerDir) - if err != nil { - return errs.Wrap(err, "could not create completion marker directory") - } - - data, err := json.Marshal(Marker{commitID.String(), namespace, constants.Version}) - if err != nil { - return errs.Wrap(err, "Could not marshal marker data") - } - - err = fileutils.WriteFile(markerFile, data) - if err != nil { - return errs.Wrap(err, "could not set completion marker") - } - - return nil -} - -func (s *Store) CommitID() (string, error) { - marker, err := s.parseMarker() - if err != nil { - return "", errs.Wrap(err, "Could not parse marker file") - } - - return marker.CommitID, nil -} - -func (s *Store) Namespace() (string, error) { - marker, err := s.parseMarker() - if err != nil { - return "", errs.Wrap(err, "Could not parse marker file") - } - - return marker.Namespace, nil -} diff --git a/pkg/platform/runtime/store/store.go b/pkg/platform/runtime/store/store.go deleted file mode 100644 index 9ad92363a0..0000000000 --- a/pkg/platform/runtime/store/store.go +++ /dev/null @@ -1,319 +0,0 @@ -package store - -import ( - "encoding/json" - "os" - "path/filepath" - "strings" - - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/pkg/buildplan" - "github.com/ActiveState/cli/pkg/buildscript" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" - "github.com/ActiveState/cli/pkg/platform/api/inventory/inventory_models" - "github.com/ActiveState/cli/pkg/platform/model/buildplanner" - "github.com/ActiveState/cli/pkg/platform/runtime/envdef" - "github.com/go-openapi/strfmt" -) - -// Store manages the storing and loading of persistable information about the runtime -type Store struct { - installPath string - storagePath string -} - -type StoredArtifact struct { - ArtifactID strfmt.UUID `json:"artifactID"` - Files []string `json:"files"` - Dirs []string `json:"dirs"` - EnvDef *envdef.EnvironmentDefinition `json:"envdef"` -} - -func NewStoredArtifact(artifactID strfmt.UUID, files []string, dirs []string, envDef *envdef.EnvironmentDefinition) StoredArtifact { - return StoredArtifact{ - ArtifactID: artifactID, - Files: files, - Dirs: dirs, - EnvDef: envDef, - } -} - -type StoredArtifactMap = map[strfmt.UUID]StoredArtifact - -func New(installPath string) *Store { - return &Store{ - installPath, - filepath.Join(installPath, constants.LocalRuntimeEnvironmentDirectory), - } -} - -func (s *Store) buildEngineFile() string { - return filepath.Join(s.storagePath, constants.RuntimeBuildEngineStore) -} - -func (s *Store) recipeFile() string { - return filepath.Join(s.storagePath, constants.RuntimeRecipeStore) -} - -func (s *Store) buildPlanFile() string { - return filepath.Join(s.storagePath, constants.RuntimeBuildPlanStore) -} - -func (s *Store) buildScriptFile() string { - return filepath.Join(s.storagePath, constants.BuildScriptStore) -} - -// BuildEngine returns the runtime build engine value stored in the runtime directory -func (s *Store) BuildEngine() (types.BuildEngine, error) { - storeFile := s.buildEngineFile() - - data, err := fileutils.ReadFile(storeFile) - if err != nil { - return types.UnknownEngine, errs.Wrap(err, "Could not read build engine cache store.") - } - - return buildplanner.ParseBuildEngine(string(data)), nil -} - -// StoreBuildEngine stores the build engine value in the runtime directory -func (s *Store) StoreBuildEngine(buildEngine types.BuildEngine) error { - storeFile := s.buildEngineFile() - storeDir := filepath.Dir(storeFile) - logging.Debug("Storing build engine %s at %s", buildEngine.String(), storeFile) - err := fileutils.MkdirUnlessExists(storeDir) - if err != nil { - return errs.Wrap(err, "Could not create completion marker directory.") - } - err = fileutils.WriteFile(storeFile, []byte(buildEngine.String())) - if err != nil { - return errs.Wrap(err, "Could not store build engine string.") - } - return nil -} - -// Recipe returns the recipe the stored runtime has been built with -func (s *Store) Recipe() (*inventory_models.Recipe, error) { - data, err := fileutils.ReadFile(s.recipeFile()) - if err != nil { - return nil, errs.Wrap(err, "Could not read recipe file.") - } - - var recipe inventory_models.Recipe - err = json.Unmarshal(data, &recipe) - if err != nil { - return nil, errs.Wrap(err, "Could not parse recipe file.") - } - return &recipe, err -} - -// StoreRecipe stores a along side the stored runtime -func (s *Store) StoreRecipe(recipe *inventory_models.Recipe) error { - data, err := json.Marshal(recipe) - if err != nil { - return errs.Wrap(err, "Could not marshal recipe.") - } - err = fileutils.WriteFile(s.recipeFile(), data) - if err != nil { - return errs.Wrap(err, "Could not write recipe file.") - } - return nil -} - -// Artifacts loads artifact information collected during the installation. -// It includes the environment definition configuration and files installed for this artifact. -func (s *Store) Artifacts() (StoredArtifactMap, error) { - stored := make(StoredArtifactMap) - jsonDir := filepath.Join(s.storagePath, constants.ArtifactMetaDir) - if !fileutils.DirExists(jsonDir) { - return stored, nil - } - - files, err := os.ReadDir(jsonDir) - if err != nil { - return stored, errs.Wrap(err, "Readdir %s failed", jsonDir) - } - - for _, file := range files { - if file.IsDir() || !strings.HasSuffix(file.Name(), ".json") { - continue - } - - var artifactStore StoredArtifact - jsonBlob, err := fileutils.ReadFile(filepath.Join(jsonDir, file.Name())) - if err != nil { - return stored, errs.Wrap(err, "Could not read artifact meta file") - } - if err := json.Unmarshal(jsonBlob, &artifactStore); err != nil { - return stored, errs.Wrap(err, "Could not unmarshal artifact meta file") - } - - stored[artifactStore.ArtifactID] = artifactStore - } - - return stored, nil -} - -// DeleteArtifactStore deletes the stored information for a specific artifact from the store -func (s *Store) DeleteArtifactStore(id strfmt.UUID) error { - jsonFile := filepath.Join(s.storagePath, constants.ArtifactMetaDir, id.String()+".json") - if !fileutils.FileExists(jsonFile) { - return nil - } - return os.Remove(jsonFile) -} - -func (s *Store) StoreArtifact(artf StoredArtifact) error { - // Save artifact cache information - jsonBlob, err := json.Marshal(artf) - if err != nil { - return errs.Wrap(err, "Failed to marshal artifact cache information") - } - jsonFile := filepath.Join(s.storagePath, constants.ArtifactMetaDir, artf.ArtifactID.String()+".json") - if err := fileutils.WriteFile(jsonFile, jsonBlob); err != nil { - return errs.Wrap(err, "Failed to write artifact cache information") - } - return nil -} - -func (s *Store) EnvDef() (*envdef.EnvironmentDefinition, error) { - mergedRuntimeDefinitionFile := filepath.Join(s.storagePath, constants.RuntimeDefinitionFilename) - envDef, err := envdef.NewEnvironmentDefinition(mergedRuntimeDefinitionFile) - if err != nil { - return nil, locale.WrapError( - err, "err_no_environment_definition", - "Your installation seems corrupted.\nPlease try to re-run this command, as it may fix the problem. If the problem persists, please report it in our forum: {{.V0}}", - constants.ForumsURL, - ) - } - return envDef, nil -} - -func (s *Store) Environ(inherit bool) (map[string]string, error) { - envDef, err := s.EnvDef() - if err != nil { - return nil, errs.Wrap(err, "Could not grab EnvDef") - } - return envDef.GetEnv(inherit), nil -} - -func (s *Store) UpdateEnviron(orderedArtifacts []strfmt.UUID) (*envdef.EnvironmentDefinition, error) { - artifacts, err := s.Artifacts() - if err != nil { - return nil, errs.Wrap(err, "Could not retrieve stored artifacts") - } - - rtGlobal, err := s.updateEnviron(orderedArtifacts, artifacts) - if err != nil { - return nil, err - } - - return rtGlobal, rtGlobal.WriteFile(filepath.Join(s.storagePath, constants.RuntimeDefinitionFilename)) -} - -func (s *Store) updateEnviron(orderedArtifacts []strfmt.UUID, artifacts StoredArtifactMap) (*envdef.EnvironmentDefinition, error) { - if len(orderedArtifacts) == 0 { - return nil, errs.New("Environment cannot be updated if no artifacts were installed") - } - - var rtGlobal *envdef.EnvironmentDefinition - // use artifact order as returned by the build status response form the HC for merging artifacts - for _, artID := range orderedArtifacts { - a, ok := artifacts[artID] - if !ok { - continue - } - - if rtGlobal == nil { - rtGlobal = a.EnvDef - continue - } - var err error - rtGlobal, err = rtGlobal.Merge(a.EnvDef) - if err != nil { - return nil, errs.Wrap(err, "Could not merge envdef") - } - } - - if rtGlobal == nil { - // Returning nil will end up causing a nil-pointer-exception panic in setup.Update(). - // There is additional logging of the buildplan there that may help diagnose why this is happening. - logging.Error("There were artifacts returned, but none of them ended up being stored/installed.") - logging.Error("Artifacts returned: %v", orderedArtifacts) - logging.Error("Artifacts stored: %v", artifacts) - } - - return rtGlobal, nil -} - -// InstallPath returns the installation path of the runtime -func (s *Store) InstallPath() string { - return s.installPath -} - -var ErrNoBuildPlanFile = errs.New("no build plan file") - -func (s *Store) BuildPlanRaw() ([]byte, error) { - if !fileutils.FileExists(s.buildPlanFile()) { - return nil, ErrNoBuildPlanFile - } - data, err := fileutils.ReadFile(s.buildPlanFile()) - if err != nil { - return nil, errs.Wrap(err, "Could not read build plan file.") - } - - return data, nil -} - -type ErrVersionMarker struct { - *locale.LocalizedError -} - -func (s *Store) BuildPlan() (*buildplan.BuildPlan, error) { - if !s.VersionMarkerIsValid() { - return nil, &ErrVersionMarker{locale.NewInputError("err_runtime_needs_refresh")} - } - - data, err := s.BuildPlanRaw() - if err != nil { - return nil, errs.Wrap(err, "Could not get build plan file.") - } - - return buildplan.Unmarshal(data) -} - -func (s *Store) StoreBuildPlan(bp *buildplan.BuildPlan) error { - data, err := bp.Marshal() - if err != nil { - return errs.Wrap(err, "Could not marshal buildPlan.") - } - err = fileutils.WriteFile(s.buildPlanFile(), data) - if err != nil { - return errs.Wrap(err, "Could not write recipe file.") - } - return nil -} - -var ErrNoBuildScriptFile = errs.New("no buildscript file") - -func (s *Store) BuildScript() (*buildscript.BuildScript, error) { - if !fileutils.FileExists(s.buildScriptFile()) { - return nil, ErrNoBuildScriptFile - } - bytes, err := fileutils.ReadFile(s.buildScriptFile()) - if err != nil { - return nil, errs.Wrap(err, "Could not read buildscript file") - } - return buildscript.Unmarshal(bytes) -} - -func (s *Store) StoreBuildScript(script *buildscript.BuildScript) error { - scriptBytes, err := script.Marshal() - if err != nil { - return errs.Wrap(err, "Could not marshal buildscript") - } - return fileutils.WriteFile(s.buildScriptFile(), scriptBytes) -} diff --git a/pkg/platform/runtime/store/store_test.go b/pkg/platform/runtime/store/store_test.go deleted file mode 100644 index 7cd608320f..0000000000 --- a/pkg/platform/runtime/store/store_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package store - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - "strings" - "testing" - - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/pkg/platform/runtime/envdef" - "github.com/go-openapi/strfmt" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestUpdateEnviron(t *testing.T) { - artifactIDs := []strfmt.UUID{"1", "2", "3", "4"} - artifacts := StoredArtifactMap{} - for i, artID := range artifactIDs[0:3] { - artifacts[artID] = StoredArtifact{EnvDef: &envdef.EnvironmentDefinition{Env: []envdef.EnvironmentVariable{ - { - Name: "vars", - Join: envdef.Append, - Separator: ":", - Values: []string{fmt.Sprintf("%d", i+1)}, - }, - }}} - } - s := New("/installPath") - rt, err := s.updateEnviron(artifactIDs, artifacts) - require.NoError(t, err) - env := rt.GetEnv(false) - assert.Equal(t, map[string]string{ - "vars": "1:2:3", - }, env) -} - -func TestUpdateMarker(t *testing.T) { - dir := filepath.Join(os.TempDir(), t.Name()) - err := fileutils.Mkdir(dir) - require.NoError(t, err) - - s := New(dir) - uuid := "00000000-0000-0000-0000-000000000000" - version := constants.Version - err = fileutils.WriteFile(s.markerFile(), []byte(strings.Join([]string{uuid, version}, "\n"))) - require.NoError(t, err) - - marker, err := s.parseMarker() - require.NoError(t, err) - - if marker.CommitID != uuid { - t.Errorf("Expected UUID to be %s, got %s", uuid, marker.CommitID) - } - if marker.Version != version { - t.Errorf("Expected version to be %s, got %s", version, marker.Version) - } - - data, err := fileutils.ReadFile(s.markerFile()) - require.NoError(t, err) - if !json.Valid(data) { - t.Errorf("Expected marker file to be valid JSON") - } -} diff --git a/pkg/platform/runtime/target/target.go b/pkg/platform/runtime/target/target.go deleted file mode 100644 index 56d5ea8e0e..0000000000 --- a/pkg/platform/runtime/target/target.go +++ /dev/null @@ -1,245 +0,0 @@ -package target - -import ( - "fmt" - "path/filepath" - "strings" - - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/hash" - "github.com/ActiveState/cli/internal/installation/storage" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/pkg/localcommit" - "github.com/ActiveState/cli/pkg/project" - "github.com/go-openapi/strfmt" -) - -type Trigger string - -func (t Trigger) String() string { - return string(t) -} - -const ( - TriggerActivate Trigger = "activate" - TriggerScript Trigger = "script" - TriggerDeploy Trigger = "deploy" - TriggerExec Trigger = "exec-cmd" - TriggerExecutor Trigger = "exec" - TriggerExport Trigger = "export" - TriggerResetExec Trigger = "reset-exec" - TriggerSwitch Trigger = "switch" - TriggerImport Trigger = "import" - TriggerInit Trigger = "init" - TriggerPackage Trigger = "package" - TriggerLanguage Trigger = "language" - TriggerPlatform Trigger = "platform" - TriggerManifest Trigger = "manifest" - TriggerPull Trigger = "pull" - TriggerRefresh Trigger = "refresh" - TriggerReset Trigger = "reset" - TriggerRevert Trigger = "revert" - TriggerOffline Trigger = "offline" - TriggerShell Trigger = "shell" - TriggerCheckout Trigger = "checkout" - TriggerCommit Trigger = "commit" - TriggerUse Trigger = "use" - TriggerOfflineInstaller Trigger = "offline-installer" - TriggerOfflineUninstaller Trigger = "offline-uninstaller" - TriggerBuilds Trigger = "builds" - triggerUnknown Trigger = "unknown" -) - -func NewExecTrigger(cmd string) Trigger { - return Trigger(fmt.Sprintf("%s: %s", TriggerExec, cmd)) -} - -func (t Trigger) IndicatesUsage() bool { - // All triggers should indicate runtime use except for refreshing executors - return !strings.EqualFold(string(t), string(TriggerResetExec)) -} - -type ProjectTarget struct { - *project.Project - cacheDir string - customCommit *strfmt.UUID - trigger Trigger -} - -func NewProjectTarget(pj *project.Project, customCommit *strfmt.UUID, trigger Trigger) *ProjectTarget { - runtimeCacheDir := storage.CachePath() - if pj.Cache() != "" { - runtimeCacheDir = pj.Cache() - } - return &ProjectTarget{pj, runtimeCacheDir, customCommit, trigger} -} - -func NewProjectTargetCache(pj *project.Project, cacheDir string, customCommit *strfmt.UUID, trigger Trigger) *ProjectTarget { - return &ProjectTarget{pj, cacheDir, customCommit, trigger} -} - -func (p *ProjectTarget) Dir() string { - if p.Project.Cache() != "" { - return p.Project.Cache() - } - return ProjectDirToTargetDir(filepath.Dir(p.Project.Source().Path()), p.cacheDir) -} - -func (p *ProjectTarget) CommitUUID() strfmt.UUID { - if p.customCommit != nil { - return *p.customCommit - } - commitID, err := localcommit.Get(p.Project.Dir()) - if err != nil { - multilog.Error("Unable to get local commit: %v", errs.JoinMessage(err)) - return "" - } - return commitID -} - -func (p *ProjectTarget) Trigger() Trigger { - if p.trigger == "" { - return triggerUnknown - } - return p.trigger -} - -func (p *ProjectTarget) ReadOnly() bool { - return false -} - -func (p *ProjectTarget) InstallFromDir() *string { - return nil -} - -func (p *ProjectTarget) ProjectDir() string { - return p.Project.Dir() -} - -func ProjectDirToTargetDir(projectDir, cacheDir string) string { - resolvedDir, err := fileutils.ResolveUniquePath(projectDir) - if err != nil { - multilog.Error("Could not resolve unique path for projectDir: %s, error: %s", projectDir, err.Error()) - resolvedDir = projectDir - } - logging.Debug("In newStore: resolved project dir is: %s", resolvedDir) - - return filepath.Join(cacheDir, hash.ShortHash(resolvedDir)) -} - -type CustomTarget struct { - owner string - name string - commitUUID strfmt.UUID - dir string - trigger Trigger -} - -func NewCustomTarget(owner string, name string, commitUUID strfmt.UUID, dir string, trigger Trigger) *CustomTarget { - cleanDir, err := fileutils.ResolveUniquePath(dir) - if err != nil { - multilog.Error("Could not resolve unique path for dir: %s, error: %s", dir, err.Error()) - } else { - dir = cleanDir - } - return &CustomTarget{owner, name, commitUUID, dir, trigger} -} - -func (c *CustomTarget) Owner() string { - return c.owner -} - -func (c *CustomTarget) Name() string { - return c.name -} - -func (c *CustomTarget) CommitUUID() strfmt.UUID { - return c.commitUUID -} - -func (c *CustomTarget) Dir() string { - return c.dir -} - -func (c *CustomTarget) Trigger() Trigger { - if c.trigger == "" { - return triggerUnknown - } - return c.trigger -} - -func (c *CustomTarget) ReadOnly() bool { - return c.commitUUID == "" -} - -func (c *CustomTarget) InstallFromDir() *string { - return nil -} - -func (c *CustomTarget) ProjectDir() string { - return "" -} - -type OfflineTarget struct { - ns *project.Namespaced - dir string - artifactsDir string - trigger Trigger -} - -func NewOfflineTarget(namespace *project.Namespaced, dir string, artifactsDir string) *OfflineTarget { - cleanDir, err := fileutils.ResolveUniquePath(dir) - if err != nil { - multilog.Error("Could not resolve unique path for dir: %s, error: %s", dir, err.Error()) - } else { - dir = cleanDir - } - return &OfflineTarget{namespace, dir, artifactsDir, TriggerOffline} -} - -func (i *OfflineTarget) Owner() string { - if i.ns == nil { - return "" - } - return i.ns.Owner -} - -func (i *OfflineTarget) Name() string { - if i.ns == nil { - return "" - } - return i.ns.Project -} - -func (i *OfflineTarget) CommitUUID() strfmt.UUID { - if i.ns == nil || i.ns.CommitID == nil { - return "" - } - return *i.ns.CommitID -} - -func (i *OfflineTarget) Dir() string { - return i.dir -} - -func (i *OfflineTarget) SetTrigger(t Trigger) { - i.trigger = t -} - -func (i *OfflineTarget) Trigger() Trigger { - return i.trigger -} - -func (i *OfflineTarget) ReadOnly() bool { - return false -} - -func (i *OfflineTarget) InstallFromDir() *string { - return &i.artifactsDir -} - -func (i *OfflineTarget) ProjectDir() string { - return "" -} diff --git a/pkg/platform/runtime/target/target_test.go b/pkg/platform/runtime/target/target_test.go deleted file mode 100644 index 89954c293e..0000000000 --- a/pkg/platform/runtime/target/target_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package target - -import "testing" - -func TestTrigger_IndicatesUsage(t *testing.T) { - tests := []struct { - name string - t Trigger - want bool - }{ - { - "Activate counts as usage", - TriggerActivate, - true, - }, - { - "Reset exec does not count as usage", - TriggerResetExec, - false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := tt.t.IndicatesUsage(); got != tt.want { - t.Errorf("IndicatesUsage() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/platform/runtime/testhelper/data/builds/alternative-completed.json b/pkg/platform/runtime/testhelper/data/builds/alternative-completed.json deleted file mode 100644 index 95e2553c92..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/alternative-completed.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "artifacts": [ - { - "artifact_id": "71e4a1fe-eba7-5ee1-a95f-94fd70aa2d87", - "build_state": "succeeded", - "build_timestamp": "2021-02-03T22:21:39.496Z", - "dependency_ids": null, - "ingredient_version_id": "a845e482-d3ec-5379-aba3-96e74794570f", - "log_uri": "s3://as-builds/production/language/perl/5.32.0/7/71e4a1fe-eba7-5ee1-a95f-94fd70aa2d87/logs.jsonl", - "platform_id": "0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a", - "uri": "s3://as-builds/production/language/perl/5.32.0/7/71e4a1fe-eba7-5ee1-a95f-94fd70aa2d87/artifact.tar.gz" - }, - { - "artifact_id": "ad807d9a-8214-5395-92c4-77b6301248f2", - "build_state": "succeeded", - "build_timestamp": "2021-02-06T00:17:40.179Z", - "dependency_ids": null, - "log_uri": "s3://as-builds/noop/logs.jsonl", - "platform_id": "0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a", - "uri": "s3://as-builds/noop/artifact.tar.gz" - } - ], - "build_engine": "alternative", - "build_request_id": "af46a10c-e788-459e-9e17-4e4add8973c0", - "errors": [], - "is_retryable": false, - "message": "Recipe build completed successfully", - "recipe_id": "ad807d9a-8214-5395-92c4-77b6301248f2", - "timestamp": "2021-02-18T18:03:18.756Z", - "type": "build_completed" -} diff --git a/pkg/platform/runtime/testhelper/data/builds/camel-building.json b/pkg/platform/runtime/testhelper/data/builds/camel-building.json deleted file mode 100644 index 7ca0f04394..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/camel-building.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "artifacts": [], - "build_engine": "camel", - "build_request_id": "ccf8173c-9810-4ae3-afd6-02f7597258ae", - "errors": [], - "is_retryable": false, - "message": "Camel build sent to scheduler with camel commit 3d46a065", - "recipe_id": "50dd4b2f-a42e-537e-911c-3122b89f8c36", - "timestamp": "2021-02-18T17:58:38.465Z", - "type": "build_started" -} diff --git a/pkg/platform/runtime/testhelper/data/builds/camel-done.json b/pkg/platform/runtime/testhelper/data/builds/camel-done.json deleted file mode 100644 index ed777e11fc..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/camel-done.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":null,"build_engine":"camel","build_request_id":"ccf8173c-9810-4ae3-afd6-02f7597258ae","errors":null,"is_retryable":false,"message":"Sent build to scheduler","recipe_id":"50dd4b2f-a42e-537e-911c-3122b89f8c36","timestamp":"2021-02-18T17:58:38.468Z","type":"build_started"} diff --git a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-base.json b/pkg/platform/runtime/testhelper/data/builds/perl-alternative-base.json deleted file mode 100644 index 72b46c57a0..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-base.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":[{"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_state":"succeeded","build_timestamp":"2021-02-04T18:04:26.190Z","dependency_ids":null,"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/5.32.1/3/b30ab2e5-4074-572c-8146-da692b1c9e45/artifact.tar.gz"},{"artifact_id":"aa21f7c8-85a7-5cc2-8ee8-f8bd3b342406","build_state":"succeeded","build_timestamp":"2021-02-06T00:17:40.179Z","dependency_ids":null,"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/noop/artifact.tar.gz"}],"build_engine":"alternative","build_request_id":"fd118bfd-7534-49fc-be42-4e63ea2e69d1","errors":[],"is_retryable":false,"message":"Recipe build completed successfully","recipe_id":"aa21f7c8-85a7-5cc2-8ee8-f8bd3b342406","timestamp":"2021-02-20T08:28:49.813Z","type":"build_completed"} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-failure.json b/pkg/platform/runtime/testhelper/data/builds/perl-alternative-failure.json deleted file mode 100644 index 740aa36a5f..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-failure.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":[{"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_state":"succeeded","build_timestamp":"2021-02-04T18:04:26.190Z","dependency_ids":null,"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/5.32.1/3/b30ab2e5-4074-572c-8146-da692b1c9e45/artifact.tar.gz"},{"artifact_id":"48951744-f839-5031-8cf4-6e82a4be2089","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:38.937Z","dependency_ids":null,"ingredient_version_id":"e8527602-630b-57ab-b21f-a185719a6c91","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Data-UUID/1.226/6/48951744-f839-5031-8cf4-6e82a4be2089/artifact.tar.gz"},{"artifact_id":"0029ae25-8497-5130-8268-1f0fe26ccc77","build_state":"succeeded","build_timestamp":"2021-02-05T18:02:09.243Z","dependency_ids":null,"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Importer/0.025/2/0029ae25-8497-5130-8268-1f0fe26ccc77/artifact.tar.gz"},{"artifact_id":"6591f01d-939d-5080-bb1a-7816ff4d020b","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:35.524Z","dependency_ids":null,"ingredient_version_id":"6c89ed56-ef22-541a-bf87-9ff4e10ee371","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Long-Jump/0.000001/3/6591f01d-939d-5080-bb1a-7816ff4d020b/artifact.tar.gz"},{"artifact_id":"7c541a6a-4dfd-5135-8b98-2b44b5d1a816","build_state":"succeeded","build_timestamp":"2021-02-05T18:04:43.305Z","dependency_ids":null,"ingredient_version_id":"0f028feb-10aa-531d-9660-b56c19fb7b43","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Module-Pluggable/5.2/7/7c541a6a-4dfd-5135-8b98-2b44b5d1a816/artifact.tar.gz"},{"artifact_id":"7f8a7197-b277-5621-a6f3-7f2ef32d871b","build_state":"succeeded","build_timestamp":"2021-02-05T18:02:10.497Z","dependency_ids":null,"ingredient_version_id":"1ff5b410-a933-53c7-b3a1-f11524b53213","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Scope-Guard/0.21/5/7f8a7197-b277-5621-a6f3-7f2ef32d871b/artifact.tar.gz"},{"artifact_id":"29983a5b-49c4-5cf4-a2c5-2490647d6910","build_state":"succeeded","build_timestamp":"2021-02-19T21:16:18.962Z","dependency_ids":null,"ingredient_version_id":"9e33e514-0b22-504b-8409-6d0bdbf86108","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Sub-Info/0.002/4/29983a5b-49c4-5cf4-a2c5-2490647d6910/artifact.tar.gz"},{"artifact_id":"4d95557d-2200-5a56-a809-4ea3d3502b20","build_state":"succeeded","build_timestamp":"2021-02-19T21:16:19.477Z","dependency_ids":null,"ingredient_version_id":"7e483f34-00ad-523a-91be-e9ddf74366a5","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Term-Table/0.015/3/4d95557d-2200-5a56-a809-4ea3d3502b20/artifact.tar.gz"},{"artifact_id":"288aa0db-c0e4-55e7-8f67-fc2da409be70","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:45.569Z","dependency_ids":null,"ingredient_version_id":"9c514f0f-5abb-546a-840a-1c97f2010c78","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Harness/1.000042/2/288aa0db-c0e4-55e7-8f67-fc2da409be70/artifact.tar.gz"},{"artifact_id":"282e3768-e12a-51ed-831f-7cbc212ba8bd","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:34.879Z","dependency_ids":null,"ingredient_version_id":"d85188d8-231d-589f-9bdd-fc5667cc2d2f","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Plugin-MemUsage/0.002003/3/282e3768-e12a-51ed-831f-7cbc212ba8bd/artifact.tar.gz"},{"artifact_id":"5ad88c8a-bc8f-50a0-9f61-74856cd28017","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:32.081Z","dependency_ids":null,"ingredient_version_id":"b8f76881-09d4-53fd-8cc6-e595b6d69132","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Plugin-NoWarnings/0.06/3/5ad88c8a-bc8f-50a0-9f61-74856cd28017/artifact.tar.gz"},{"artifact_id":"c3e652a7-676e-594f-b87f-93d19122f3f4","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:32.425Z","dependency_ids":null,"ingredient_version_id":"4bd9f2db-1c09-5a14-82a3-7cb6d966d18c","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Plugin-UUID/0.002001/3/c3e652a7-676e-594f-b87f-93d19122f3f4/artifact.tar.gz"},{"artifact_id":"30dc7965-0a69-5686-831a-e563fa73a98c","build_state":"succeeded","build_timestamp":"2021-02-19T21:16:40.002Z","dependency_ids":null,"ingredient_version_id":"fa7a0c73-1e93-5e08-8f6b-a009e82d7179","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Suite/0.000127/2/30dc7965-0a69-5686-831a-e563fa73a98c/artifact.tar.gz"},{"artifact_id":"c1e8c6c4-ea11-55a4-b415-97da2d32121e","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:32.005Z","dependency_ids":null,"ingredient_version_id":"ee3bc68e-abb3-58ff-aa9c-60b7412df7e2","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/goto-file/0.005/3/c1e8c6c4-ea11-55a4-b415-97da2d32121e/artifact.tar.gz"},{"artifact_id":"c894fa23-0416-556d-9ca5-fdf9375595bc","build_state":"succeeded","build_timestamp":"2021-02-20T07:48:54.696Z","dependency_ids":null,"ingredient_version_id":"21141224-b8b8-565c-8fdf-4ded24fcbd8d","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/noop/artifact.tar.gz"},{"artifact_id":"3ac7b175-6fc9-569c-bb15-785fe14298a2","build_state":"failed","build_timestamp":"2021-02-20T07:50:24.594Z","dependency_ids":null,"error":"Builder returned with exit code 255","ingredient_version_id":"e0f207c2-9922-51e3-95cf-e586da39436e","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},{"artifact_id":"d806994e-1154-5b81-9104-b8d4d4dd72a4","build_state":"failed","build_timestamp":"2021-02-20T07:50:44.314Z","dependency_ids":null,"error":"Builder returned with exit code 255","ingredient_version_id":"bac128cd-1439-5857-b5b5-5633763f78d5","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},{"artifact_id":"08f7470e-bd8b-5ef1-a94d-a04960d355eb","build_state":"failed","build_timestamp":"2021-02-20T07:50:38.365Z","dependency_ids":null,"error":"Builder returned with exit code 255","ingredient_version_id":"e41f38b7-11e6-52e8-9f12-eba3533f3055","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},{"artifact_id":"ea103bb8-1e74-58ff-8f35-3bc14994d268","build_state":"skipped","build_timestamp":"2021-02-20T07:50:27.548Z","dependency_ids":null,"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"}],"build_engine":"alternative","build_request_id":"73105a9f-8479-45e8-96bf-b82be42237b4","errors":["language/perl Win32-Console-ANSI 1.11: Builder returned with exit code 255","language/perl Win32-Pipe 0.025: Builder returned with exit code 255","language/perl Win32-Process 0.16: Builder returned with exit code 255"],"is_retryable":false,"message":"Recipe build failed: 3 build steps failed","recipe_id":"ea103bb8-1e74-58ff-8f35-3bc14994d268","timestamp":"2021-02-20T08:28:59.242Z","type":"build_failed"} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-bundle.json b/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-bundle.json deleted file mode 100644 index 5b2aae0349..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-bundle.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":[{"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_state":"succeeded","build_timestamp":"2021-02-04T18:04:26.190Z","dependency_ids":null,"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/5.32.1/3/b30ab2e5-4074-572c-8146-da692b1c9e45/artifact.tar.gz"},{"artifact_id":"48951744-f839-5031-8cf4-6e82a4be2089","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:38.937Z","dependency_ids":null,"ingredient_version_id":"e8527602-630b-57ab-b21f-a185719a6c91","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Data-UUID/1.226/6/48951744-f839-5031-8cf4-6e82a4be2089/artifact.tar.gz"},{"artifact_id":"0029ae25-8497-5130-8268-1f0fe26ccc77","build_state":"succeeded","build_timestamp":"2021-02-05T18:02:09.243Z","dependency_ids":null,"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Importer/0.025/2/0029ae25-8497-5130-8268-1f0fe26ccc77/artifact.tar.gz"},{"artifact_id":"6591f01d-939d-5080-bb1a-7816ff4d020b","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:35.524Z","dependency_ids":null,"ingredient_version_id":"6c89ed56-ef22-541a-bf87-9ff4e10ee371","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Long-Jump/0.000001/3/6591f01d-939d-5080-bb1a-7816ff4d020b/artifact.tar.gz"},{"artifact_id":"7c541a6a-4dfd-5135-8b98-2b44b5d1a816","build_state":"succeeded","build_timestamp":"2021-02-05T18:04:43.305Z","dependency_ids":null,"ingredient_version_id":"0f028feb-10aa-531d-9660-b56c19fb7b43","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Module-Pluggable/5.2/7/7c541a6a-4dfd-5135-8b98-2b44b5d1a816/artifact.tar.gz"},{"artifact_id":"7f8a7197-b277-5621-a6f3-7f2ef32d871b","build_state":"succeeded","build_timestamp":"2021-02-05T18:02:10.497Z","dependency_ids":null,"ingredient_version_id":"1ff5b410-a933-53c7-b3a1-f11524b53213","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Scope-Guard/0.21/5/7f8a7197-b277-5621-a6f3-7f2ef32d871b/artifact.tar.gz"},{"artifact_id":"29983a5b-49c4-5cf4-a2c5-2490647d6910","build_state":"succeeded","build_timestamp":"2021-02-19T21:16:18.962Z","dependency_ids":null,"ingredient_version_id":"9e33e514-0b22-504b-8409-6d0bdbf86108","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Sub-Info/0.002/4/29983a5b-49c4-5cf4-a2c5-2490647d6910/artifact.tar.gz"},{"artifact_id":"4d95557d-2200-5a56-a809-4ea3d3502b20","build_state":"succeeded","build_timestamp":"2021-02-19T21:16:19.477Z","dependency_ids":null,"ingredient_version_id":"7e483f34-00ad-523a-91be-e9ddf74366a5","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Term-Table/0.015/3/4d95557d-2200-5a56-a809-4ea3d3502b20/artifact.tar.gz"},{"artifact_id":"288aa0db-c0e4-55e7-8f67-fc2da409be70","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:45.569Z","dependency_ids":null,"ingredient_version_id":"9c514f0f-5abb-546a-840a-1c97f2010c78","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Harness/1.000042/2/288aa0db-c0e4-55e7-8f67-fc2da409be70/artifact.tar.gz"},{"artifact_id":"282e3768-e12a-51ed-831f-7cbc212ba8bd","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:34.879Z","dependency_ids":null,"ingredient_version_id":"d85188d8-231d-589f-9bdd-fc5667cc2d2f","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Plugin-MemUsage/0.002003/3/282e3768-e12a-51ed-831f-7cbc212ba8bd/artifact.tar.gz"},{"artifact_id":"5ad88c8a-bc8f-50a0-9f61-74856cd28017","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:32.081Z","dependency_ids":null,"ingredient_version_id":"b8f76881-09d4-53fd-8cc6-e595b6d69132","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Plugin-NoWarnings/0.06/3/5ad88c8a-bc8f-50a0-9f61-74856cd28017/artifact.tar.gz"},{"artifact_id":"c3e652a7-676e-594f-b87f-93d19122f3f4","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:32.425Z","dependency_ids":null,"ingredient_version_id":"4bd9f2db-1c09-5a14-82a3-7cb6d966d18c","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Plugin-UUID/0.002001/3/c3e652a7-676e-594f-b87f-93d19122f3f4/artifact.tar.gz"},{"artifact_id":"30dc7965-0a69-5686-831a-e563fa73a98c","build_state":"succeeded","build_timestamp":"2021-02-19T21:16:40.002Z","dependency_ids":null,"ingredient_version_id":"fa7a0c73-1e93-5e08-8f6b-a009e82d7179","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Test2-Suite/0.000127/2/30dc7965-0a69-5686-831a-e563fa73a98c/artifact.tar.gz"},{"artifact_id":"c1e8c6c4-ea11-55a4-b415-97da2d32121e","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:32.005Z","dependency_ids":null,"ingredient_version_id":"ee3bc68e-abb3-58ff-aa9c-60b7412df7e2","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/goto-file/0.005/3/c1e8c6c4-ea11-55a4-b415-97da2d32121e/artifact.tar.gz"},{"artifact_id":"c894fa23-0416-556d-9ca5-fdf9375595bc","build_state":"succeeded","build_timestamp":"2021-02-20T07:48:54.696Z","dependency_ids":null,"ingredient_version_id":"21141224-b8b8-565c-8fdf-4ded24fcbd8d","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/noop/artifact.tar.gz"},{"artifact_id":"410f6ec8-2e41-5085-9ffe-b6860b7f60d3","build_state":"succeeded","build_timestamp":"2021-02-20T07:48:56.148Z","dependency_ids":null,"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/noop/artifact.tar.gz"}],"build_engine":"alternative","build_request_id":"84061016-0ebb-46f2-9155-3cf82c5f70b3","errors":[],"is_retryable":false,"message":"Recipe build completed successfully","recipe_id":"410f6ec8-2e41-5085-9ffe-b6860b7f60d3","timestamp":"2021-02-20T08:28:57.012Z","type":"build_completed"} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-package.json b/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-package.json deleted file mode 100644 index 831c123a98..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-package.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":[{"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_state":"succeeded","build_timestamp":"2021-02-04T18:04:26.190Z","dependency_ids":null,"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/5.32.1/3/b30ab2e5-4074-572c-8146-da692b1c9e45/artifact.tar.gz"},{"artifact_id":"41dbce7b-0d0f-597b-bb6f-411a4fb0b829","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:36.747Z","dependency_ids":null,"ingredient_version_id":"9930b34d-2ad3-507f-912f-729e5bb4e3e1","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Canary-Stability/2013/5/41dbce7b-0d0f-597b-bb6f-411a4fb0b829/artifact.tar.gz"},{"artifact_id":"d51871fd-d270-5423-82b9-78b567c53636","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:53.437Z","dependency_ids":null,"ingredient_version_id":"bc4acfbd-4c39-59fd-bc9c-62662b851b3d","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/JSON-XS/4.03/2/d51871fd-d270-5423-82b9-78b567c53636/artifact.tar.gz"},{"artifact_id":"bfe02625-c7d6-5604-ae04-2e5b4c9592a2","build_state":"succeeded","build_timestamp":"2021-02-20T07:46:50.742Z","dependency_ids":null,"ingredient_version_id":"a64758c6-32a6-5c57-8c43-64a5e53d7309","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/JSON/2.97001/5/bfe02625-c7d6-5604-ae04-2e5b4c9592a2/artifact.tar.gz"},{"artifact_id":"c62e933c-7f68-5e94-8fcd-5f978e3825b4","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:42.084Z","dependency_ids":null,"ingredient_version_id":"f547017b-1726-5839-bb7f-214e420b2f66","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/Types-Serialiser/1.0/3/c62e933c-7f68-5e94-8fcd-5f978e3825b4/artifact.tar.gz"},{"artifact_id":"279d6621-2756-5f82-b1d4-1bd7a41dfc57","build_state":"succeeded","build_timestamp":"2021-02-05T17:59:40.495Z","dependency_ids":null,"ingredient_version_id":"09e2438e-36a3-534b-9626-f5a8825d84ad","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/common-sense/3.75/2/279d6621-2756-5f82-b1d4-1bd7a41dfc57/artifact.tar.gz"},{"artifact_id":"b50600fa-f2ef-5079-afbb-550bf3b8295d","build_state":"succeeded","build_timestamp":"2021-02-20T07:47:01.993Z","dependency_ids":null,"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/noop/artifact.tar.gz"}],"build_engine":"alternative","build_request_id":"e1e5b412-2cf3-45fb-8cd6-ee29c9b5e360","errors":[],"is_retryable":false,"message":"Recipe build completed successfully","recipe_id":"b50600fa-f2ef-5079-afbb-550bf3b8295d","timestamp":"2021-02-20T08:28:51.467Z","type":"build_completed"} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-removed.json b/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-removed.json deleted file mode 100644 index f39e628fbe..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-removed.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":[{"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_state":"succeeded","build_timestamp":"2021-02-04T18:04:26.190Z","dependency_ids":null,"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/5.32.1/3/b30ab2e5-4074-572c-8146-da692b1c9e45/artifact.tar.gz"},{"artifact_id":"aa21f7c8-85a7-5cc2-8ee8-f8bd3b342406","build_state":"succeeded","build_timestamp":"2021-02-06T00:17:40.179Z","dependency_ids":null,"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/noop/artifact.tar.gz"}],"build_engine":"alternative","build_request_id":"8e47da6d-1fce-46c8-bc0e-4fc3b5e0e3cc","errors":[],"is_retryable":false,"message":"Recipe build completed successfully","recipe_id":"aa21f7c8-85a7-5cc2-8ee8-f8bd3b342406","timestamp":"2021-02-20T08:28:55.131Z","type":"build_completed"} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-update.json b/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-update.json deleted file mode 100644 index 0603ef8d13..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/perl-alternative-one-update.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":[{"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_state":"succeeded","build_timestamp":"2021-02-04T18:04:26.190Z","dependency_ids":null,"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/5.32.1/3/b30ab2e5-4074-572c-8146-da692b1c9e45/artifact.tar.gz"},{"artifact_id":"f56acc9c-dd02-5cf8-97f9-a5cd015f4c7b","build_state":"succeeded","build_timestamp":"2021-02-05T18:01:58.243Z","dependency_ids":null,"ingredient_version_id":"9c52ef68-d833-59c7-a537-4d20efd2d728","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/perl/JSON/4.02/4/f56acc9c-dd02-5cf8-97f9-a5cd015f4c7b/artifact.tar.gz"},{"artifact_id":"631c1698-0af4-5b38-ac98-2f8df4220b79","build_state":"succeeded","build_timestamp":"2021-02-20T07:47:53.193Z","dependency_ids":null,"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/noop/artifact.tar.gz"}],"build_engine":"alternative","build_request_id":"0556781d-4318-451e-a388-ac20d62deee2","errors":[],"is_retryable":false,"message":"Recipe build completed successfully","recipe_id":"631c1698-0af4-5b38-ac98-2f8df4220b79","timestamp":"2021-02-20T08:28:53.501Z","type":"build_completed"} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/builds/perl-recipe.json b/pkg/platform/runtime/testhelper/data/builds/perl-recipe.json deleted file mode 100644 index a75d4ad42f..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/perl-recipe.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":[{"artifact_id":"b759aa67-6aa0-51db-b8a5-015a0a7866b4","build_state":"succeeded","build_timestamp":"2020-04-24T17:28:43.000Z","dependency_ids":[],"platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a","uri":"https://s3.amazonaws.com/camel-builds/ActivePerl/x86_64-linux-glibc-2.17/20200424T172842Z/ActivePerl-5.28.1.0000-x86_64-linux-glibc-2.17-2a0758c3-packages.txt"},{"artifact_id":"e88f6f1f-74c9-512e-9c9b-8c921a80c6fb","build_state":"succeeded","build_timestamp":"2020-04-24T17:28:43.000Z","dependency_ids":[],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a","platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a","uri":"https://s3.amazonaws.com/camel-builds/ActivePerl/x86_64-linux-glibc-2.17/20200424T172842Z/ActivePerl-5.28.1.0000-x86_64-linux-glibc-2.17-2a0758c3.tar.gz"}],"build_engine":"camel","build_request_id":"f2c04701-faf5-49d9-b2b6-a35152901d03","errors":[],"is_retryable":false,"log_uri":"https://s3.amazonaws.com/camel-builds/ActivePerl/x86_64-linux-glibc-2.17/20200424T172842Z/ActivePerl-5.28.1.0000-x86_64-linux-glibc-2.17-2a0758c3.log","message":"Build completed successfully","recipe_id":"585b3357-14fa-58a8-96db-4f5aa602113e","timestamp":"2020-04-24T17:28:43.000Z","type":"build_completed"} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/builds/perl.json b/pkg/platform/runtime/testhelper/data/builds/perl.json deleted file mode 100644 index a75d4ad42f..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/perl.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":[{"artifact_id":"b759aa67-6aa0-51db-b8a5-015a0a7866b4","build_state":"succeeded","build_timestamp":"2020-04-24T17:28:43.000Z","dependency_ids":[],"platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a","uri":"https://s3.amazonaws.com/camel-builds/ActivePerl/x86_64-linux-glibc-2.17/20200424T172842Z/ActivePerl-5.28.1.0000-x86_64-linux-glibc-2.17-2a0758c3-packages.txt"},{"artifact_id":"e88f6f1f-74c9-512e-9c9b-8c921a80c6fb","build_state":"succeeded","build_timestamp":"2020-04-24T17:28:43.000Z","dependency_ids":[],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a","platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a","uri":"https://s3.amazonaws.com/camel-builds/ActivePerl/x86_64-linux-glibc-2.17/20200424T172842Z/ActivePerl-5.28.1.0000-x86_64-linux-glibc-2.17-2a0758c3.tar.gz"}],"build_engine":"camel","build_request_id":"f2c04701-faf5-49d9-b2b6-a35152901d03","errors":[],"is_retryable":false,"log_uri":"https://s3.amazonaws.com/camel-builds/ActivePerl/x86_64-linux-glibc-2.17/20200424T172842Z/ActivePerl-5.28.1.0000-x86_64-linux-glibc-2.17-2a0758c3.log","message":"Build completed successfully","recipe_id":"585b3357-14fa-58a8-96db-4f5aa602113e","timestamp":"2020-04-24T17:28:43.000Z","type":"build_completed"} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/builds/python-alternative-base.json b/pkg/platform/runtime/testhelper/data/builds/python-alternative-base.json deleted file mode 100644 index 8737879821..0000000000 --- a/pkg/platform/runtime/testhelper/data/builds/python-alternative-base.json +++ /dev/null @@ -1 +0,0 @@ -{"artifacts":[{"artifact_id":"f0c54356-7350-5804-a857-230268000f0b","build_state":"succeeded","build_timestamp":"2021-07-05T18:04:19.790Z","checksum":"15bb59d747aaa2734191f5c1e9a4e563adb4155ca3264bbc8c9332c0c35983f1","dependency_ids":null,"ingredient_version_id":"b077ac4e-7503-503f-b530-9f7f13dfd77f","log_uri":"s3://as-builds/production/shared/bzip2/1.0.8/4/f0c54356-7350-5804-a857-230268000f0b/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/bzip2/1.0.8/4/f0c54356-7350-5804-a857-230268000f0b/artifact.tar.gz"},{"artifact_id":"abd1cb5d-c520-5218-9891-b35c4c22280f","build_state":"succeeded","build_timestamp":"2021-07-05T18:04:54.973Z","checksum":"15a1b24bd970a4f6811a1dc62c5b5f811534295866d43240a9c2f3815bd6fd7b","dependency_ids":null,"ingredient_version_id":"a45dc564-3e7d-5b43-b2b3-2a941b0f5807","log_uri":"s3://as-builds/production/shared/expat/2.2.9/12/abd1cb5d-c520-5218-9891-b35c4c22280f/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/expat/2.2.9/12/abd1cb5d-c520-5218-9891-b35c4c22280f/artifact.tar.gz"},{"artifact_id":"1927acf9-a8b2-5c31-a2c2-0b50fbf19607","build_state":"succeeded","build_timestamp":"2021-07-05T18:04:14.588Z","checksum":"bbfd13509e2ff80ef8779e87a30394431c6ac580d3a36965c771998a1dc6b817","dependency_ids":null,"ingredient_version_id":"04dfbfcd-33b0-585d-8444-1af40bde98fd","log_uri":"s3://as-builds/production/shared/ffi/3.3/5/1927acf9-a8b2-5c31-a2c2-0b50fbf19607/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/ffi/3.3/5/1927acf9-a8b2-5c31-a2c2-0b50fbf19607/artifact.tar.gz"},{"artifact_id":"754fb735-1ba5-5a20-b374-5d8068892457","build_state":"succeeded","build_timestamp":"2021-07-05T18:04:26.840Z","checksum":"e2eac30394b7b447d69a3b3bc354ad14c78fdb06c6f203110009f5b86c9688ff","dependency_ids":null,"ingredient_version_id":"a59dcc34-5296-529e-a614-d1816ee25ebb","log_uri":"s3://as-builds/production/shared/lzma/5.2.4/6/754fb735-1ba5-5a20-b374-5d8068892457/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/lzma/5.2.4/6/754fb735-1ba5-5a20-b374-5d8068892457/artifact.tar.gz"},{"artifact_id":"a4f0e9ee-58ff-5dc4-ba78-dc84f65456e4","build_state":"succeeded","build_timestamp":"2021-07-05T18:05:50.806Z","checksum":"0e961855cf57f0ccfb551b5ab670550a6f5d757bffb0a1abffd415298cebdc10","dependency_ids":null,"ingredient_version_id":"93bf4699-657f-5fff-9bc0-417c4ac841e4","log_uri":"s3://as-builds/production/shared/ncurses/6.2/3/a4f0e9ee-58ff-5dc4-ba78-dc84f65456e4/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/ncurses/6.2/3/a4f0e9ee-58ff-5dc4-ba78-dc84f65456e4/artifact.tar.gz"},{"artifact_id":"f4f1817a-4571-5572-94c7-ea5f7599c0d1","build_state":"succeeded","build_timestamp":"2021-07-05T18:05:27.252Z","checksum":"4806ec35a1fee13b81e6648ba417d2b0f9ae7f022baa8186bb7b2e3920c3774d","dependency_ids":null,"ingredient_version_id":"b98a9a54-ca3d-509d-9295-7e499a0872a5","log_uri":"s3://as-builds/production/shared/openssl/1.11.0.11/1/f4f1817a-4571-5572-94c7-ea5f7599c0d1/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/openssl/1.11.0.11/1/f4f1817a-4571-5572-94c7-ea5f7599c0d1/artifact.tar.gz"},{"artifact_id":"6ced5e90-0f8d-5840-b4be-a96d744fb879","build_state":"succeeded","build_timestamp":"2021-07-05T18:06:07.310Z","checksum":"7fb1b0a1f31b68e1578cbc4eec7c92d5a25cb4da20089b33f1d787820048a9c3","dependency_ids":null,"ingredient_version_id":"fc0a6031-9d27-5d2b-90cb-871ee6ad01d9","log_uri":"s3://as-builds/production/shared/readline/8.1/4/6ced5e90-0f8d-5840-b4be-a96d744fb879/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/readline/8.1/4/6ced5e90-0f8d-5840-b4be-a96d744fb879/artifact.tar.gz"},{"artifact_id":"b078f93d-644c-551e-a368-bcd5c3026d39","build_state":"succeeded","build_timestamp":"2021-07-05T17:38:16.056Z","checksum":"3f0ef14f56a3ca0d7749b23443e7a1ead8534f573a51a16660c319cbfb3d14db","dependency_ids":null,"ingredient_version_id":"c3b7c513-8be8-56d9-8d30-b19e9c56e393","log_uri":"s3://as-builds/production/shared/zlib/1.2.11/6/b078f93d-644c-551e-a368-bcd5c3026d39/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/zlib/1.2.11/6/b078f93d-644c-551e-a368-bcd5c3026d39/artifact.tar.gz"},{"artifact_id":"e4c49e72-8ac8-5f6d-a6e1-a254f783e482","build_state":"succeeded","build_timestamp":"2021-07-05T18:05:51.835Z","checksum":"cd03e100454ae2e9508a6d33285913ec8dba9a642349dde0fd8630728357cdca","dependency_ids":null,"ingredient_version_id":"56725f0f-e7be-5f77-8a1e-27e33003d763","log_uri":"s3://as-builds/production/shared/sqlite3/3.35.5/2/e4c49e72-8ac8-5f6d-a6e1-a254f783e482/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/sqlite3/3.35.5/2/e4c49e72-8ac8-5f6d-a6e1-a254f783e482/artifact.tar.gz"},{"artifact_id":"f7624f3f-cde8-5b44-9df8-d784c74736a4","build_state":"succeeded","build_timestamp":"2021-07-06T20:44:14.998Z","checksum":"079da8b93e7089f9f90eb6078cb3bfde5e30f41bd144206aa2ff620746f75eb1","dependency_ids":null,"ingredient_version_id":"39d388df-21db-51e5-a550-a6cd04e15ba3","log_uri":"s3://as-builds/production/shared/tcltktix/8.6.10/1/f7624f3f-cde8-5b44-9df8-d784c74736a4/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/shared/tcltktix/8.6.10/1/f7624f3f-cde8-5b44-9df8-d784c74736a4/artifact.tar.gz"},{"artifact_id":"cc37913d-c215-5a8b-a2fc-3f3884b00ca9","build_state":"succeeded","build_timestamp":"2021-07-12T22:57:08.799Z","checksum":"d785ea2cf3715810c7dc1b98452f67936100feade0e0e9ca2bef965742719763","dependency_ids":null,"ingredient_version_id":"1d648abb-c93f-578c-9710-cfd692cea165","log_uri":"s3://as-builds/production/language/python/3.9.6/1/cc37913d-c215-5a8b-a2fc-3f3884b00ca9/logs.jsonl","mime_type":"application/x.artifact","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","uri":"s3://as-builds/production/language/python/3.9.6/1/cc37913d-c215-5a8b-a2fc-3f3884b00ca9/artifact.tar.gz"},{"artifact_id":"413fd54c-f030-58b6-be56-8a90b22eea6b","build_state":"succeeded","build_timestamp":"2021-07-13T23:12:37.888Z","checksum":"bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440","dependency_ids":null,"log_uri":"s3://as-builds/noop/v3/logs.jsonl","mime_type":"application/x.artifact","platform_id":"00000000-0000-0000-0000-000000000000","uri":"s3://as-builds/noop/v3/artifact.tar.gz"}],"build_engine":"alternative","errors":[],"is_retryable":false,"message":"Recipe build completed successfully","recipe_id":"413fd54c-f030-58b6-be56-8a90b22eea6b","timestamp":"2021-07-13T23:21:28.374Z","type":"build_completed"} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/recipes/alternative-bare.json b/pkg/platform/runtime/testhelper/data/recipes/alternative-bare.json deleted file mode 100644 index 819b533af6..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/alternative-bare.json +++ /dev/null @@ -1,9002 +0,0 @@ -{ - "camel_flags": [], - "from_recipe_store": false, - "image": { - "image_id": "b210b15e-c98a-4259-89c8-b7bae56d237f", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/images/b210b15e-c98a-4259-89c8-b7bae56d237f" - }, - "name": "docker-registry.activestate.build/activestate/centos-7.6-builder", - "platform_id": "0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a", - "type": "Docker", - "sortable_version": [ - "1", - "0", - "31", - "0" - ], - "version": "1.0.31", - "provided_features": [ - { - "feature": "GCC", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "7", - "3", - "0" - ], - "version": "7.3" - }, - { - "feature": "GNU C++03", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++14", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C89", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++98", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C99", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++03", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++14", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C89", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++98", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C99", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 77", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 90", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 95", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "author_platform_user_id": "e501c7e7-40cc-4b7a-8fc9-f6a3d314c254", - "comment": "Added a new revision to add compiler features to images", - "is_stable_revision": true, - "conditions": [ - { - "feature": "alternative-builder", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0", - "1", - "0" - ], - "version": "0.0.1" - } - ] - }, - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "status": "stable", - "revision": 4, - "revision_timestamp": "2020-12-03T22:54:45.160370Z" - }, - "is_indemnified": false, - "platform": { - "cpu_architecture": { - "cpu_architecture_id": "4cdba18d-0851-4925-9ae5-9c8a2987828a", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a" - }, - "bit_width": "64", - "name": "x86", - "provided_features": [ - { - "feature": "x86 64-bit", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "cpu-architecture", - "sortable_version": [ - "1", - "0" - ], - "version": "1" - } - ], - "author_platform_user_id": "7f320133-2c9a-476e-9c09-8970ac525a8f", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true, - "revision": 1, - "revision_timestamp": "2019-08-06T21:46:35.288458Z" - }, - "cpu_extensions": [], - "creation_timestamp": "2019-08-06T21:46:35.288458Z", - "display_name": "CentOS 7.6.1810, Linux 4.15.0, glibc 2.17 x86 64-bit", - "images": [ - { - "image_id": "0fceabb4-ca86-4846-9b0a-c23947770cdb", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/images/0fceabb4-ca86-4846-9b0a-c23947770cdb" - }, - "name": "activestate/centos-7.6-build", - "platform_id": "0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a", - "type": "Docker", - "sortable_version": [ - "1", - "0", - "9", - "0" - ], - "version": "1.0.9", - "provided_features": [ - { - "feature": "GCC", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "4", - "9", - "2", - "0" - ], - "version": "4.9.2" - }, - { - "feature": "GNU C++03", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C89", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++98", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C99", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++03", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C89", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++98", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C99", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 77", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 90", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 95", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "author_platform_user_id": "36a36906-04a3-4221-adf1-805632ee9bb7", - "comment": "Added a new revision to add compiler features to images", - "is_stable_revision": true, - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - }, - { - "feature": "bogus-dependency", - "namespace": "shared", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "status": "stable", - "revision": 13, - "revision_timestamp": "2021-02-04T20:25:44.473616Z" - }, - { - "image_id": "b210b15e-c98a-4259-89c8-b7bae56d237f", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/images/b210b15e-c98a-4259-89c8-b7bae56d237f" - }, - "name": "docker-registry.activestate.build/activestate/centos-7.6-builder", - "platform_id": "0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a", - "type": "Docker", - "sortable_version": [ - "1", - "0", - "31", - "0" - ], - "version": "1.0.31", - "provided_features": [ - { - "feature": "GCC", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "7", - "3", - "0" - ], - "version": "7.3" - }, - { - "feature": "GNU C++03", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++14", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C89", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++98", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C99", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++03", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++14", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C89", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++98", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C99", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 77", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 90", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 95", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "author_platform_user_id": "e501c7e7-40cc-4b7a-8fc9-f6a3d314c254", - "comment": "Added a new revision to add compiler features to images", - "is_stable_revision": true, - "conditions": [ - { - "feature": "alternative-builder", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0", - "1", - "0" - ], - "version": "0.0.1" - } - ] - }, - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "status": "stable", - "revision": 4, - "revision_timestamp": "2020-12-03T22:54:45.160370Z" - }, - { - "image_id": "74150f63-4452-4bfa-9622-c64552e68346", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/images/74150f63-4452-4bfa-9622-c64552e68346" - }, - "name": "docker-registry.activestate.build/activestate/centos-7.9-build", - "platform_id": "0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a", - "type": "Docker", - "sortable_version": [ - "1", - "1", - "1", - "0" - ], - "version": "1.1.1", - "provided_features": [ - { - "feature": "GCC", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "7", - "3", - "0" - ], - "version": "7.3" - }, - { - "feature": "GNU C++03", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++14", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C89", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C++98", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "GNU C99", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++03", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++14", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C89", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++98", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C99", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 77", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 90", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO Fortran 95", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "author_platform_user_id": "36a36906-04a3-4221-adf1-805632ee9bb7", - "comment": "Added a new revision to add compiler features to images", - "is_stable_revision": true, - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "status": "stable", - "revision": 1, - "revision_timestamp": "2021-02-04T20:25:28.031620Z" - } - ], - "is_user_visible": true, - "kernel": { - "kernel_id": "ef737274-fff9-4164-b72b-88067613f822", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822" - }, - "name": "Linux" - }, - "kernel_version": { - "kernel_version_id": "2450c462-66e0-4aca-97d4-9910a19996f6", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/2450c462-66e0-4aca-97d4-9910a19996f6" - }, - "sortable_version": [ - "4", - "15", - "0", - "0" - ], - "version": "4.15.0", - "provided_features": [ - { - "feature": "Linux", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "kernel", - "sortable_version": [ - "4", - "15", - "0", - "0" - ], - "version": "4.15.0" - } - ], - "author_platform_user_id": "7f320133-2c9a-476e-9c09-8970ac525a8f", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true, - "revision": 1, - "revision_timestamp": "2019-08-06T21:46:35.288458Z" - }, - "libc": { - "libc_id": "09a2eb42-ad34-4734-a93e-4b97395577df", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df" - }, - "name": "glibc" - }, - "libc_version": { - "libc_version_id": "277c8630-948f-449c-9d69-5cf2ce3eb7eb", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/277c8630-948f-449c-9d69-5cf2ce3eb7eb" - }, - "sortable_version": [ - "2", - "17", - "0" - ], - "version": "2.17", - "provided_features": [ - { - "feature": "glibc", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "libc", - "sortable_version": [ - "2", - "17", - "0" - ], - "version": "2.17" - } - ], - "author_platform_user_id": "7f320133-2c9a-476e-9c09-8970ac525a8f", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true, - "revision": 1, - "revision_timestamp": "2019-08-06T21:46:35.288458Z" - }, - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a" - }, - "operating_system": { - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99" - }, - "operating_system_id": "7b3a2dbb-d543-48d6-8390-7e7b63751e99", - "has_libc": true, - "name": "CentOS" - }, - "operating_system_version": { - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/2cab2f48-fb0b-415f-85f8-ddd045969662" - }, - "operating_system_version_id": "2cab2f48-fb0b-415f-85f8-ddd045969662", - "sortable_version": [ - "7", - "6", - "1810", - "0" - ], - "version": "7.6.1810", - "provided_features": [ - { - "feature": "CentOS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "operating-system", - "sortable_version": [ - "7", - "6", - "1810", - "0" - ], - "version": "7.6.1810" - } - ], - "author_platform_user_id": "7f320133-2c9a-476e-9c09-8970ac525a8f", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true, - "revision": 1, - "revision_timestamp": "2019-08-06T21:46:35.288458Z" - }, - "platform_id": "0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a" - }, - "recipe_id": "ad807d9a-8214-5395-92c4-77b6301248f2", - "resolved_ingredients": [ - { - "alternatives": [], - "artifact_id": "ccffef06-ba83-5716-9dd0-b629f2a65f68", - "build_scripts": null, - "dependencies": [], - "ingredient": { - "creation_timestamp": "2020-08-10T23:47:40.385229Z", - "ingredient_id": "a4128de4-f62c-5349-80e6-b072d5aa3e31", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31" - }, - "name": "perl-core-builder", - "normalized_name": "perl-core-builder", - "primary_namespace": "builder", - "description": "Builds the core Perl interpreter on the ActiveState platform.", - "website": "https://activestate.com" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2020-09-30T17:58:38.567523Z", - "ingredient_id": "a4128de4-f62c-5349-80e6-b072d5aa3e31", - "ingredient_version_id": "d5ac8c7c-b025-5418-ab77-a139e60e1d41", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31/versions/d5ac8c7c-b025-5418-ab77-a139e60e1d41", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31" - }, - "revision": 2, - "revision_timestamp": "2020-10-30T17:04:06.702744Z", - "copyright_text": "To be added.", - "documentation_uri": "https://activestate.com", - "is_binary_only": false, - "license_expression": "(MIT-1.0)", - "release_timestamp": "2020-06-25T07:05:14.000000Z", - "source_uri": "https://github.com/ActiveState/platform-builders/builders/perl-core-builder", - "sortable_version": [ - "1", - "0", - "23", - "0" - ], - "version": "1.0.23", - "activestate_license_expression": "unknown", - "camel_extras": {}, - "dependencies": null, - "ingredient_options": null, - "is_indemnified": false, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/builder/cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374/perl-core-builder.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374", - "status": "stable", - "provided_features": [ - { - "feature": "alternative-builder", - "is_activestate_version": false, - "is_default_provider": false, - "namespace": "builder", - "sortable_version": [ - "1", - "0", - "0", - "0" - ], - "version": "1.0.0" - }, - { - "feature": "perl-core-builder", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "builder", - "sortable_version": [ - "1", - "0", - "23", - "0" - ], - "version": "1.0.23" - } - ], - "author_platform_user_id": "fe7c9294-51d6-4df6-a5b5-44cf5a924ebc", - "comment": "Initial builder for perl 5.30+", - "is_stable_revision": true - }, - "patches": null, - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "71e4a1fe-eba7-5ee1-a95f-94fd70aa2d87", - "build_scripts": null, - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "d5ac8c7c-b025-5418-ab77-a139e60e1d41" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T16:56:32.665096Z", - "ingredient_id": "ed4b2154-eaee-5fba-88bb-d1eca86b1206", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206" - }, - "name": "perl", - "normalized_name": "perl", - "primary_namespace": "language", - "description": "Practical Extraction and Report Language" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2020-10-14T19:24:44.505799Z", - "ingredient_id": "ed4b2154-eaee-5fba-88bb-d1eca86b1206", - "ingredient_version_id": "a845e482-d3ec-5379-aba3-96e74794570f", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206/versions/a845e482-d3ec-5379-aba3-96e74794570f", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206" - }, - "revision": 7, - "revision_timestamp": "2021-02-03T21:13:51.365878Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "1970-01-01T00:00:00.000000Z", - "source_uri": "https://www.cpan.org/src/5.0/perl-5.32.0.tar.gz", - "sortable_version": [ - "5", - "32", - "0" - ], - "version": "5.32.0", - "activestate_license_expression": "[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]", - "camel_extras": {}, - "dependencies": [ - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "description": "The perl language requires a compiler to build", - "feature": "Visual Studio", - "namespace": "compiler", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": null, - "feature": "perl-core-builder", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": null, - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ], - "type": "build" - }, - { - "conditions": null, - "description": "The perl language requires a compiler to build", - "feature": "ISO C89", - "namespace": "compiler", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/language/efeb1ce1f10824190ad1cadbcccf6fdb8a5d37007d0100d2d9ae5f2b5900c0b4/perl-5.32.0.tar.gz", - "scanner_license_expression": "[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]", - "source_checksum": "efeb1ce1f10824190ad1cadbcccf6fdb8a5d37007d0100d2d9ae5f2b5900c0b4", - "status": "stable", - "provided_features": [ - { - "feature": "alternative-built-language", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language", - "sortable_version": [ - "5", - "32", - "0", - "0" - ], - "version": "5.32.0" - }, - { - "feature": "perl", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language", - "sortable_version": [ - "5", - "32", - "0" - ], - "version": "5.32.0" - }, - { - "feature": "Amiga::ARexx", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "40", - "0" - ], - "version": "0.04" - }, - { - "feature": "Amiga::Exec", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "20", - "0" - ], - "version": "0.02" - }, - { - "feature": "AnyDBM_File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "10", - "0" - ], - "version": "1.01" - }, - { - "feature": "App::Cpan", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "675", - "0" - ], - "version": "1.675" - }, - { - "feature": "App::Prove", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "App::Prove::State", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "App::Prove::State::Result", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "App::Prove::State::Result::Test", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "Archive::Tar", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "360", - "0" - ], - "version": "2.36" - }, - { - "feature": "Archive::Tar::Constant", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "360", - "0" - ], - "version": "2.36" - }, - { - "feature": "Archive::Tar::File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "360", - "0" - ], - "version": "2.36" - }, - { - "feature": "Attribute::Handlers", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "10", - "0" - ], - "version": "1.01" - }, - { - "feature": "AutoLoader", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "740", - "0" - ], - "version": "5.74" - }, - { - "feature": "AutoSplit", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "60", - "0" - ], - "version": "1.06" - }, - { - "feature": "B", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "800", - "0" - ], - "version": "1.80" - }, - { - "feature": "B::Concise", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "4", - "0" - ], - "version": "1.004" - }, - { - "feature": "B::Deparse", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "540", - "0" - ], - "version": "1.54" - }, - { - "feature": "B::Op_private", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "32", - "0" - ], - "version": "5.032000" - }, - { - "feature": "B::Showlex", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "50", - "0" - ], - "version": "1.05" - }, - { - "feature": "B::Terse", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "90", - "0" - ], - "version": "1.09" - }, - { - "feature": "B::Xref", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "70", - "0" - ], - "version": "1.07" - }, - { - "feature": "Benchmark", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "230", - "0" - ], - "version": "1.23" - }, - { - "feature": "CPAN", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "270", - "0" - ], - "version": "2.27" - }, - { - "feature": "CPAN::Author", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "200" - ], - "version": "5.5002" - }, - { - "feature": "CPAN::Bundle", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "500" - ], - "version": "5.5005" - }, - { - "feature": "CPAN::CacheMgr", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "200" - ], - "version": "5.5002" - }, - { - "feature": "CPAN::Complete", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "100" - ], - "version": "5.5001" - }, - { - "feature": "CPAN::Debug", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "100" - ], - "version": "5.5001" - }, - { - "feature": "CPAN::DeferredCode", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "0" - ], - "version": "5.50" - }, - { - "feature": "CPAN::Distribution", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "270", - "0" - ], - "version": "2.27" - }, - { - "feature": "CPAN::Distroprefs", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "6", - "0", - "100" - ], - "version": "6.0001" - }, - { - "feature": "CPAN::Distrostatus", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "0" - ], - "version": "5.5" - }, - { - "feature": "CPAN::Exception::RecursiveDependency", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "100" - ], - "version": "5.5001" - }, - { - "feature": "CPAN::Exception::blocked_urllist", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "1", - "0" - ], - "version": "1.001" - }, - { - "feature": "CPAN::Exception::yaml_not_installed", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "0" - ], - "version": "5.5" - }, - { - "feature": "CPAN::Exception::yaml_process_error", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "0" - ], - "version": "5.5" - }, - { - "feature": "CPAN::FTP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "501", - "200" - ], - "version": "5.5012" - }, - { - "feature": "CPAN::FTP::netrc", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "10", - "0" - ], - "version": "1.01" - }, - { - "feature": "CPAN::FirstTime", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "531", - "400" - ], - "version": "5.5314" - }, - { - "feature": "CPAN::HTTP::Client", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "960", - "100" - ], - "version": "1.9601" - }, - { - "feature": "CPAN::HTTP::Credentials", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "960", - "100" - ], - "version": "1.9601" - }, - { - "feature": "CPAN::HandleConfig", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "501", - "100" - ], - "version": "5.5011" - }, - { - "feature": "CPAN::Index", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "120", - "0" - ], - "version": "2.12" - }, - { - "feature": "CPAN::InfoObj", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "0" - ], - "version": "5.5" - }, - { - "feature": "CPAN::Kwalify", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "0" - ], - "version": "5.50" - }, - { - "feature": "CPAN::LWP::UserAgent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "960", - "100" - ], - "version": "1.9601" - }, - { - "feature": "CPAN::Meta", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "150", - "10" - ], - "version": "2.150010" - }, - { - "feature": "CPAN::Meta::Converter", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "150", - "10" - ], - "version": "2.150010" - }, - { - "feature": "CPAN::Meta::Feature", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "150", - "10" - ], - "version": "2.150010" - }, - { - "feature": "CPAN::Meta::History", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "150", - "10" - ], - "version": "2.150010" - }, - { - "feature": "CPAN::Meta::Merge", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "150", - "10" - ], - "version": "2.150010" - }, - { - "feature": "CPAN::Meta::Prereqs", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "150", - "10" - ], - "version": "2.150010" - }, - { - "feature": "CPAN::Meta::Requirements", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "140", - "0" - ], - "version": "2.140" - }, - { - "feature": "CPAN::Meta::Spec", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "150", - "10" - ], - "version": "2.150010" - }, - { - "feature": "CPAN::Meta::Validator", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "150", - "10" - ], - "version": "2.150010" - }, - { - "feature": "CPAN::Meta::YAML", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "18", - "0" - ], - "version": "0.018" - }, - { - "feature": "CPAN::Mirrors", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "270", - "0" - ], - "version": "2.27" - }, - { - "feature": "CPAN::Module", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "300" - ], - "version": "5.5003" - }, - { - "feature": "CPAN::Nox", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "100" - ], - "version": "5.5001" - }, - { - "feature": "CPAN::Plugin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "970", - "0" - ], - "version": "0.97" - }, - { - "feature": "CPAN::Plugin::Specfile", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "20", - "0" - ], - "version": "0.02" - }, - { - "feature": "CPAN::Prompt", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "0" - ], - "version": "5.5" - }, - { - "feature": "CPAN::Queue", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "300" - ], - "version": "5.5003" - }, - { - "feature": "CPAN::Shell", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "900" - ], - "version": "5.5009" - }, - { - "feature": "CPAN::Tarzip", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "501", - "300" - ], - "version": "5.5013" - }, - { - "feature": "CPAN::URL", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "0" - ], - "version": "5.5" - }, - { - "feature": "CPAN::Version", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "500", - "300" - ], - "version": "5.5003" - }, - { - "feature": "Carp", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "500", - "0" - ], - "version": "1.50" - }, - { - "feature": "Carp::Heavy", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "500", - "0" - ], - "version": "1.50" - }, - { - "feature": "Class::Struct", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "660", - "0" - ], - "version": "0.66" - }, - { - "feature": "Compress::Raw::Bzip2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "Compress::Raw::Zlib", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "Compress::Zlib", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "Config", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "32", - "0" - ], - "version": "5.032" - }, - { - "feature": "Config::Extensions", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "30", - "0" - ], - "version": "0.03" - }, - { - "feature": "Config::Perl::V", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "320", - "0" - ], - "version": "0.32" - }, - { - "feature": "Cwd", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "DB", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "80", - "0" - ], - "version": "1.08" - }, - { - "feature": "DBM_Filter", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "60", - "0" - ], - "version": "0.06" - }, - { - "feature": "DBM_Filter::compress", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "30", - "0" - ], - "version": "0.03" - }, - { - "feature": "DBM_Filter::encode", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "30", - "0" - ], - "version": "0.03" - }, - { - "feature": "DBM_Filter::int32", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "30", - "0" - ], - "version": "0.03" - }, - { - "feature": "DBM_Filter::null", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "30", - "0" - ], - "version": "0.03" - }, - { - "feature": "DBM_Filter::utf8", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "30", - "0" - ], - "version": "0.03" - }, - { - "feature": "DB_File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "853", - "0" - ], - "version": "1.853" - }, - { - "feature": "Data::Dumper", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "174", - "0" - ], - "version": "2.174" - }, - { - "feature": "Devel::PPPort", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "570", - "0" - ], - "version": "3.57" - }, - { - "feature": "Devel::Peek", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "280", - "0" - ], - "version": "1.28" - }, - { - "feature": "Devel::SelfStubber", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "60", - "0" - ], - "version": "1.06" - }, - { - "feature": "Digest", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "170", - "100" - ], - "version": "1.17_01" - }, - { - "feature": "Digest::MD5", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "550", - "100" - ], - "version": "2.55_01" - }, - { - "feature": "Digest::SHA", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "6", - "20", - "0" - ], - "version": "6.02" - }, - { - "feature": "Digest::base", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "160", - "0" - ], - "version": "1.16" - }, - { - "feature": "Digest::file", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "160", - "0" - ], - "version": "1.16" - }, - { - "feature": "DirHandle", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "50", - "0" - ], - "version": "1.05" - }, - { - "feature": "Dumpvalue", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "210", - "0" - ], - "version": "1.21" - }, - { - "feature": "DynaLoader", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "470", - "0" - ], - "version": "1.47" - }, - { - "feature": "Encode", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "60", - "0" - ], - "version": "3.06" - }, - { - "feature": "Encode::Alias", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "240", - "0" - ], - "version": "2.24" - }, - { - "feature": "Encode::Byte", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "40", - "0" - ], - "version": "2.04" - }, - { - "feature": "Encode::CJKConstants", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "20", - "0" - ], - "version": "2.02" - }, - { - "feature": "Encode::CN", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "30", - "0" - ], - "version": "2.03" - }, - { - "feature": "Encode::CN::HZ", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "100", - "0" - ], - "version": "2.10" - }, - { - "feature": "Encode::Config", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "50", - "0" - ], - "version": "2.05" - }, - { - "feature": "Encode::EBCDIC", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "20", - "0" - ], - "version": "2.02" - }, - { - "feature": "Encode::Encoder", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "30", - "0" - ], - "version": "2.03" - }, - { - "feature": "Encode::Encoding", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "80", - "0" - ], - "version": "2.08" - }, - { - "feature": "Encode::GSM0338", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "70", - "0" - ], - "version": "2.07" - }, - { - "feature": "Encode::Guess", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "80", - "0" - ], - "version": "2.08" - }, - { - "feature": "Encode::JP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "40", - "0" - ], - "version": "2.04" - }, - { - "feature": "Encode::JP::H2Z", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "20", - "0" - ], - "version": "2.02" - }, - { - "feature": "Encode::JP::JIS7", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "80", - "0" - ], - "version": "2.08" - }, - { - "feature": "Encode::KR", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "30", - "0" - ], - "version": "2.03" - }, - { - "feature": "Encode::KR::2022_KR", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "40", - "0" - ], - "version": "2.04" - }, - { - "feature": "Encode::MIME::Header", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "280", - "0" - ], - "version": "2.28" - }, - { - "feature": "Encode::MIME::Header::ISO_2022_JP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "90", - "0" - ], - "version": "1.09" - }, - { - "feature": "Encode::MIME::Name", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "Encode::Symbol", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "20", - "0" - ], - "version": "2.02" - }, - { - "feature": "Encode::TW", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "30", - "0" - ], - "version": "2.03" - }, - { - "feature": "Encode::Unicode", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "180", - "0" - ], - "version": "2.18" - }, - { - "feature": "Encode::Unicode::UTF7", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "100", - "0" - ], - "version": "2.10" - }, - { - "feature": "English", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "110", - "0" - ], - "version": "1.11" - }, - { - "feature": "Env", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "40", - "0" - ], - "version": "1.04" - }, - { - "feature": "Errno", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "300", - "0" - ], - "version": "1.30" - }, - { - "feature": "Exporter", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "740", - "0" - ], - "version": "5.74" - }, - { - "feature": "Exporter::Heavy", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "740", - "0" - ], - "version": "5.74" - }, - { - "feature": "ExtUtils::CBuilder", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Base", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::Unix", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::VMS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::Windows", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::Windows::BCC", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::Windows::GCC", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::Windows::MSVC", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::aix", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::android", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::cygwin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::darwin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::dec_osf", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::CBuilder::Platform::os2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "234" - ], - "version": "0.280234" - }, - { - "feature": "ExtUtils::Command", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::Command::MM", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::Constant", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "250", - "0" - ], - "version": "0.25" - }, - { - "feature": "ExtUtils::Constant::Base", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "60", - "0" - ], - "version": "0.06" - }, - { - "feature": "ExtUtils::Constant::ProxySubs", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "90", - "0" - ], - "version": "0.09" - }, - { - "feature": "ExtUtils::Constant::Utils", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "40", - "0" - ], - "version": "0.04" - }, - { - "feature": "ExtUtils::Constant::XS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "30", - "0" - ], - "version": "0.03" - }, - { - "feature": "ExtUtils::Embed", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "350", - "0" - ], - "version": "1.35" - }, - { - "feature": "ExtUtils::Install", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "140", - "0" - ], - "version": "2.14" - }, - { - "feature": "ExtUtils::Installed", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "140", - "0" - ], - "version": "2.14" - }, - { - "feature": "ExtUtils::Liblist", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::Liblist::Kid", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_AIX", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_Any", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_BeOS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_Cygwin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_DOS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_Darwin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_MacOS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_NW5", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_OS2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_QNX", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_UWIN", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_Unix", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_VMS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_VOS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_Win32", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MM_Win95", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MY", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MakeMaker", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MakeMaker::Config", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MakeMaker::Locale", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MakeMaker::version", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::MakeMaker::version::regex", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::Manifest", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "720", - "0" - ], - "version": "1.72" - }, - { - "feature": "ExtUtils::Miniperl", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "90", - "0" - ], - "version": "1.09" - }, - { - "feature": "ExtUtils::Mkbootstrap", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::Mksymlists", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "ExtUtils::Packlist", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "140", - "0" - ], - "version": "2.14" - }, - { - "feature": "ExtUtils::ParseXS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "ExtUtils::ParseXS::Constants", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "ExtUtils::ParseXS::CountLines", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "ExtUtils::ParseXS::Eval", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "ExtUtils::ParseXS::Utilities", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "ExtUtils::Typemaps", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "380", - "0" - ], - "version": "3.38" - }, - { - "feature": "ExtUtils::Typemaps::Cmd", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "380", - "0" - ], - "version": "3.38" - }, - { - "feature": "ExtUtils::Typemaps::InputMap", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "380", - "0" - ], - "version": "3.38" - }, - { - "feature": "ExtUtils::Typemaps::OutputMap", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "380", - "0" - ], - "version": "3.38" - }, - { - "feature": "ExtUtils::Typemaps::Type", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "380", - "0" - ], - "version": "3.38" - }, - { - "feature": "ExtUtils::XSSymSet", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "400", - "0" - ], - "version": "1.4" - }, - { - "feature": "ExtUtils::testlib", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "7", - "440", - "0" - ], - "version": "7.44" - }, - { - "feature": "Fatal", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "320", - "0" - ], - "version": "2.32" - }, - { - "feature": "Fcntl", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "130", - "0" - ], - "version": "1.13" - }, - { - "feature": "File::Basename", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "850", - "0" - ], - "version": "2.85" - }, - { - "feature": "File::Compare", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "100", - "600" - ], - "version": "1.1006" - }, - { - "feature": "File::Copy", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "340", - "0" - ], - "version": "2.34" - }, - { - "feature": "File::DosGlob", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "120", - "0" - ], - "version": "1.12" - }, - { - "feature": "File::Fetch", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "560", - "0" - ], - "version": "0.56" - }, - { - "feature": "File::Find", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "370", - "0" - ], - "version": "1.37" - }, - { - "feature": "File::Glob", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "330", - "0" - ], - "version": "1.33" - }, - { - "feature": "File::GlobMapper", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "1", - "0" - ], - "version": "1.001" - }, - { - "feature": "File::Path", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "160", - "0" - ], - "version": "2.16" - }, - { - "feature": "File::Spec", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "File::Spec::AmigaOS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "File::Spec::Cygwin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "File::Spec::Epoc", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "File::Spec::Functions", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "File::Spec::Mac", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "File::Spec::OS2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "File::Spec::Unix", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "File::Spec::VMS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "780", - "0" - ], - "version": "3.78" - }, - { - "feature": "File::Spec::Win32", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "790", - "0" - ], - "version": "3.79" - }, - { - "feature": "File::Temp", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "230", - "900" - ], - "version": "0.2309" - }, - { - "feature": "File::stat", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "90", - "0" - ], - "version": "1.09" - }, - { - "feature": "FileCache", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "100", - "0" - ], - "version": "1.10" - }, - { - "feature": "FileHandle", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "30", - "0" - ], - "version": "2.03" - }, - { - "feature": "Filter::Simple", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "960", - "0" - ], - "version": "0.96" - }, - { - "feature": "Filter::Util::Call", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "590", - "0" - ], - "version": "1.59" - }, - { - "feature": "FindBin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "510", - "0" - ], - "version": "1.51" - }, - { - "feature": "GDBM_File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "180", - "0" - ], - "version": "1.18" - }, - { - "feature": "Getopt::Long", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "510", - "0" - ], - "version": "2.51" - }, - { - "feature": "Getopt::Std", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "120", - "0" - ], - "version": "1.12" - }, - { - "feature": "HTTP::Tiny", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "76", - "0" - ], - "version": "0.076" - }, - { - "feature": "Hash::Util", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "230", - "0" - ], - "version": "0.23" - }, - { - "feature": "Hash::Util::FieldHash", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "200", - "0" - ], - "version": "1.20" - }, - { - "feature": "I18N::Collate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "20", - "0" - ], - "version": "1.02" - }, - { - "feature": "I18N::LangTags", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "440", - "0" - ], - "version": "0.44" - }, - { - "feature": "I18N::LangTags::Detect", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "80", - "0" - ], - "version": "1.08" - }, - { - "feature": "I18N::LangTags::List", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "400", - "0" - ], - "version": "0.40" - }, - { - "feature": "I18N::Langinfo", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "190", - "0" - ], - "version": "0.19" - }, - { - "feature": "IO", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "430", - "0" - ], - "version": "1.43" - }, - { - "feature": "IO::Compress::Adapter::Bzip2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Adapter::Deflate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Adapter::Identity", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Base", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Base::Common", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Bzip2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Deflate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Gzip", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Gzip::Constants", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::RawDeflate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Zip", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Zip::Constants", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Zlib::Constants", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Compress::Zlib::Extra", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Dir", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "410", - "0" - ], - "version": "1.41" - }, - { - "feature": "IO::File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "410", - "0" - ], - "version": "1.41" - }, - { - "feature": "IO::Handle", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "420", - "0" - ], - "version": "1.42" - }, - { - "feature": "IO::Pipe", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "410", - "0" - ], - "version": "1.41" - }, - { - "feature": "IO::Poll", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "410", - "0" - ], - "version": "1.41" - }, - { - "feature": "IO::Seekable", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "410", - "0" - ], - "version": "1.41" - }, - { - "feature": "IO::Select", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "420", - "0" - ], - "version": "1.42" - }, - { - "feature": "IO::Socket", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "430", - "0" - ], - "version": "1.43" - }, - { - "feature": "IO::Socket::INET", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "410", - "0" - ], - "version": "1.41" - }, - { - "feature": "IO::Socket::IP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "390", - "0" - ], - "version": "0.39" - }, - { - "feature": "IO::Socket::UNIX", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "410", - "0" - ], - "version": "1.41" - }, - { - "feature": "IO::Uncompress::Adapter::Bunzip2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::Adapter::Identity", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::Adapter::Inflate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::AnyInflate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::AnyUncompress", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::Base", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::Bunzip2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::Gunzip", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::Inflate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::RawInflate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Uncompress::Unzip", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "93", - "0" - ], - "version": "2.093" - }, - { - "feature": "IO::Zlib", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "100", - "0" - ], - "version": "1.10" - }, - { - "feature": "IPC::Cmd", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "40", - "0" - ], - "version": "1.04" - }, - { - "feature": "IPC::Msg", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "70", - "0" - ], - "version": "2.07" - }, - { - "feature": "IPC::Open2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "50", - "0" - ], - "version": "1.05" - }, - { - "feature": "IPC::Open3", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "210", - "0" - ], - "version": "1.21" - }, - { - "feature": "IPC::Semaphore", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "70", - "0" - ], - "version": "2.07" - }, - { - "feature": "IPC::SharedMem", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "70", - "0" - ], - "version": "2.07" - }, - { - "feature": "IPC::SysV", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "70", - "0" - ], - "version": "2.07" - }, - { - "feature": "JSON::PP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "40", - "0" - ], - "version": "4.04" - }, - { - "feature": "JSON::PP::Boolean", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "40", - "0" - ], - "version": "4.04" - }, - { - "feature": "List::Util", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "550", - "0" - ], - "version": "1.55" - }, - { - "feature": "List::Util::XS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "550", - "0" - ], - "version": "1.55" - }, - { - "feature": "Locale::Maketext", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "290", - "0" - ], - "version": "1.29" - }, - { - "feature": "Locale::Maketext::Guts", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "200", - "0" - ], - "version": "1.20" - }, - { - "feature": "Locale::Maketext::GutsLoader", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "200", - "0" - ], - "version": "1.20" - }, - { - "feature": "Locale::Maketext::Simple", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "210", - "100" - ], - "version": "0.21_01" - }, - { - "feature": "MIME::Base64", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "150", - "0" - ], - "version": "3.15" - }, - { - "feature": "MIME::QuotedPrint", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "130", - "0" - ], - "version": "3.13" - }, - { - "feature": "Math::BigFloat", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "999", - "818" - ], - "version": "1.999818" - }, - { - "feature": "Math::BigFloat::Trace", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "510", - "0" - ], - "version": "0.51" - }, - { - "feature": "Math::BigInt", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "999", - "818" - ], - "version": "1.999818" - }, - { - "feature": "Math::BigInt::Calc", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "999", - "818" - ], - "version": "1.999818" - }, - { - "feature": "Math::BigInt::FastCalc", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "500", - "900" - ], - "version": "0.5009" - }, - { - "feature": "Math::BigInt::Lib", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "999", - "818" - ], - "version": "1.999818" - }, - { - "feature": "Math::BigInt::Trace", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "510", - "0" - ], - "version": "0.51" - }, - { - "feature": "Math::BigRat", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "261", - "400" - ], - "version": "0.2614" - }, - { - "feature": "Math::Complex", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "590", - "100" - ], - "version": "1.5901" - }, - { - "feature": "Math::Trig", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "230", - "0" - ], - "version": "1.23" - }, - { - "feature": "Memoize", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "100" - ], - "version": "1.03_01" - }, - { - "feature": "Memoize::AnyDBM_File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "Memoize::Expire", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "Memoize::ExpireFile", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "Memoize::ExpireTest", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "Memoize::NDBM_File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "Memoize::SDBM_File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "Memoize::Storable", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "Module::CoreList", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "202", - "6", - "200" - ], - "version": "5.20200620" - }, - { - "feature": "Module::CoreList::Utils", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "202", - "6", - "200" - ], - "version": "5.20200620" - }, - { - "feature": "Module::Load", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "340", - "0" - ], - "version": "0.34" - }, - { - "feature": "Module::Load::Conditional", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "700", - "0" - ], - "version": "0.70" - }, - { - "feature": "Module::Loaded", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "80", - "0" - ], - "version": "0.08" - }, - { - "feature": "Module::Metadata", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "0", - "37" - ], - "version": "1.000037" - }, - { - "feature": "Moped::Msg", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "10", - "0" - ], - "version": "0.01" - }, - { - "feature": "NDBM_File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "150", - "0" - ], - "version": "1.15" - }, - { - "feature": "NEXT", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "670", - "100" - ], - "version": "0.67_01" - }, - { - "feature": "Net::Cmd", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::Config", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::Domain", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::FTP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::FTP::A", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::FTP::E", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::FTP::I", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::FTP::L", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::FTP::dataconn", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::NNTP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::Netrc", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::POP3", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::Ping", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "720", - "0" - ], - "version": "2.72" - }, - { - "feature": "Net::SMTP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::Time", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "110", - "0" - ], - "version": "3.11" - }, - { - "feature": "Net::hostent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "20", - "0" - ], - "version": "1.02" - }, - { - "feature": "Net::netent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "10", - "0" - ], - "version": "1.01" - }, - { - "feature": "Net::protoent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "10", - "0" - ], - "version": "1.01" - }, - { - "feature": "Net::servent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "20", - "0" - ], - "version": "1.02" - }, - { - "feature": "O", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "ODBM_File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "160", - "0" - ], - "version": "1.16" - }, - { - "feature": "OS2::DLL", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "70", - "0" - ], - "version": "1.07" - }, - { - "feature": "OS2::ExtAttr", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "40", - "0" - ], - "version": "0.04" - }, - { - "feature": "OS2::PrfDB", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "40", - "0" - ], - "version": "0.04" - }, - { - "feature": "OS2::Process", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "120", - "0" - ], - "version": "1.12" - }, - { - "feature": "OS2::REXX", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "50", - "0" - ], - "version": "1.05" - }, - { - "feature": "Opcode", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "470", - "0" - ], - "version": "1.47" - }, - { - "feature": "POSIX", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "940", - "0" - ], - "version": "1.94" - }, - { - "feature": "Params::Check", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "380", - "0" - ], - "version": "0.38" - }, - { - "feature": "Parse::CPAN::Meta", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "150", - "10" - ], - "version": "2.150010" - }, - { - "feature": "Perl::OSType", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "10", - "0" - ], - "version": "1.010" - }, - { - "feature": "PerlIO", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "110", - "0" - ], - "version": "1.11" - }, - { - "feature": "PerlIO::encoding", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "280", - "0" - ], - "version": "0.28" - }, - { - "feature": "PerlIO::mmap", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "16", - "0" - ], - "version": "0.016" - }, - { - "feature": "PerlIO::scalar", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "300", - "0" - ], - "version": "0.30" - }, - { - "feature": "PerlIO::via", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "180", - "0" - ], - "version": "0.18" - }, - { - "feature": "PerlIO::via::QuotedPrint", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "80", - "0" - ], - "version": "0.08" - }, - { - "feature": "Pod::Checker", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "730", - "0" - ], - "version": "1.73" - }, - { - "feature": "Pod::Escapes", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "70", - "0" - ], - "version": "1.07" - }, - { - "feature": "Pod::Functions", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "130", - "0" - ], - "version": "1.13" - }, - { - "feature": "Pod::Functions::Functions", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "130", - "0" - ], - "version": "1.13" - }, - { - "feature": "Pod::Html", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "250", - "0" - ], - "version": "1.25" - }, - { - "feature": "Pod::Man", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "140", - "0" - ], - "version": "4.14" - }, - { - "feature": "Pod::ParseLink", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "140", - "0" - ], - "version": "4.14" - }, - { - "feature": "Pod::Perldoc", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "100" - ], - "version": "3.2801" - }, - { - "feature": "Pod::Perldoc::BaseTo", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::GetOptsOO", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToANSI", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToChecker", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToMan", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToNroff", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToPod", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToRtf", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToTerm", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToText", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToTk", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Perldoc::ToXml", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "280", - "0" - ], - "version": "3.28" - }, - { - "feature": "Pod::Simple", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::BlackBox", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::Checker", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::Debug", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::DumpAsText", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::DumpAsXML", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::HTML", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::HTMLBatch", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::HTMLLegacy", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "10", - "0" - ], - "version": "5.01" - }, - { - "feature": "Pod::Simple::LinkSection", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::Methody", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::Progress", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::PullParser", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::PullParserEndToken", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::PullParserStartToken", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::PullParserTextToken", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::PullParserToken", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::RTF", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::Search", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::SimpleTree", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::Text", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::TextContent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::TiedOutFH", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::Transcode", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::TranscodeDumb", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::TranscodeSmart", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::XHTML", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Simple::XMLOutStream", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "400", - "0" - ], - "version": "3.40" - }, - { - "feature": "Pod::Text", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "140", - "0" - ], - "version": "4.14" - }, - { - "feature": "Pod::Text::Color", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "140", - "0" - ], - "version": "4.14" - }, - { - "feature": "Pod::Text::Overstrike", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "140", - "0" - ], - "version": "4.14" - }, - { - "feature": "Pod::Text::Termcap", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "140", - "0" - ], - "version": "4.14" - }, - { - "feature": "Pod::Usage", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "690", - "0" - ], - "version": "1.69" - }, - { - "feature": "SDBM_File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "150", - "0" - ], - "version": "1.15" - }, - { - "feature": "Safe", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "410", - "0" - ], - "version": "2.41" - }, - { - "feature": "Scalar::Util", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "550", - "0" - ], - "version": "1.55" - }, - { - "feature": "Search::Dict", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "70", - "0" - ], - "version": "1.07" - }, - { - "feature": "SelectSaver", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "20", - "0" - ], - "version": "1.02" - }, - { - "feature": "SelfLoader", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "260", - "0" - ], - "version": "1.26" - }, - { - "feature": "Socket", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "29", - "0" - ], - "version": "2.029" - }, - { - "feature": "Storable", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "210", - "0" - ], - "version": "3.21" - }, - { - "feature": "Sub::Util", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "550", - "0" - ], - "version": "1.55" - }, - { - "feature": "Symbol", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "80", - "0" - ], - "version": "1.08" - }, - { - "feature": "Sys::Hostname", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "230", - "0" - ], - "version": "1.23" - }, - { - "feature": "Sys::Syslog", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "360", - "0" - ], - "version": "0.36" - }, - { - "feature": "TAP::Base", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Formatter::Base", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Formatter::Color", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Formatter::Console", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Formatter::Console::ParallelSession", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Formatter::Console::Session", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Formatter::File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Formatter::File::Session", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Formatter::Session", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Harness", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Harness::Env", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Object", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Aggregator", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Grammar", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Iterator", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Iterator::Array", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Iterator::Process", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Iterator::Stream", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::IteratorFactory", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Multiplexer", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Result", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Result::Bailout", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Result::Comment", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Result::Plan", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Result::Pragma", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Result::Test", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Result::Unknown", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Result::Version", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Result::YAML", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::ResultFactory", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Scheduler", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Scheduler::Job", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Scheduler::Spinner", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::Source", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::SourceHandler", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::SourceHandler::Executable", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::SourceHandler::File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::SourceHandler::Handle", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::SourceHandler::Perl", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::SourceHandler::RawTAP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::YAMLish::Reader", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "TAP::Parser::YAMLish::Writer", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "Term::ANSIColor", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "10", - "0" - ], - "version": "5.01" - }, - { - "feature": "Term::Cap", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "170", - "0" - ], - "version": "1.17" - }, - { - "feature": "Term::Complete", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "403", - "0" - ], - "version": "1.403" - }, - { - "feature": "Term::ReadLine", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "170", - "0" - ], - "version": "1.17" - }, - { - "feature": "Test", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "310", - "0" - ], - "version": "1.31" - }, - { - "feature": "Test2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::API", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::API::Breakage", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::API::Context", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::API::Instance", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::API::Stack", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Bail", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Diag", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Encoding", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Exception", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Fail", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Generic", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Note", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Ok", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Pass", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Plan", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Skip", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Subtest", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::TAP::Version", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::V2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Event::Waiting", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::About", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Amnesty", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Assert", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Control", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Error", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Hub", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Info", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Info::Table", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Meta", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Parent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Plan", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Render", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::EventFacet::Trace", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Formatter", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Formatter::TAP", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Hub", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Hub::Interceptor", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Hub::Interceptor::Terminator", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Hub::Subtest", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::IPC", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::IPC::Driver", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::IPC::Driver::Files", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Tools::Tiny", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Util", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Util::ExternalMeta", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Util::Facets2Legacy", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Util::HashBase", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test2::Util::Trace", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Builder", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Builder::Formatter", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Builder::IO::Scalar", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "114", - "0" - ], - "version": "2.114" - }, - { - "feature": "Test::Builder::Module", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Builder::Tester", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Builder::Tester::Color", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Builder::TodoDiag", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Harness", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "420", - "0" - ], - "version": "3.42" - }, - { - "feature": "Test::More", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Simple", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Tester", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Tester::Capture", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Tester::CaptureRunner", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::Tester::Delegate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Test::use::ok", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "Text::Abbrev", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "20", - "0" - ], - "version": "1.02" - }, - { - "feature": "Text::Balanced", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "30", - "0" - ], - "version": "2.03" - }, - { - "feature": "Text::ParseWords", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "300", - "0" - ], - "version": "3.30" - }, - { - "feature": "Text::Tabs", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2013", - "52", - "300" - ], - "version": "2013.0523" - }, - { - "feature": "Text::Wrap", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2013", - "52", - "300" - ], - "version": "2013.0523" - }, - { - "feature": "Thread", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "50", - "0" - ], - "version": "3.05" - }, - { - "feature": "Thread::Queue", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "140", - "0" - ], - "version": "3.14" - }, - { - "feature": "Thread::Semaphore", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "130", - "0" - ], - "version": "2.13" - }, - { - "feature": "Tie::Array", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "70", - "0" - ], - "version": "1.07" - }, - { - "feature": "Tie::File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "60", - "0" - ], - "version": "1.06" - }, - { - "feature": "Tie::Handle", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "200", - "0" - ], - "version": "4.2" - }, - { - "feature": "Tie::Hash", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "50", - "0" - ], - "version": "1.05" - }, - { - "feature": "Tie::Hash::NamedCapture", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "130", - "0" - ], - "version": "0.13" - }, - { - "feature": "Tie::Memoize", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "100", - "0" - ], - "version": "1.1" - }, - { - "feature": "Tie::RefHash", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "390", - "0" - ], - "version": "1.39" - }, - { - "feature": "Tie::Scalar", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "50", - "0" - ], - "version": "1.05" - }, - { - "feature": "Tie::StdHandle", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "4", - "600", - "0" - ], - "version": "4.6" - }, - { - "feature": "Tie::SubstrHash", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "0", - "0" - ], - "version": "1.0" - }, - { - "feature": "Time::HiRes", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "976", - "400" - ], - "version": "1.9764" - }, - { - "feature": "Time::Local", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "280", - "0" - ], - "version": "1.28" - }, - { - "feature": "Time::Piece", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "340", - "100" - ], - "version": "1.3401" - }, - { - "feature": "Time::Seconds", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "340", - "100" - ], - "version": "1.3401" - }, - { - "feature": "Time::gmtime", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "40", - "0" - ], - "version": "1.04" - }, - { - "feature": "Time::localtime", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "Time::tm", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "0", - "0" - ], - "version": "1.0" - }, - { - "feature": "UNIVERSAL", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "130", - "0" - ], - "version": "1.13" - }, - { - "feature": "Unicode", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "13", - "0", - "0" - ], - "version": "13.0.0" - }, - { - "feature": "Unicode::Collate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::Collate::CJK::Big5", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::Collate::CJK::GB2312", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::Collate::CJK::JISX0208", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::Collate::CJK::Korean", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::Collate::CJK::Pinyin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::Collate::CJK::Stroke", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::Collate::CJK::Zhuyin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::Collate::Locale", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::Normalize", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "270", - "0" - ], - "version": "1.27" - }, - { - "feature": "Unicode::UCD", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "750", - "0" - ], - "version": "0.75" - }, - { - "feature": "User::grent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "User::pwent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "10", - "0" - ], - "version": "1.01" - }, - { - "feature": "VMS::DCLsym", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "90", - "0" - ], - "version": "1.09" - }, - { - "feature": "VMS::Filespec", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "120", - "0" - ], - "version": "1.12" - }, - { - "feature": "VMS::Stdio", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "450", - "0" - ], - "version": "2.45" - }, - { - "feature": "Win32", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "530", - "0" - ], - "version": "0.53" - }, - { - "feature": "Win32API::File", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "120", - "301" - ], - "version": "0.1203_01" - }, - { - "feature": "Win32API::File::inc::ExtUtils::Myconst2perl", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "0", - "0" - ], - "version": "1" - }, - { - "feature": "Win32CORE", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "40", - "0" - ], - "version": "0.04" - }, - { - "feature": "XS::APItest", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "90", - "0" - ], - "version": "1.09" - }, - { - "feature": "XS::Typemap", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "170", - "0" - ], - "version": "0.17" - }, - { - "feature": "XSLoader", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "300", - "0" - ], - "version": "0.30" - }, - { - "feature": "_charnames", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "480", - "0" - ], - "version": "1.48" - }, - { - "feature": "attributes", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "330", - "0" - ], - "version": "0.33" - }, - { - "feature": "autodie", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "320", - "0" - ], - "version": "2.32" - }, - { - "feature": "autodie::Scope::Guard", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "320", - "0" - ], - "version": "2.32" - }, - { - "feature": "autodie::Scope::GuardStack", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "320", - "0" - ], - "version": "2.32" - }, - { - "feature": "autodie::Util", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "320", - "0" - ], - "version": "2.32" - }, - { - "feature": "autodie::exception", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "320", - "0" - ], - "version": "2.32" - }, - { - "feature": "autodie::exception::system", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "320", - "0" - ], - "version": "2.32" - }, - { - "feature": "autodie::hints", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "320", - "0" - ], - "version": "2.32" - }, - { - "feature": "autodie::skip", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "320", - "0" - ], - "version": "2.32" - }, - { - "feature": "autouse", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "110", - "0" - ], - "version": "1.11" - }, - { - "feature": "base", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "270", - "0" - ], - "version": "2.27" - }, - { - "feature": "bigint", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "510", - "0" - ], - "version": "0.51" - }, - { - "feature": "bignum", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "510", - "0" - ], - "version": "0.51" - }, - { - "feature": "bigrat", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "510", - "0" - ], - "version": "0.51" - }, - { - "feature": "blib", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "70", - "0" - ], - "version": "1.07" - }, - { - "feature": "bytes", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "70", - "0" - ], - "version": "1.07" - }, - { - "feature": "charnames", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "480", - "0" - ], - "version": "1.48" - }, - { - "feature": "constant", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "330", - "0" - ], - "version": "1.33" - }, - { - "feature": "deprecate", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "40", - "0" - ], - "version": "0.04" - }, - { - "feature": "diagnostics", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "370", - "0" - ], - "version": "1.37" - }, - { - "feature": "encoding", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "3", - "0", - "0" - ], - "version": "3.00" - }, - { - "feature": "encoding::warnings", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "130", - "0" - ], - "version": "0.13" - }, - { - "feature": "experimental", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "20", - "0" - ], - "version": "0.020" - }, - { - "feature": "feature", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "580", - "0" - ], - "version": "1.58" - }, - { - "feature": "fields", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "240", - "0" - ], - "version": "2.24" - }, - { - "feature": "filetest", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "if", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "60", - "800" - ], - "version": "0.0608" - }, - { - "feature": "integer", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "10", - "0" - ], - "version": "1.01" - }, - { - "feature": "less", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "30", - "0" - ], - "version": "0.03" - }, - { - "feature": "lib", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "650", - "0" - ], - "version": "0.65" - }, - { - "feature": "locale", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "90", - "0" - ], - "version": "1.09" - }, - { - "feature": "mro", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "230", - "0" - ], - "version": "1.23" - }, - { - "feature": "ok", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "302", - "175" - ], - "version": "1.302175" - }, - { - "feature": "open", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "120", - "0" - ], - "version": "1.12" - }, - { - "feature": "ops", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "20", - "0" - ], - "version": "1.02" - }, - { - "feature": "overload", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "310", - "0" - ], - "version": "1.31" - }, - { - "feature": "overloading", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "20", - "0" - ], - "version": "0.02" - }, - { - "feature": "parent", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "238", - "0" - ], - "version": "0.238" - }, - { - "feature": "perlfaq", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "5", - "202", - "5", - "230" - ], - "version": "5.20200523" - }, - { - "feature": "re", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "400", - "0" - ], - "version": "0.40" - }, - { - "feature": "sigtrap", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "90", - "0" - ], - "version": "1.09" - }, - { - "feature": "sort", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "40", - "0" - ], - "version": "2.04" - }, - { - "feature": "strict", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "110", - "0" - ], - "version": "1.11" - }, - { - "feature": "subs", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "30", - "0" - ], - "version": "1.03" - }, - { - "feature": "threads", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "2", - "250", - "0" - ], - "version": "2.25" - }, - { - "feature": "threads::shared", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "610", - "0" - ], - "version": "1.61" - }, - { - "feature": "utf8", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "220", - "0" - ], - "version": "1.22" - }, - { - "feature": "vars", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "50", - "0" - ], - "version": "1.05" - }, - { - "feature": "version", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "992", - "400" - ], - "version": "0.9924" - }, - { - "feature": "version::regex", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "0", - "992", - "400" - ], - "version": "0.9924" - }, - { - "feature": "vmsish", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "40", - "0" - ], - "version": "1.04" - }, - { - "feature": "warnings", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "470", - "0" - ], - "version": "1.47" - }, - { - "feature": "warnings::register", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/perl", - "sortable_version": [ - "1", - "40", - "0" - ], - "version": "1.04" - } - ], - "author_platform_user_id": "fe7c9294-51d6-4df6-a5b5-44cf5a924ebc", - "comment": "Bump again", - "is_stable_revision": true - }, - "patches": null, - "resolved_requirements": [ - { - "feature": "perl", - "namespace": "language", - "version_requirements": [ - { - "comparator": "eq", - "version": "5.32.0" - } - ] - } - ] - } - ], - "solver_version": 1 -} diff --git a/pkg/platform/runtime/testhelper/data/recipes/camel.json b/pkg/platform/runtime/testhelper/data/recipes/camel.json deleted file mode 100644 index f3f6ee1ef8..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/camel.json +++ /dev/null @@ -1,3137 +0,0 @@ -{ - "camel_flags": [], - "from_recipe_store": false, - "image": { - "image_id": "4b8b53b0-609b-4a02-865a-0fb2974f9952", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/images/4b8b53b0-609b-4a02-865a-0fb2974f9952" - }, - "name": "macos1013-camel-builder", - "platform_id": "96b7e6f2-bebf-564c-bc1c-f04482398f38", - "type": "Mac", - "sortable_version": [ - "4", - "0" - ], - "version": "4", - "provided_features": [], - "author_platform_user_id": "e501c7e7-40cc-4b7a-8fc9-f6a3d314c254", - "comment": "Added a new revision to add compiler features to images", - "is_stable_revision": true, - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "status": "stable", - "revision": 5, - "revision_timestamp": "2020-12-03T22:54:45.160370Z" - }, - "is_indemnified": false, - "platform": { - "cpu_architecture": { - "cpu_architecture_id": "4cdba18d-0851-4925-9ae5-9c8a2987828a", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a" - }, - "bit_width": "64", - "name": "x86", - "provided_features": [ - { - "feature": "x86 64-bit", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "cpu-architecture", - "sortable_version": [ - "1", - "0" - ], - "version": "1" - } - ], - "author_platform_user_id": "7f320133-2c9a-476e-9c09-8970ac525a8f", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true, - "revision": 1, - "revision_timestamp": "2019-08-06T21:46:35.288458Z" - }, - "cpu_extensions": [], - "creation_timestamp": "2019-08-06T21:46:35.288458Z", - "display_name": "macOS 10.12.6, Darwin 16.6.0, libSystem 1238.60.2 x86 64-bit", - "end_of_support_date": "2030-02-03", - "images": [ - { - "image_id": "4b8b53b0-609b-4a02-865a-0fb2974f9952", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/images/4b8b53b0-609b-4a02-865a-0fb2974f9952" - }, - "name": "macos1013-camel-builder", - "platform_id": "96b7e6f2-bebf-564c-bc1c-f04482398f38", - "type": "Mac", - "sortable_version": [ - "4", - "0" - ], - "version": "4", - "provided_features": [ - { - "feature": "clang", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "1000", - "10", - "44", - "4", - "0" - ], - "version": "1000.10.44.4" - }, - { - "feature": "ISO C++03", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++11", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++14", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++17", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C89", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C++98", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - }, - { - "feature": "ISO C99", - "is_activestate_version": true, - "is_default_provider": true, - "namespace": "compiler", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "author_platform_user_id": "e501c7e7-40cc-4b7a-8fc9-f6a3d314c254", - "comment": "Added a new revision to add compiler features to images", - "is_stable_revision": true, - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "status": "stable", - "revision": 5, - "revision_timestamp": "2020-12-03T22:54:45.160370Z" - } - ], - "is_user_visible": true, - "kernel": { - "kernel_id": "7d600f8a-bc24-4875-a09c-8e63c4da078c", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/7d600f8a-bc24-4875-a09c-8e63c4da078c" - }, - "name": "Darwin" - }, - "kernel_version": { - "kernel_version_id": "e7d8c941-4dfd-49fe-81f7-5bb90df0edd9", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/7d600f8a-bc24-4875-a09c-8e63c4da078c/versions/e7d8c941-4dfd-49fe-81f7-5bb90df0edd9" - }, - "sortable_version": [ - "16", - "6", - "0", - "0" - ], - "version": "16.6.0", - "provided_features": [ - { - "feature": "Darwin", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "kernel", - "sortable_version": [ - "16", - "6", - "0", - "0" - ], - "version": "16.6.0" - } - ], - "author_platform_user_id": "7f320133-2c9a-476e-9c09-8970ac525a8f", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true, - "revision": 1, - "revision_timestamp": "2019-08-06T21:46:35.288458Z" - }, - "libc": { - "libc_id": "669bbbe3-1f57-48d3-a11e-018780809b4a", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/669bbbe3-1f57-48d3-a11e-018780809b4a" - }, - "name": "libSystem" - }, - "libc_version": { - "libc_version_id": "6e0f402c-3837-4d73-a36c-9cd4ace9d002", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/669bbbe3-1f57-48d3-a11e-018780809b4a/versions/6e0f402c-3837-4d73-a36c-9cd4ace9d002" - }, - "sortable_version": [ - "1238", - "60", - "2", - "0" - ], - "version": "1238.60.2", - "provided_features": [ - { - "feature": "libSystem", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "libc", - "sortable_version": [ - "1238", - "60", - "2", - "0" - ], - "version": "1238.60.2" - } - ], - "author_platform_user_id": "7f320133-2c9a-476e-9c09-8970ac525a8f", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true, - "revision": 1, - "revision_timestamp": "2019-08-06T21:46:35.288458Z" - }, - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/96b7e6f2-bebf-564c-bc1c-f04482398f38" - }, - "operating_system": { - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/63d8f1cc-5f5c-47e1-bab0-74d38938d919" - }, - "operating_system_id": "63d8f1cc-5f5c-47e1-bab0-74d38938d919", - "has_libc": true, - "name": "macOS" - }, - "operating_system_version": { - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/63d8f1cc-5f5c-47e1-bab0-74d38938d919/versions/da15b51d-12d8-484d-8006-cc5f93198817" - }, - "operating_system_version_id": "da15b51d-12d8-484d-8006-cc5f93198817", - "sortable_version": [ - "10", - "12", - "6", - "0" - ], - "version": "10.12.6", - "provided_features": [ - { - "feature": "macOS", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "operating-system", - "sortable_version": [ - "10", - "12", - "6", - "0" - ], - "version": "10.12.6" - } - ], - "author_platform_user_id": "7f320133-2c9a-476e-9c09-8970ac525a8f", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true, - "revision": 1, - "revision_timestamp": "2019-08-06T21:46:35.288458Z" - }, - "platform_id": "96b7e6f2-bebf-564c-bc1c-f04482398f38" - }, - "recipe_id": "0adc81a2-760d-5577-9827-309c9c9c645f", - "resolved_ingredients": [ - { - "alternatives": [], - "artifact_id": "e8a2b6cc-19de-5b87-bb84-8ba67039aa79", - "build_scripts": null, - "dependencies": [], - "ingredient": { - "creation_timestamp": "2019-10-21T19:16:38.749062Z", - "ingredient_id": "20816534-c073-5d68-9eb7-11c1d6be09f5", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/20816534-c073-5d68-9eb7-11c1d6be09f5" - }, - "name": "camel", - "normalized_name": "camel", - "primary_namespace": "builder", - "description": "The camel unified build system", - "website": "https://platform.activestate.com" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2021-02-16T17:50:29.599906Z", - "ingredient_id": "20816534-c073-5d68-9eb7-11c1d6be09f5", - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/20816534-c073-5d68-9eb7-11c1d6be09f5/versions/c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/20816534-c073-5d68-9eb7-11c1d6be09f5" - }, - "revision": 1, - "revision_timestamp": "2021-02-16T17:50:29.599906Z", - "copyright_text": "Copyright © ActiveState Inc, 2004-2020", - "documentation_uri": "https://github.com/ActiveState/camel/tree/3d46a065883c88b560d67edf7ea1f96bef125ae6/docs", - "is_binary_only": false, - "license_expression": "UNLICENSED", - "release_timestamp": "2021-02-16T17:50:24.296928Z", - "source_uri": "https://github.com/ActiveState/camel/tree/3d46a065883c88b560d67edf7ea1f96bef125ae6", - "sortable_version": [ - "20210216", - "125023", - "3", - "100", - "46", - "97", - "65", - "0" - ], - "version": "20210216.125023.3d46a065", - "activestate_license_expression": "UNLICENSED", - "camel_extras": {}, - "dependencies": null, - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://INVALID", - "scanner_license_expression": "UNLICENSED", - "source_checksum": "3d46a065883c88b560d67edf7ea1f96bef125ae6", - "status": "stable", - "provided_features": [ - { - "feature": "camel", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "builder", - "sortable_version": [ - "20210216", - "125023", - "3", - "100", - "46", - "97", - "65", - "0" - ], - "version": "20210216.125023.3d46a065" - } - ], - "author_platform_user_id": "8fd0aa9c-0483-4ee7-9197-96c9194c0318", - "comment": "Camel commit.", - "is_stable_revision": true - }, - "patches": null, - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "bdd5642b-928c-5770-9e12-5816c9676960", - "build_scripts": null, - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "06b8597a-4cc1-5e3c-b548-f0baa7861688" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "3bde6cf9-2445-563f-8e65-1437d1737a8f" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "491568f3-50a4-56f6-a971-580eaa99715f" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "54cbf7c2-c87c-51b5-a2cc-72b3b284d68c" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "8d5d63b0-e941-59a3-8653-35470bd70056" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "a45dc564-3e7d-5b43-b2b3-2a941b0f5807" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "a61c1442-98a0-576c-b606-3046b22c3413" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "b0d9a189-aedb-5461-b872-5e643ac97551" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c3b7c513-8be8-56d9-8d30-b19e9c56e393" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T17:06:08.287941Z", - "ingredient_id": "161a6a17-6b8a-54c9-a476-2c8c960b054e", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/161a6a17-6b8a-54c9-a476-2c8c960b054e" - }, - "name": "python", - "normalized_name": "python", - "primary_namespace": "language", - "description": "It's just a flesh wound!" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2019-10-01T17:06:08.287941Z", - "ingredient_id": "161a6a17-6b8a-54c9-a476-2c8c960b054e", - "ingredient_version_id": "be4744a4-89a6-58bb-b345-d15468657076", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/161a6a17-6b8a-54c9-a476-2c8c960b054e/versions/be4744a4-89a6-58bb-b345-d15468657076", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/161a6a17-6b8a-54c9-a476-2c8c960b054e" - }, - "revision": 13, - "revision_timestamp": "2020-12-08T19:15:07.163109Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "1970-01-01T00:00:00.000000Z", - "source_uri": "https://s3.amazonaws.com/camel-sources/src/ActivePython/vendor/Python-3.7.4.tgz", - "sortable_version": [ - "0", - "3", - "7", - "4", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "3.7.4", - "activestate_license_expression": "unknown", - "camel_extras": {}, - "dependencies": [ - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "feature": "windows-python-core-openssl", - "namespace": "language/python", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Linux", - "namespace": "kernel", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "feature": "lzma", - "namespace": "shared", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [ - "5", - "2", - "4", - "0" - ], - "version": "5.2.4" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "tk", - "namespace": "shared", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [ - "8", - "6", - "8", - "0" - ], - "version": "8.6.8" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "AIX", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - }, - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "sqlite3", - "namespace": "shared", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [ - "3", - "15", - "2", - "0" - ], - "version": "3.15.2" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "bzip2", - "namespace": "shared", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [ - "1", - "0", - "6", - "0" - ], - "version": "1.0.6" - } - ], - "type": "build" - }, - { - "conditions": null, - "description": "All ingredients have a build-time dependency on the camel build system", - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "expat", - "namespace": "shared", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "2", - "2", - "7", - "0" - ], - "version": "2.2.7" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "tix", - "namespace": "shared", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "8", - "4", - "3", - "0" - ], - "version": "8.4.3" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0.0", - "0.0" - ], - "version": "0" - } - ] - } - ], - "description": "The python language requires a compiler to build", - "feature": "Visual Studio", - "namespace": "compiler", - "requirements": [ - { - "comparator": "lt", - "sortable_version": [ - "15.0", - "0.0" - ], - "version": "15" - }, - { - "comparator": "gte", - "sortable_version": [ - "14.0", - "0.0" - ], - "version": "14" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "tcl", - "namespace": "shared", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [ - "8", - "6", - "8", - "0" - ], - "version": "8.6.8" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "openssl", - "namespace": "shared", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "1", - "11", - "0", - "0", - "0" - ], - "version": "1.11.0.0" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "zlib", - "namespace": "shared", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [ - "1", - "2", - "11", - "0" - ], - "version": "1.2.11" - } - ], - "type": "build" - }, - { - "conditions": null, - "description": "The python language requires a compiler to build", - "feature": "ISO C89", - "namespace": "compiler", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0.0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "Windows", - "namespace": "kernel", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "bsddb", - "namespace": "shared", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [ - "4", - "4", - "20", - "0" - ], - "version": "4.4.20" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/languages/d63e63e14e6d29e17490abbe6f7d17afb3db182dbd801229f14e55f4157c4ba3/Python-3.7.4.tgz", - "scanner_license_expression": "unknown", - "source_checksum": "d63e63e14e6d29e17490abbe6f7d17afb3db182dbd801229f14e55f4157c4ba3", - "status": "stable", - "provided_features": [ - { - "feature": "python", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language", - "sortable_version": [ - "0", - "3", - "7", - "4", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "3.7.4" - }, - { - "feature": "pip", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/python", - "sortable_version": [ - "0", - "18", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "18.0" - }, - { - "feature": "setuptools", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/python", - "sortable_version": [ - "0", - "40", - "8", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "40.8.0" - } - ], - "author_platform_user_id": "ddfb4cc7-4a50-45a5-a6a5-1336b3ad1ef2", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true - }, - "patches": [ - { - "creation_timestamp": "2020-08-31T18:14:54.204215Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/8869b8cc-11d5-43cf-8d4d-0c93ada5dba3" - }, - "patch_id": "8869b8cc-11d5-43cf-8d4d-0c93ada5dba3", - "conditions": null, - "content": "s3://platform-sources/patches/7ddd664c4f000ae9c38e8730add4cd501514439c400ae3b78f76d68be2881c47.patch", - "description": "From 6299dd58bb662ebd801d6d86f82ade7f533b692b Mon Sep 17 00:00:00 2001\nFrom: Ashley Whetter \nDate: Thu, 2 Jan 2020 08:57:44 -0800\nSubject: [PATCH] v3.7.4 patched from apy/3.7/*\n\nd057759576 activepython: Merge tag 'v3.7.4' into apy/3.7/activepython\n839b605c44 activepython: Add changes needed for V3.7\nd057759576 nix: Merge tag 'v3.7.4' into apy/3.7/activepython\n839b605c44 nix: Add changes needed for V3.7\n738a9121c4 win32: Compile openssl from source and build against it\n78c745359f win32: Revert \"Support downloading externals directly from cpython-bin-deps\"\n16ebbdc015 win32: Support downloading externals directly from cpython-bin-deps\n04e6fc4fcf win32: Can override version of openssl\n54d8f0462c win32: Support downloading externals directly from cpython-source-deps\nd2745843cf win32: Build against OpenSSL sources\n9309e799e8 win32: bump versions for tcl, tk, openssl and remove commands that are no longer used\nddf9c43ece win32: Merge branch 'apy/3.7/activepython' into apy/3.7/win32\nd057759576 win32: Merge tag 'v3.7.4' into apy/3.7/activepython\n839b605c44 win32: Add changes needed for V3.7\n7b3d6b9d7e win32: Update OpenSSL to 1.1.0k\n5b9627c322 win32: Add tcl 8.6.8 and openssl 1.1.0j to 3.7\n69570872c7 win32: Upgrade sqlite3 to 3.24.0.0\n0de3cf0acd win32: Set tcltk and openssl bins\n1ce01cc66a win32: Remove bin from openssl tarball name\nbaa340b145 win32: Add zlib to list of files to get for Windows\n81257a43c7 win32: Add AS specific build scripts for building", - "sequence_number": 1 - }, - { - "creation_timestamp": "2020-08-31T18:14:54.492940Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/80bef92b-2971-49b3-b5c5-448230d0675e" - }, - "patch_id": "80bef92b-2971-49b3-b5c5-448230d0675e", - "conditions": null, - "content": "python-3.7.4-python.props.patch", - "description": "HEAD~1 patched from activepython/3.7/*", - "sequence_number": 2 - } - ], - "resolved_requirements": [ - { - "feature": "python", - "namespace": "language", - "version_requirements": [ - { - "comparator": "eq", - "version": "3.7.4" - } - ] - } - ] - }, - { - "alternatives": [], - "artifact_id": "decfc04f-5770-5663-8d00-e029402e6917", - "build_scripts": null, - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "806b06ad-3f32-52e1-aecb-677759ce8c74" - }, - { - "dependency_types": [ - "build", - "runtime", - "test" - ], - "ingredient_version_id": "be4744a4-89a6-58bb-b345-d15468657076" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2020-10-18T02:02:00.611863Z", - "ingredient_id": "39750e64-e0bf-5a97-9caa-d6ec8ec8c456", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/39750e64-e0bf-5a97-9caa-d6ec8ec8c456" - }, - "name": "json2", - "normalized_name": "json2", - "primary_namespace": "language/python", - "description": "# Logfast\n\n## Purpose\nPython package which just wraps the default python json but with.\n```json2.load_file``` and ```json2.save_file```\n\n## Installation\n\n```pip install json2```\n\n## Usage\n\n```\nimport ...", - "website": "https://github.com/ThoenigAdrian/json2" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2020-10-23T02:19:24.740864Z", - "ingredient_id": "39750e64-e0bf-5a97-9caa-d6ec8ec8c456", - "ingredient_version_id": "a30e7169-d1b8-5f34-b50b-6be74d369e9c", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/39750e64-e0bf-5a97-9caa-d6ec8ec8c456/versions/a30e7169-d1b8-5f34-b50b-6be74d369e9c", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/39750e64-e0bf-5a97-9caa-d6ec8ec8c456" - }, - "revision": 1, - "revision_timestamp": "2020-10-23T02:19:24.740864Z", - "copyright_text": "Could not be determined", - "is_binary_only": false, - "license_expression": "UNKNOWN", - "release_timestamp": "2020-10-18T21:56:38.000000Z", - "source_uri": "https://files.pythonhosted.org/packages/91/2a/ec4045f29cacf6eb06c8b7577ce783149d5ec0349c2959937fe867124cfa/json2-0.4.0.tar.gz", - "sortable_version": [ - "0", - "0", - "4", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "0.4.0", - "activestate_license_expression": "unknown", - "camel_extras": {}, - "dependencies": [ - { - "conditions": null, - "description": "Extracted from source distribution in PyPI.", - "feature": "wheel", - "namespace": "language/python", - "original_requirement": "wheel", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": null, - "description": "Extracted from source distribution in PyPI.", - "feature": "python", - "namespace": "language", - "original_requirement": "python >=0", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "0" - } - ], - "type": "runtime" - }, - { - "conditions": null, - "description": "Extracted from source distribution in PyPI.", - "feature": "python", - "namespace": "language", - "original_requirement": "python >=0", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": null, - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": null, - "description": "Extracted from source distribution in PyPI.", - "feature": "python", - "namespace": "language", - "original_requirement": "python >=0", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "0" - } - ], - "type": "test" - } - ], - "ingredient_options": null, - "is_indemnified": false, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/data-acquisition/eab80bdfcc30fd0ee934c3c67a959d76ea1a45a629c4c10cdf6f8078c6224fc8/json2-0.4.0.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "eab80bdfcc30fd0ee934c3c67a959d76ea1a45a629c4c10cdf6f8078c6224fc8", - "status": "stable", - "provided_features": [ - { - "feature": "json2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/python", - "sortable_version": [ - "0", - "0", - "4", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "0.4.0" - } - ], - "author_platform_user_id": "2e044215-1b51-498f-a440-ae0cc11bdd4c", - "comment": "Data Acquisition import run with commit ID abef5908904fe908ad93c6140e56044dd4b47f72 and reason: Automated sync of newly whitelisted language/python ingredient versions", - "is_stable_revision": true - }, - "patches": null, - "resolved_requirements": [ - { - "feature": "json2", - "namespace": "language/python", - "version_requirements": null - } - ] - }, - { - "alternatives": [], - "artifact_id": "e6997088-7854-5498-8c57-afbe4343036a", - "build_scripts": null, - "dependencies": [ - { - "dependency_types": [ - "build", - "runtime", - "test" - ], - "ingredient_version_id": "be4744a4-89a6-58bb-b345-d15468657076" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T17:08:07.349831Z", - "ingredient_id": "9d592341-b78d-5e0f-b7ee-83b4533441b2", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9d592341-b78d-5e0f-b7ee-83b4533441b2" - }, - "name": "wheel", - "normalized_name": "wheel", - "primary_namespace": "language/python", - "description": "The wheel package" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2020-11-13T23:46:48.685681Z", - "ingredient_id": "9d592341-b78d-5e0f-b7ee-83b4533441b2", - "ingredient_version_id": "806b06ad-3f32-52e1-aecb-677759ce8c74", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9d592341-b78d-5e0f-b7ee-83b4533441b2/versions/806b06ad-3f32-52e1-aecb-677759ce8c74", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9d592341-b78d-5e0f-b7ee-83b4533441b2" - }, - "revision": 3, - "revision_timestamp": "2020-11-20T23:08:03.168261Z", - "copyright_text": "Could not be determined", - "is_binary_only": false, - "license_expression": "UNKNOWN", - "release_timestamp": "2020-08-15T02:23:59.000000Z", - "source_uri": "https://files.pythonhosted.org/packages/83/72/611c121b6bd15479cb62f1a425b2e3372e121b324228df28e64cc28b01c2/wheel-0.35.1.tar.gz", - "sortable_version": [ - "0", - "0", - "35", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "0.35.1", - "activestate_license_expression": "unknown", - "camel_extras": {}, - "dependencies": [ - { - "conditions": null, - "description": "Extracted from source distribution in PyPI.", - "feature": "python", - "namespace": "language", - "original_requirement": "python >=0", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "3", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "3" - } - ], - "type": "runtime" - }, - { - "conditions": null, - "description": "Extracted from source distribution in PyPI.", - "feature": "python", - "namespace": "language", - "original_requirement": "python >=0", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "3", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "3" - } - ], - "type": "test" - }, - { - "conditions": null, - "description": "Extracted from source distribution in PyPI.", - "feature": "python", - "namespace": "language", - "original_requirement": "python >=0", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "3", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "3" - } - ], - "type": "build" - }, - { - "conditions": null, - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": false, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/data-acquisition/99a22d87add3f634ff917310a3d87e499f19e663413a52eb9232c447aa646c9f/wheel-0.35.1.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "99a22d87add3f634ff917310a3d87e499f19e663413a52eb9232c447aa646c9f", - "status": "stable", - "provided_features": [ - { - "feature": "wheel", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "language/python", - "sortable_version": [ - "0", - "0", - "35", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "version": "0.35.1" - } - ], - "author_platform_user_id": "e51a58da-d22b-49c2-9fe6-f143159120eb", - "comment": "Data Acquisition import run with commit ID 0000000000000000000000000000000000000000 and reason: Could not be determined from the database query", - "is_stable_revision": true - }, - "patches": null, - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "2a2dc52f-8324-59bf-ae5e-082ea2468a28", - "build_scripts": [ - { - "build_script_id": "e00c71e5-6c74-487b-a67f-6a120e17f068", - "creation_timestamp": "2019-10-01T17:01:14.537345Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/e00c71e5-6c74-487b-a67f-6a120e17f068" - }, - "conditions": null, - "language": "perl", - "script": "db-4.4.20-AS-Makefile.PL" - } - ], - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T17:01:14.890567Z", - "ingredient_id": "5a6e935d-3fb3-5629-a4cf-34e78b035e5f", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/5a6e935d-3fb3-5629-a4cf-34e78b035e5f" - }, - "name": "bsddb", - "normalized_name": "bsddb", - "primary_namespace": "shared", - "description": "Berkeley Database" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2019-10-01T17:01:14.890567Z", - "ingredient_id": "5a6e935d-3fb3-5629-a4cf-34e78b035e5f", - "ingredient_version_id": "06b8597a-4cc1-5e3c-b548-f0baa7861688", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/5a6e935d-3fb3-5629-a4cf-34e78b035e5f/versions/06b8597a-4cc1-5e3c-b548-f0baa7861688", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/5a6e935d-3fb3-5629-a4cf-34e78b035e5f" - }, - "revision": 2, - "revision_timestamp": "2019-10-24T21:51:00.179770Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "1970-01-01T00:00:00.000000Z", - "source_uri": "https://s3.amazonaws.com/camel-sources/src/vendor-sources/python/db-4.4.20.NC-pysvn.zip", - "sortable_version": [ - "4", - "4", - "20", - "0" - ], - "version": "4.4.20", - "activestate_license_expression": "unknown", - "camel_extras": { - "skip_test": "yes" - }, - "dependencies": [ - { - "conditions": null, - "description": "All ingredients have a build-time dependency on the camel build system", - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/shared/0732630da52af56e1d8a92a4a386405b5b13aa21715aa4e8d28da647c57affba/db-4.4.20.NC-pysvn.zip", - "scanner_license_expression": "unknown", - "source_checksum": "0732630da52af56e1d8a92a4a386405b5b13aa21715aa4e8d28da647c57affba", - "status": "stable", - "provided_features": [ - { - "feature": "bsddb", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "shared", - "sortable_version": [ - "4", - "4", - "20", - "0" - ], - "version": "4.4.20" - } - ], - "author_platform_user_id": "7f320133-2c9a-476e-9c09-8970ac525a8f", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true - }, - "patches": null, - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "f6f7099a-2a86-5a30-8098-a111661cfbc5", - "build_scripts": [ - { - "build_script_id": "9c94a935-e12a-4211-8c69-151cc0cea019", - "creation_timestamp": "2019-11-21T00:41:56.108670Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/9c94a935-e12a-4211-8c69-151cc0cea019" - }, - "conditions": null, - "language": "perl", - "script": "bzip2-1.0.6-AS-Makefile.PL" - } - ], - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T16:55:29.800792Z", - "ingredient_id": "c9621f15-45d3-5da0-849a-f2979aa8e0d5", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c9621f15-45d3-5da0-849a-f2979aa8e0d5" - }, - "name": "bzip2", - "normalized_name": "bzip2", - "primary_namespace": "shared", - "description": "bzip2 is a data compressor." - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2019-10-01T16:55:29.800792Z", - "ingredient_id": "c9621f15-45d3-5da0-849a-f2979aa8e0d5", - "ingredient_version_id": "3bde6cf9-2445-563f-8e65-1437d1737a8f", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c9621f15-45d3-5da0-849a-f2979aa8e0d5/versions/3bde6cf9-2445-563f-8e65-1437d1737a8f", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c9621f15-45d3-5da0-849a-f2979aa8e0d5" - }, - "revision": 5, - "revision_timestamp": "2020-09-16T16:53:25.145774Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "2018-11-03T00:00:00.000000Z", - "source_uri": "https://s3.amazonaws.com/camel-sources/src/vendor-sources/bzip2-1.0.6.tar.gz", - "sortable_version": [ - "1", - "0", - "6", - "0" - ], - "version": "1.0.6", - "activestate_license_expression": "unknown", - "camel_extras": { - "ppm_pkg": "no", - "skip_test": "yes" - }, - "dependencies": [ - { - "conditions": null, - "description": "All ingredients have a build-time dependency on the camel build system", - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/shared/a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd/bzip2-1.0.6.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd", - "status": "stable", - "provided_features": [ - { - "feature": "bzip2", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "shared", - "sortable_version": [ - "1", - "0", - "6", - "0" - ], - "version": "1.0.6" - } - ], - "author_platform_user_id": "a19a07b9-313a-4e8f-916b-633457d72be8", - "comment": "Convert patch content to S3 URI and add condition on camel builder", - "is_stable_revision": true - }, - "patches": [ - { - "creation_timestamp": "2020-09-16T16:53:24.890193Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/0e0735a7-c5cd-47ed-a599-e2c9475b37c8" - }, - "patch_id": "0e0735a7-c5cd-47ed-a599-e2c9475b37c8", - "conditions": [ - { - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "content": "s3://platform-sources/patches/Libraries/patches/bzip2-1.0.6-Makefile-install.patch", - "description": "Only install headers and lib, some of these paths broke on\n Windows. Add an MSVC install target.", - "sequence_number": 1 - } - ], - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "1931b61b-5e8b-5bce-a5ff-5663a0b9b9c3", - "build_scripts": [ - { - "build_script_id": "2bca6c96-626f-472b-a3e0-6fc2e19d5da1", - "creation_timestamp": "2021-01-11T17:46:35.461471Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/2bca6c96-626f-472b-a3e0-6fc2e19d5da1" - }, - "conditions": null, - "language": "perl", - "script": "s3://platform-sources/build_scripts/2dd5db9d3d82fffed2a682f960dc4bc4f41dcdbb62f4e83f4586c793452709f7/expat-2.2.9-AS-Makefile.PL" - } - ], - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T16:55:36.729403Z", - "ingredient_id": "005fec58-7763-5ccf-9fce-d35fa3bfd791", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/005fec58-7763-5ccf-9fce-d35fa3bfd791" - }, - "name": "expat", - "normalized_name": "expat", - "primary_namespace": "shared", - "description": "The expat package" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2019-11-05T00:40:36.179438Z", - "ingredient_id": "005fec58-7763-5ccf-9fce-d35fa3bfd791", - "ingredient_version_id": "a45dc564-3e7d-5b43-b2b3-2a941b0f5807", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/005fec58-7763-5ccf-9fce-d35fa3bfd791/versions/a45dc564-3e7d-5b43-b2b3-2a941b0f5807", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/005fec58-7763-5ccf-9fce-d35fa3bfd791" - }, - "revision": 11, - "revision_timestamp": "2021-01-11T17:46:36.186158Z", - "copyright_text": "To be added.", - "documentation_uri": "https://libexpat.github.io/doc/", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "2019-09-24T00:00:00.000000Z", - "source_uri": "https://github.com/libexpat/libexpat/archive/R_2_2_9.tar.gz", - "sortable_version": [ - "2", - "2", - "9", - "0" - ], - "version": "2.2.9", - "activestate_license_expression": "unknown", - "camel_extras": { - "skip_test": "yes" - }, - "dependencies": [ - { - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "feature": "autotools-builder", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/shared/4456e0aa72ecc7e1d4b3368cd545a5eec7f9de5133a8dc37fdb1efa6174c4947/expat-2.2.9.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "4456e0aa72ecc7e1d4b3368cd545a5eec7f9de5133a8dc37fdb1efa6174c4947", - "status": "stable", - "provided_features": [ - { - "feature": "expat", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "shared", - "sortable_version": [ - "2", - "2", - "9", - "0" - ], - "version": "2.2.9" - } - ], - "author_platform_user_id": "8fd0aa9c-0483-4ee7-9197-96c9194c0318", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true - }, - "patches": [ - { - "creation_timestamp": "2021-01-11T17:46:35.593158Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/57c568bc-9f1e-4a0b-904d-cd41ba27cd05" - }, - "patch_id": "57c568bc-9f1e-4a0b-904d-cd41ba27cd05", - "conditions": [ - { - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "content": "s3://platform-sources/patches/239341623ebad1490c7f33ec81681f497c1e2f1ffe75e6810162e7c1e40757c7.patch", - "description": "expat ~ Add MSVC Makefile. Created for expat-2.2.9.", - "sequence_number": 1 - }, - { - "creation_timestamp": "2021-01-11T17:46:35.711198Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/a55c2d03-bae1-40f1-ae5b-fbb050c702fb" - }, - "patch_id": "a55c2d03-bae1-40f1-ae5b-fbb050c702fb", - "conditions": [ - { - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "content": "s3://platform-sources/patches/ac8dcdeb798a847dc56d29de262552e873ac88883e6630552a668997a9a64b4f.patch", - "description": "expat ~ Remove hidden flag for AIX. Created for expat-2.2.9.", - "sequence_number": 2 - }, - { - "creation_timestamp": "2021-01-11T17:46:35.846122Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/798eadbe-103f-422b-a761-938cbef16a5a" - }, - "patch_id": "798eadbe-103f-422b-a761-938cbef16a5a", - "conditions": [ - { - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "content": "s3://platform-sources/patches/00b3bb81c1032a8854cf469ac7208dc6e192bc0e0acfbe41677aca61a67ad457.patch", - "description": "expat ~ Update for C89. Created for expat-2.2.9", - "sequence_number": 3 - }, - { - "creation_timestamp": "2021-01-11T17:46:36.033025Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/586a3c05-b1a4-433a-a673-7b382c681906" - }, - "patch_id": "586a3c05-b1a4-433a-a673-7b382c681906", - "conditions": null, - "content": "s3://platform-sources/patches/92f35efe9d078a78bc8ab10b92649ed3f814a3242b91d83ebe1f36f4bdd0e9a4.patch", - "description": "expat ~ Fix tests trying to use wine when not cross-compiling", - "sequence_number": 4 - } - ], - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "fb916bb5-73f9-55f8-9a01-ad79a876e00c", - "build_scripts": [ - { - "build_script_id": "844336b4-e883-44c8-bf22-de11ddfbd482", - "creation_timestamp": "2020-10-29T19:15:40.719565Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/844336b4-e883-44c8-bf22-de11ddfbd482" - }, - "conditions": null, - "language": "perl", - "script": "s3://platform-sources/build_scripts/4432de517c9e851a7f7772843cb30f6dda380a5e330ce39f3169186421048566/openssl-1.1.1-AS-Makefile.PL" - } - ], - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T16:56:17.721017Z", - "ingredient_id": "c1256669-2a2d-5cf2-8860-804bf43ceb5f", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f" - }, - "name": "openssl", - "normalized_name": "openssl", - "primary_namespace": "shared", - "description": "Open Secure Sockets Layer general cryptography library." - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2020-06-16T06:27:06.148324Z", - "ingredient_id": "c1256669-2a2d-5cf2-8860-804bf43ceb5f", - "ingredient_version_id": "491568f3-50a4-56f6-a971-580eaa99715f", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f/versions/491568f3-50a4-56f6-a971-580eaa99715f", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f" - }, - "revision": 6, - "revision_timestamp": "2020-10-29T19:15:41.225634Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "2020-04-21T02:22:00.000000Z", - "source_uri": "https://github.com/openssl/openssl/archive/OpenSSL_1_1_1g.tar.gz", - "sortable_version": [ - "1", - "11", - "0", - "7", - "0" - ], - "version": "1.11.0.7", - "activestate_license_expression": "unknown", - "camel_extras": { - "ppm_pkg": "no" - }, - "dependencies": [ - { - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "feature": "openssl-builder", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/shared/281e4f13142b53657bd154481e18195b2d477572fdffa8ed1065f73ef5a19777/OpenSSL_1_1_1g.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "281e4f13142b53657bd154481e18195b2d477572fdffa8ed1065f73ef5a19777", - "status": "stable", - "provided_features": [ - { - "feature": "openssl", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "shared", - "sortable_version": [ - "1", - "11", - "0", - "7", - "0" - ], - "version": "1.11.0.7" - } - ], - "author_platform_user_id": "8fd0aa9c-0483-4ee7-9197-96c9194c0318", - "comment": "Convert patch content to S3 URI and add condition on camel builder", - "is_stable_revision": true - }, - "patches": [ - { - "creation_timestamp": "2020-10-29T19:15:40.956403Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/df530ca2-a174-4148-a843-c7f34dd13652" - }, - "patch_id": "df530ca2-a174-4148-a843-c7f34dd13652", - "conditions": [ - { - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "content": "s3://platform-sources/patches/6a990e80dad9a75de34a762d621f4b56b93dd8d68e37cf805e820f889726e886.patch", - "description": "Do not attempt to install non-existent .pdb files", - "sequence_number": 1 - } - ], - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "7b9a5527-a6d0-50b9-a6fe-0c5c73d242cd", - "build_scripts": [ - { - "build_script_id": "e9ffe653-3f26-4dfe-b588-2883dd5eeb94", - "creation_timestamp": "2020-08-31T18:13:08.145236Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/e9ffe653-3f26-4dfe-b588-2883dd5eeb94" - }, - "conditions": null, - "language": "perl", - "script": "sqlite3-3.15.2-AS-Makefile.PL" - } - ], - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T17:07:11.488759Z", - "ingredient_id": "380e1f63-4050-59d3-b14d-2b431b5fa2e0", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/380e1f63-4050-59d3-b14d-2b431b5fa2e0" - }, - "name": "sqlite3", - "normalized_name": "sqlite3", - "primary_namespace": "shared", - "description": "SQL Lite Database" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2019-10-01T17:07:11.488759Z", - "ingredient_id": "380e1f63-4050-59d3-b14d-2b431b5fa2e0", - "ingredient_version_id": "54cbf7c2-c87c-51b5-a2cc-72b3b284d68c", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/380e1f63-4050-59d3-b14d-2b431b5fa2e0/versions/54cbf7c2-c87c-51b5-a2cc-72b3b284d68c", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/380e1f63-4050-59d3-b14d-2b431b5fa2e0" - }, - "revision": 3, - "revision_timestamp": "2020-08-31T18:13:08.393927Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "1970-01-01T00:00:00.000000Z", - "source_uri": "https://s3.amazonaws.com/camel-sources/src/vendor-sources/python/sqlite-autoconf-3150200.tar.gz", - "sortable_version": [ - "3", - "15", - "2", - "0" - ], - "version": "3.15.2", - "activestate_license_expression": "unknown", - "camel_extras": { - "skip_test": "yes" - }, - "dependencies": [ - { - "conditions": null, - "description": "All ingredients have a build-time dependency on the camel build system", - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/shared/07b35063b9386865b78226cdaca9a299d938a87aaa8fdc4d73edb0cef30f3149/sqlite-autoconf-3150200.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "07b35063b9386865b78226cdaca9a299d938a87aaa8fdc4d73edb0cef30f3149", - "status": "stable", - "provided_features": [ - { - "feature": "sqlite3", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "shared", - "sortable_version": [ - "3", - "15", - "2", - "0" - ], - "version": "3.15.2" - } - ], - "author_platform_user_id": "ddfb4cc7-4a50-45a5-a6a5-1336b3ad1ef2", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true - }, - "patches": null, - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "06e6c26f-7645-5971-a6ad-277497bdec0c", - "build_scripts": [ - { - "build_script_id": "b5e19267-2ad1-450e-a3d1-a9b7ed1cd344", - "creation_timestamp": "2019-11-26T20:46:06.363894Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/b5e19267-2ad1-450e-a3d1-a9b7ed1cd344" - }, - "conditions": null, - "language": "perl", - "script": "tcl-8.6.8-AS-Makefile.PL" - } - ], - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T17:07:20.968772Z", - "ingredient_id": "040ef024-47fa-5220-aa7e-becd3b44e203", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/040ef024-47fa-5220-aa7e-becd3b44e203" - }, - "name": "tcl", - "normalized_name": "tcl", - "primary_namespace": "shared", - "description": "Toolkit Command Language" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2019-10-01T17:07:20.968772Z", - "ingredient_id": "040ef024-47fa-5220-aa7e-becd3b44e203", - "ingredient_version_id": "b0d9a189-aedb-5461-b872-5e643ac97551", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/040ef024-47fa-5220-aa7e-becd3b44e203/versions/b0d9a189-aedb-5461-b872-5e643ac97551", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/040ef024-47fa-5220-aa7e-becd3b44e203" - }, - "revision": 4, - "revision_timestamp": "2020-09-16T16:53:54.537734Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "1970-01-01T00:00:00.000000Z", - "source_uri": "https://s3.amazonaws.com/camel-sources/src/vendor-sources/tcl/tcl8.6.8-src.tar.gz", - "sortable_version": [ - "8", - "6", - "8", - "0" - ], - "version": "8.6.8", - "activestate_license_expression": "unknown", - "camel_extras": { - "cold_storage_dirs": { - "src": "__SRC__" - }, - "skip_test": "yes" - }, - "dependencies": [ - { - "conditions": null, - "description": "All ingredients have a build-time dependency on the camel build system", - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "AIX", - "namespace": "kernel", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "feature": "zlib", - "namespace": "shared", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/shared/c43cb0c1518ce42b00e7c8f6eaddd5195c53a98f94adc717234a65cbcfd3f96a/tcl8.6.8-src.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "c43cb0c1518ce42b00e7c8f6eaddd5195c53a98f94adc717234a65cbcfd3f96a", - "status": "stable", - "provided_features": [ - { - "feature": "tcl", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "shared", - "sortable_version": [ - "8", - "6", - "8", - "0" - ], - "version": "8.6.8" - } - ], - "author_platform_user_id": "a19a07b9-313a-4e8f-916b-633457d72be8", - "comment": "Convert patch content to S3 URI and add condition on camel builder", - "is_stable_revision": true - }, - "patches": [ - { - "creation_timestamp": "2020-09-16T16:53:54.314313Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/126a4875-aec6-476b-9ff5-83944e0c08b2" - }, - "patch_id": "126a4875-aec6-476b-9ff5-83944e0c08b2", - "conditions": [ - { - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "content": "tcl/8.6.8/0001-Add-lm-for-AIX.patch", - "description": "Add lm for AIX", - "sequence_number": 1 - } - ], - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "060cc2b8-01e4-5afe-8618-c44ccb25a592", - "build_scripts": [ - { - "build_script_id": "efe458cc-4f5f-410a-ba71-ff9ff6514dc7", - "creation_timestamp": "2019-11-21T00:46:19.305262Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/efe458cc-4f5f-410a-ba71-ff9ff6514dc7" - }, - "conditions": null, - "language": "perl", - "script": "tix-8.4.3-AS-Makefile.PL" - } - ], - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "8d5d63b0-e941-59a3-8653-35470bd70056" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "b0d9a189-aedb-5461-b872-5e643ac97551" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T17:07:40.922846Z", - "ingredient_id": "be9d279c-48f3-5233-9250-fc5a61dc8b07", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/be9d279c-48f3-5233-9250-fc5a61dc8b07" - }, - "name": "tix", - "normalized_name": "tix", - "primary_namespace": "shared", - "description": "Tk Interface Extension" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2019-10-01T17:07:40.922846Z", - "ingredient_id": "be9d279c-48f3-5233-9250-fc5a61dc8b07", - "ingredient_version_id": "a61c1442-98a0-576c-b606-3046b22c3413", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/be9d279c-48f3-5233-9250-fc5a61dc8b07/versions/a61c1442-98a0-576c-b606-3046b22c3413", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/be9d279c-48f3-5233-9250-fc5a61dc8b07" - }, - "revision": 4, - "revision_timestamp": "2020-09-16T16:53:55.795504Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "1970-01-01T00:00:00.000000Z", - "source_uri": "https://s3.amazonaws.com/camel-sources/src/vendor-sources/python-core/tix-8.4.3.6-pysvn.tar.gz", - "sortable_version": [ - "8", - "4", - "3", - "6", - "0" - ], - "version": "8.4.3.6", - "activestate_license_expression": "unknown", - "camel_extras": { - "skip_test": "yes" - }, - "dependencies": [ - { - "conditions": null, - "feature": "tcl", - "namespace": "shared", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": null, - "feature": "tk", - "namespace": "shared", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": null, - "description": "All ingredients have a build-time dependency on the camel build system", - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/shared/d6a92d5dd259d51a40d2293e495f34a4925ee7b360b213bb8a64360892065d35/tix-8.4.3.6-pysvn.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "d6a92d5dd259d51a40d2293e495f34a4925ee7b360b213bb8a64360892065d35", - "status": "stable", - "provided_features": [ - { - "feature": "tix", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "shared", - "sortable_version": [ - "8", - "4", - "3", - "6", - "0" - ], - "version": "8.4.3.6" - } - ], - "author_platform_user_id": "a19a07b9-313a-4e8f-916b-633457d72be8", - "comment": "Convert patch content to S3 URI and add condition on camel builder", - "is_stable_revision": true - }, - "patches": [ - { - "creation_timestamp": "2020-09-16T16:53:55.513963Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/ce6ba6d3-4a26-4b60-be52-4db4e2fadf4b" - }, - "patch_id": "ce6ba6d3-4a26-4b60-be52-4db4e2fadf4b", - "conditions": [ - { - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "content": "tix/8.4.3.6/0001-Work-around-deprecated-access-to-Tcl_Interp-result.patch", - "description": "[PATCH 1/2] Work around deprecated access to Tcl_Interp->result", - "sequence_number": 1 - }, - { - "creation_timestamp": "2020-09-16T16:53:55.608640Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/c441dcb9-546a-4cc0-a386-f491539b5e98" - }, - "patch_id": "c441dcb9-546a-4cc0-a386-f491539b5e98", - "conditions": [ - { - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "content": "tix/8.4.3.6/0002-gcc64-fix.patch", - "description": "[PATCH 2/2] gcc64 fix", - "sequence_number": 2 - } - ], - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "2c8a61b6-995c-5e59-8d52-fac8604c3e88", - "build_scripts": [ - { - "build_script_id": "72d59ea6-6a31-4af4-acb8-a4c8cf3c5b2e", - "creation_timestamp": "2020-09-28T21:06:07.393481Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/72d59ea6-6a31-4af4-acb8-a4c8cf3c5b2e" - }, - "conditions": null, - "language": "perl", - "script": "s3://platform-sources/build_scripts/815b591199017b6171f96b1411ca33d87bba4c8241a8325321f6e4eb3f8b6efc/tk-8.6.8-AS-Makefile.PL" - } - ], - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "b0d9a189-aedb-5461-b872-5e643ac97551" - }, - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T17:07:42.897332Z", - "ingredient_id": "5edfd4e0-b20a-5016-8447-635029f35565", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/5edfd4e0-b20a-5016-8447-635029f35565" - }, - "name": "tk", - "normalized_name": "tk", - "primary_namespace": "shared", - "description": "Toolkit GUI Kit" - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2019-10-01T17:07:42.897332Z", - "ingredient_id": "5edfd4e0-b20a-5016-8447-635029f35565", - "ingredient_version_id": "8d5d63b0-e941-59a3-8653-35470bd70056", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/5edfd4e0-b20a-5016-8447-635029f35565/versions/8d5d63b0-e941-59a3-8653-35470bd70056", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/5edfd4e0-b20a-5016-8447-635029f35565" - }, - "revision": 9, - "revision_timestamp": "2020-09-28T21:06:41.439268Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "1970-01-01T00:00:00.000000Z", - "source_uri": "https://s3.amazonaws.com/camel-sources/src/vendor-sources/tcl/tk8.6.8-src.tar.gz", - "sortable_version": [ - "8", - "6", - "8", - "0" - ], - "version": "8.6.8", - "activestate_license_expression": "unknown", - "camel_extras": { - "cold_storage_dirs": { - "src": "__SRC__" - }, - "skip_test": "yes" - }, - "dependencies": [ - { - "conditions": null, - "description": "All ingredients have a build-time dependency on the camel build system", - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": null, - "feature": "tcl", - "namespace": "shared", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [ - "8", - "6", - "8", - "0" - ], - "version": "8.6.8" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/shared/49e7bca08dde95195a27f594f7c850b088be357a7c7096e44e1158c7a5fd7b33/tk8.6.8-src.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "49e7bca08dde95195a27f594f7c850b088be357a7c7096e44e1158c7a5fd7b33", - "status": "stable", - "provided_features": [ - { - "feature": "tk", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "shared", - "sortable_version": [ - "8", - "6", - "8", - "0" - ], - "version": "8.6.8" - } - ], - "author_platform_user_id": "2b378791-a94b-4bf1-9547-692b7e79dfef", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true - }, - "patches": null, - "resolved_requirements": [] - }, - { - "alternatives": [], - "artifact_id": "7b923ae1-94a9-574c-bb9e-a89163f0ccb8", - "build_scripts": [ - { - "build_script_id": "4dba9721-e655-4da3-a414-44c346460ab5", - "creation_timestamp": "2020-10-02T18:32:51.953001Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/4dba9721-e655-4da3-a414-44c346460ab5" - }, - "conditions": null, - "language": "perl", - "script": "zlib-1.2.8-AS-Makefile.PL" - } - ], - "dependencies": [ - { - "dependency_types": [ - "build" - ], - "ingredient_version_id": "c6688f9c-b7bc-5f6e-a1f3-903ae5b8d0bc" - } - ], - "ingredient": { - "creation_timestamp": "2019-10-01T16:58:37.399441Z", - "ingredient_id": "aaa00228-14b4-5dce-9fe2-3370801e423b", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/aaa00228-14b4-5dce-9fe2-3370801e423b" - }, - "name": "zlib", - "normalized_name": "zlib", - "primary_namespace": "shared", - "description": "General purpose data compression library." - }, - "ingredient_options": null, - "ingredient_version": { - "creation_timestamp": "2019-10-01T16:58:37.399441Z", - "ingredient_id": "aaa00228-14b4-5dce-9fe2-3370801e423b", - "ingredient_version_id": "c3b7c513-8be8-56d9-8d30-b19e9c56e393", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/aaa00228-14b4-5dce-9fe2-3370801e423b/versions/c3b7c513-8be8-56d9-8d30-b19e9c56e393", - "ingredient": "https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/aaa00228-14b4-5dce-9fe2-3370801e423b" - }, - "revision": 5, - "revision_timestamp": "2020-10-02T18:32:52.928805Z", - "copyright_text": "To be added.", - "is_binary_only": false, - "license_expression": "Unknown", - "release_timestamp": "2017-01-15T00:00:00.000000Z", - "source_uri": "https://s3.amazonaws.com/camel-sources/src/Libraries/vendor/zlib-1.2.11.tar.gz", - "sortable_version": [ - "1", - "2", - "11", - "0" - ], - "version": "1.2.11", - "activestate_license_expression": "unknown", - "camel_extras": { - "ppm_pkg": "no", - "skip_test": "yes" - }, - "dependencies": [ - { - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "feature": "zlib-builder", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - }, - { - "conditions": [ - { - "feature": "alternative-built-language", - "namespace": "language", - "requirements": [ - { - "comparator": "eq", - "sortable_version": [] - } - ] - } - ], - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ], - "type": "build" - } - ], - "ingredient_options": null, - "is_indemnified": true, - "is_stable_release": true, - "platform_source_uri": "s3://platform-sources/shared/c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1/zlib-1.2.11.tar.gz", - "scanner_license_expression": "unknown", - "source_checksum": "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1", - "status": "stable", - "provided_features": [ - { - "feature": "zlib", - "is_activestate_version": false, - "is_default_provider": true, - "namespace": "shared", - "sortable_version": [ - "1", - "2", - "11", - "0" - ], - "version": "1.2.11" - } - ], - "author_platform_user_id": "a4603881-68af-4a9f-9e4c-6de870d9cbb4", - "comment": "Created prior to addition of revision comments.", - "is_stable_revision": true - }, - "patches": [ - { - "creation_timestamp": "2020-10-02T18:32:52.140755Z", - "links": { - "self": "https://platform.activestate.com/sv/inventory-api-v1/v1/patches/8c1dc792-b9e1-44d8-9dfe-27cd3c9884c6" - }, - "patch_id": "8c1dc792-b9e1-44d8-9dfe-27cd3c9884c6", - "conditions": [ - { - "feature": "camel", - "namespace": "builder", - "requirements": [ - { - "comparator": "gte", - "sortable_version": [ - "0", - "0" - ], - "version": "0" - } - ] - } - ], - "content": "s3://platform-sources/patches/Libraries/patches/zlib-1.2.8-remove-Makefile.patch", - "description": "Remove Makefile, use EU::MM to build", - "sequence_number": 1 - } - ], - "resolved_requirements": [] - } - ], - "solver_version": 1 -} diff --git a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-base.json b/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-base.json deleted file mode 100644 index 52f1bb3f8f..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-base.json +++ /dev/null @@ -1 +0,0 @@ -{"camel_flags":[],"from_recipe_store":true,"image":{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"},"is_indemnified":false,"platform":{"cpu_architecture":{"cpu_architecture_id":"4cdba18d-0851-4925-9ae5-9c8a2987828a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a"},"bit_width":"64","name":"x86","provided_features":[{"feature":"x86 64-bit","is_activestate_version":false,"is_default_provider":true,"namespace":"cpu-architecture","sortable_version":["1","0"],"version":"1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"cpu_extensions":[],"creation_timestamp":"2021-01-15T18:05:36.924Z","display_name":"CentOS 8, Linux 4.18.0, glibc 2.28 x86 64-bit","end_of_support_date":"2025-12-31","images":[{"image_id":"00216735-694e-4ef8-a7d5-7724b9200be0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/00216735-694e-4ef8-a7d5-7724b9200be0"},"name":"docker-registry.activestate.build/activestate/centos-8-build","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","1","0"],"version":"1.1","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"eq","sortable_version":[]}]}],"revision":1,"revision_timestamp":"2021-01-15T18:07:52.645Z"},{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"}],"is_user_visible":true,"kernel":{"kernel_id":"ef737274-fff9-4164-b72b-88067613f822","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822"},"name":"Linux"},"kernel_version":{"kernel_version_id":"61f9365e-03ed-448f-9a24-2b845727e4f5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/61f9365e-03ed-448f-9a24-2b845727e4f5"},"sortable_version":["4","18","0","0"],"version":"4.18.0","provided_features":[{"feature":"Linux","is_activestate_version":false,"is_default_provider":true,"namespace":"kernel","sortable_version":["4","18","0","0"],"version":"4.18.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:04.588Z"},"libc":{"libc_id":"09a2eb42-ad34-4734-a93e-4b97395577df","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df"},"name":"glibc"},"libc_version":{"libc_version_id":"22d234e7-145e-4688-9d05-ee164b4ffa12","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/22d234e7-145e-4688-9d05-ee164b4ffa12"},"sortable_version":["2","28","0"],"version":"2.28","provided_features":[{"feature":"glibc","is_activestate_version":false,"is_default_provider":true,"namespace":"libc","sortable_version":["2","28","0"],"version":"2.28"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:19.136Z"},"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/7c998ec2-7491-4e75-be4d-8885800ef5f2"},"operating_system":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99"},"operating_system_id":"7b3a2dbb-d543-48d6-8390-7e7b63751e99","has_libc":true,"name":"CentOS"},"operating_system_version":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/42cab97b-9d80-407f-89a8-230836868e88"},"operating_system_version_id":"42cab97b-9d80-407f-89a8-230836868e88","sortable_version":["8","0"],"version":"8","provided_features":[{"feature":"CentOS","is_activestate_version":false,"is_default_provider":true,"namespace":"operating-system","sortable_version":["8","0"],"version":"8"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:50.448Z"},"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},"recipe_id":"aa21f7c8-85a7-5cc2-8ee8-f8bd3b342406","recipe_store_timestamp":"2021-02-04T17:59:12.286Z","resolved_ingredients":[{"alternatives":[],"artifact_id":"cf3d86c1-2587-564e-a7b2-0cf109ce263e","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:47:40.385Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"name":"perl-core-builder","normalized_name":"perl-core-builder","primary_namespace":"builder","description":"Builds the core Perl interpreter on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:58:38.567Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31/versions/d5ac8c7c-b025-5418-ab77-a139e60e1d41","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"revision":2,"revision_timestamp":"2020-10-30T17:04:06.702Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-06-25T07:05:14.000Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-core-builder","sortable_version":["1","0","23","0"],"version":"1.0.23","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374/perl-core-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-core-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","23","0"],"version":"1.0.23"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial builder for perl 5.30+","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:32.665Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"name":"perl","normalized_name":"perl","primary_namespace":"language","description":"Practical Extraction and Report Language"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-01-29T18:11:47.039Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206/versions/86005392-bdbf-59bd-a716-70ce7fcd3a66","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"revision":3,"revision_timestamp":"2021-02-03T21:14:56.873Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/S/SH/SHAY/perl-5.32.1.tar.gz","sortable_version":["5","32","1"],"version":"5.32.1","activestate_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/language/03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c/perl-5.32.1.tar.gz","scanner_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","source_checksum":"03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c","status":"stable","provided_features":[{"feature":"alternative-built-language","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1","0"],"version":"5.32.1"},{"feature":"perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1"],"version":"5.32.1"},{"feature":"Amiga::ARexx","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","50","0"],"version":"0.05"},{"feature":"Amiga::Exec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"App::Cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","676","0"],"version":"1.676"},{"feature":"App::Prove","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Archive::Tar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Attribute::Handlers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"AutoLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","740","0"],"version":"5.74"},{"feature":"AutoSplit","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"B","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","820","0"],"version":"1.82"},{"feature":"B::Concise","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.004"},{"feature":"B::Deparse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"B::Op_private","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"B::Showlex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"B::Terse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"B::Xref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Benchmark","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"CPAN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"CPAN::Author","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","500"],"version":"5.5005"},{"feature":"CPAN::CacheMgr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::DeferredCode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::Distribution","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Distroprefs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","0","100"],"version":"6.0001"},{"feature":"CPAN::Distrostatus","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::RecursiveDependency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Exception::blocked_urllist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"CPAN::Exception::yaml_not_installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::yaml_process_error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::FTP::netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"CPAN::FirstTime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","531","500"],"version":"5.5315"},{"feature":"CPAN::HTTP::Client","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HTTP::Credentials","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HandleConfig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","100"],"version":"5.5011"},{"feature":"CPAN::Index","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","120","0"],"version":"2.12"},{"feature":"CPAN::InfoObj","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Kwalify","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Converter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::History","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Merge","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Prereqs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Requirements","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","140","0"],"version":"2.140"},{"feature":"CPAN::Meta::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Validator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","18","0"],"version":"0.018"},{"feature":"CPAN::Mirrors","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Nox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","970","0"],"version":"0.97"},{"feature":"CPAN::Plugin::Specfile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"CPAN::Prompt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Shell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","900"],"version":"5.5009"},{"feature":"CPAN::Tarzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"Carp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Carp::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Class::Struct","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","660","0"],"version":"0.66"},{"feature":"Compress::Raw::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Raw::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"Config::Extensions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"Config::Perl::V","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"Cwd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"DB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"DBM_Filter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"DBM_Filter::compress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::int32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DB_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","855","0"],"version":"1.855"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","176","0"],"version":"2.176"},{"feature":"Devel::PPPort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","620","0"],"version":"3.62"},{"feature":"Devel::Peek","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Devel::SelfStubber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Digest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::MD5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","580","0"],"version":"2.58"},{"feature":"Digest::SHA","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","20","0"],"version":"6.02"},{"feature":"Digest::base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"DirHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Dumpvalue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"DynaLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"Encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","80","0"],"version":"3.08"},{"feature":"Encode::Alias","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"Encode::Byte","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::CJKConstants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::CN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::CN::HZ","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"Encode::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.05"},{"feature":"Encode::EBCDIC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::Encoder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::GSM0338","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"Encode::Guess","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::JP::H2Z","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::JP::JIS7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::KR::2022_KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::MIME::Header","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"Encode::MIME::Header::ISO_2022_JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Encode::MIME::Name","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Encode::Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::TW","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"Encode::Unicode::UTF7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"English","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Errno","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"Exporter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"Exporter::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","250","0"],"version":"0.25"},{"feature":"ExtUtils::Constant::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"ExtUtils::Constant::ProxySubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"ExtUtils::Constant::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"ExtUtils::Constant::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"ExtUtils::Embed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","350","0"],"version":"1.35"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","730","0"],"version":"1.73"},{"feature":"ExtUtils::Miniperl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::ParseXS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::CountLines","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Eval","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::Typemaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::InputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::OutputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Type","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::XSSymSet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.4"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"Fatal","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"Fcntl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","140","0"],"version":"1.14"},{"feature":"File::Basename","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","850","0"],"version":"2.85"},{"feature":"File::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","600"],"version":"1.1006"},{"feature":"File::Copy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","350","0"],"version":"2.35"},{"feature":"File::DosGlob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"File::Fetch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.00"},{"feature":"File::Find","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","380","0"],"version":"1.38"},{"feature":"File::Glob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"File::GlobMapper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"File::Path","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Temp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","231","100"],"version":"0.2311"},{"feature":"File::stat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"FileCache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"FileHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Filter::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","960","0"],"version":"0.96"},{"feature":"Filter::Util::Call","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","600","0"],"version":"1.60"},{"feature":"FindBin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"GDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","520","0"],"version":"2.52"},{"feature":"Getopt::Std","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"HTTP::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","76","0"],"version":"0.076"},{"feature":"Hash::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","240","0"],"version":"0.24"},{"feature":"Hash::Util::FieldHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"I18N::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"I18N::LangTags","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","450","0"],"version":"0.45"},{"feature":"I18N::LangTags::Detect","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"I18N::LangTags::List","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","400","0"],"version":"0.40"},{"feature":"I18N::Langinfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","190","0"],"version":"0.19"},{"feature":"IO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Compress::Adapter::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base::Common","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::RawDeflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Extra","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Dir","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Pipe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Poll","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Seekable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Select","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::INET","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::IP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"IO::Socket::UNIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Uncompress::Adapter::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyUncompress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Gunzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::RawInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Unzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"IPC::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"IPC::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::Open2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"IPC::Open3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"IPC::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SharedMem","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SysV","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Locale::Maketext","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Locale::Maketext::Guts","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::GutsLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","100"],"version":"0.21_01"},{"feature":"MIME::Base64","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"MIME::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"Math::BigFloat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigFloat::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigInt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Calc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::FastCalc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","500","900"],"version":"0.5009"},{"feature":"Math::BigInt::Lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigRat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","261","400"],"version":"0.2614"},{"feature":"Math::Complex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","590","200"],"version":"1.5902"},{"feature":"Math::Trig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","100"],"version":"1.03_01"},{"feature":"Memoize::AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Expire","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireTest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Module::CoreList","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::CoreList::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::Load","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"Module::Load::Conditional","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","740","0"],"version":"0.74"},{"feature":"Module::Loaded","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","80","0"],"version":"0.08"},{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","37"],"version":"1.000037"},{"feature":"Moped::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10","0"],"version":"0.01"},{"feature":"NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"NEXT","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","670","100"],"version":"0.67_01"},{"feature":"Net::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Domain","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::A","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::E","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::I","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::L","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::dataconn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::NNTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::POP3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Ping","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","740","0"],"version":"2.74"},{"feature":"Net::SMTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Time","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::hostent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Net::netent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::protoent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::servent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"O","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"ODBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"OS2::DLL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"OS2::ExtAttr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::PrfDB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"OS2::REXX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Opcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","490","0"],"version":"1.49"},{"feature":"POSIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","970","0"],"version":"1.97"},{"feature":"Params::Check","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","380","0"],"version":"0.38"},{"feature":"Parse::CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"Perl::OSType","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.010"},{"feature":"PerlIO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"PerlIO::encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","0"],"version":"0.28"},{"feature":"PerlIO::mmap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.017"},{"feature":"PerlIO::scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","310","0"],"version":"0.31"},{"feature":"PerlIO::via","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"PerlIO::via::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"Pod::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","740","0"],"version":"1.74"},{"feature":"Pod::Escapes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Pod::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Functions::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Html","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Perldoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","100"],"version":"3.2801"},{"feature":"Pod::Perldoc::BaseTo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::GetOptsOO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToChecker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToMan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToNroff","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToPod","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToRtf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTerm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTk","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToXml","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::BlackBox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsXML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLBatch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLLegacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Pod::Simple::LinkSection","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Methody","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Progress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserEndToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserStartToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserTextToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::RTF","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Search","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::SimpleTree","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TextContent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TiedOutFH","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Transcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeDumb","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeSmart","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XHTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XMLOutStream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Usage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.01"},{"feature":"SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"Safe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","430","0"],"version":"2.43"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Search::Dict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"SelectSaver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"SelfLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.030"},{"feature":"Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","230","0"],"version":"3.23"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Sys::Hostname","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Sys::Syslog","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"TAP::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::ParallelSession","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness::Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Aggregator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Grammar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::IteratorFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Multiplexer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Bailout","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Comment","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Pragma","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Unknown","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::ResultFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Job","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Spinner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Source","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Executable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::RawTAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Reader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Writer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Term::ANSIColor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Term::Cap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Term::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","403","0"],"version":"1.403"},{"feature":"Term::ReadLine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","310","0"],"version":"1.31"},{"feature":"Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","114","0"],"version":"2.114"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Text::Abbrev","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Text::Balanced","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Text::ParseWords","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","300","0"],"version":"3.30"},{"feature":"Text::Tabs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Text::Wrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Thread","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","50","0"],"version":"3.05"},{"feature":"Thread::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","140","0"],"version":"3.14"},{"feature":"Thread::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","130","0"],"version":"2.13"},{"feature":"Tie::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Tie::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Tie::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","200","0"],"version":"4.2"},{"feature":"Tie::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::Hash::NamedCapture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"Tie::Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"Tie::RefHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.40"},{"feature":"Tie::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::StdHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","600","0"],"version":"4.6"},{"feature":"Tie::SubstrHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Time::HiRes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","976","600"],"version":"1.9766"},{"feature":"Time::Local","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Time::Piece","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::Seconds","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::gmtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"Time::localtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Time::tm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"UNIVERSAL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["13","0","0"],"version":"13.0.0"},{"feature":"Unicode::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Big5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::GB2312","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::JISX0208","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Korean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Pinyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Stroke","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Zhuyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Normalize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","280","0"],"version":"1.28"},{"feature":"Unicode::UCD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","750","0"],"version":"0.75"},{"feature":"User::grent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"User::pwent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"VMS::DCLsym","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"VMS::Filespec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"VMS::Stdio","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","450","0"],"version":"2.45"},{"feature":"Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","540","0"],"version":"0.54"},{"feature":"Win32API::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","120","301"],"version":"0.1203_01"},{"feature":"Win32API::File::inc::ExtUtils::Myconst2perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1"},{"feature":"Win32CORE","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"XS::APItest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"XS::Typemap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"XSLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","300","0"],"version":"0.30"},{"feature":"_charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"attributes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"autodie","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::GuardStack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception::system","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::hints","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autouse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"bigint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bignum","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bigrat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"blib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"bytes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"deprecate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"diagnostics","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","370","0"],"version":"1.37"},{"feature":"encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","0","0"],"version":"3.00"},{"feature":"encoding::warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"experimental","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","22","0"],"version":"0.022"},{"feature":"feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"fields","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"filetest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"if","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","900"],"version":"0.0609"},{"feature":"integer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"less","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","650","0"],"version":"0.65"},{"feature":"locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"mro","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","250","0"],"version":"1.25"},{"feature":"ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"open","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"ops","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"overload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"overloading","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","238","0"],"version":"0.238"},{"feature":"perlfaq","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","11","70"],"version":"5.20201107"},{"feature":"re","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"sigtrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"sort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"strict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"subs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"threads","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","260","0"],"version":"2.26"},{"feature":"threads::shared","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","240","0"],"version":"1.24"},{"feature":"vars","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"vmsish","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"warnings::register","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Bump again","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"perl","namespace":"language","version_requirements":[{"comparator":"eq","version":"5.32.1"}]}]}],"solver_version":1} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-failure.json b/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-failure.json deleted file mode 100644 index 5ab4428333..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-failure.json +++ /dev/null @@ -1 +0,0 @@ -{"camel_flags":[],"from_recipe_store":true,"image":{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"},"is_indemnified":false,"platform":{"cpu_architecture":{"cpu_architecture_id":"4cdba18d-0851-4925-9ae5-9c8a2987828a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a"},"bit_width":"64","name":"x86","provided_features":[{"feature":"x86 64-bit","is_activestate_version":false,"is_default_provider":true,"namespace":"cpu-architecture","sortable_version":["1","0"],"version":"1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"cpu_extensions":[],"creation_timestamp":"2021-01-15T18:05:36.924Z","display_name":"CentOS 8, Linux 4.18.0, glibc 2.28 x86 64-bit","end_of_support_date":"2025-12-31","images":[{"image_id":"00216735-694e-4ef8-a7d5-7724b9200be0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/00216735-694e-4ef8-a7d5-7724b9200be0"},"name":"docker-registry.activestate.build/activestate/centos-8-build","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","1","0"],"version":"1.1","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"eq","sortable_version":[]}]}],"revision":1,"revision_timestamp":"2021-01-15T18:07:52.645Z"},{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"}],"is_user_visible":true,"kernel":{"kernel_id":"ef737274-fff9-4164-b72b-88067613f822","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822"},"name":"Linux"},"kernel_version":{"kernel_version_id":"61f9365e-03ed-448f-9a24-2b845727e4f5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/61f9365e-03ed-448f-9a24-2b845727e4f5"},"sortable_version":["4","18","0","0"],"version":"4.18.0","provided_features":[{"feature":"Linux","is_activestate_version":false,"is_default_provider":true,"namespace":"kernel","sortable_version":["4","18","0","0"],"version":"4.18.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:04.588Z"},"libc":{"libc_id":"09a2eb42-ad34-4734-a93e-4b97395577df","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df"},"name":"glibc"},"libc_version":{"libc_version_id":"22d234e7-145e-4688-9d05-ee164b4ffa12","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/22d234e7-145e-4688-9d05-ee164b4ffa12"},"sortable_version":["2","28","0"],"version":"2.28","provided_features":[{"feature":"glibc","is_activestate_version":false,"is_default_provider":true,"namespace":"libc","sortable_version":["2","28","0"],"version":"2.28"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:19.136Z"},"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/7c998ec2-7491-4e75-be4d-8885800ef5f2"},"operating_system":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99"},"operating_system_id":"7b3a2dbb-d543-48d6-8390-7e7b63751e99","has_libc":true,"name":"CentOS"},"operating_system_version":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/42cab97b-9d80-407f-89a8-230836868e88"},"operating_system_version_id":"42cab97b-9d80-407f-89a8-230836868e88","sortable_version":["8","0"],"version":"8","provided_features":[{"feature":"CentOS","is_activestate_version":false,"is_default_provider":true,"namespace":"operating-system","sortable_version":["8","0"],"version":"8"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:50.448Z"},"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},"recipe_id":"ea103bb8-1e74-58ff-8f35-3bc14994d268","recipe_store_timestamp":"2021-02-20T07:49:46.271Z","resolved_ingredients":[{"alternatives":[],"artifact_id":"8c2f830d-1b31-5448-a0a4-aa9d8fcacc4b","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-09-30T17:54:34.749Z","ingredient_id":"888f7a88-fdc8-58f7-8e34-1e28425f3c5a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/888f7a88-fdc8-58f7-8e34-1e28425f3c5a"},"name":"noop-builder","normalized_name":"noop-builder","primary_namespace":"builder","description":"Does the thing - which is nothing - successfully! Hooray!","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:54:34.749Z","ingredient_id":"888f7a88-fdc8-58f7-8e34-1e28425f3c5a","ingredient_version_id":"fcfb451f-d86d-5977-ae48-f27610f7d5ab","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/888f7a88-fdc8-58f7-8e34-1e28425f3c5a/versions/fcfb451f-d86d-5977-ae48-f27610f7d5ab","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/888f7a88-fdc8-58f7-8e34-1e28425f3c5a"},"revision":2,"revision_timestamp":"2020-10-30T17:03:52.420Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-06-25T07:05:14.000Z","source_uri":"https://github.com/ActiveState/platform-builders/tree/noop-builder-1.0.0/builder/noop-builder","sortable_version":["1","0","0","0"],"version":"1.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077/noop-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"noop-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial upload.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"cf3d86c1-2587-564e-a7b2-0cf109ce263e","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:47:40.385Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"name":"perl-core-builder","normalized_name":"perl-core-builder","primary_namespace":"builder","description":"Builds the core Perl interpreter on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:58:38.567Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31/versions/d5ac8c7c-b025-5418-ab77-a139e60e1d41","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"revision":2,"revision_timestamp":"2020-10-30T17:04:06.702Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-06-25T07:05:14.000Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-core-builder","sortable_version":["1","0","23","0"],"version":"1.0.23","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374/perl-core-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-core-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","23","0"],"version":"1.0.23"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial builder for perl 5.30+","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"a1ebbc88-daeb-5588-8086-c99de70eabf7","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"ed446cc4-4e4d-5986-ad77-ed04a3b2e58b"}],"ingredient":{"creation_timestamp":"2020-08-10T23:48:55.390Z","ingredient_id":"196722f9-5600-5d89-9c47-42460922fdb1","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1"},"name":"perl-module-builder","normalized_name":"perl-module-builder","primary_namespace":"builder","description":"Builds Perl modules on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-12-07T20:54:12.006Z","ingredient_id":"196722f9-5600-5d89-9c47-42460922fdb1","ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1/versions/c4164b54-9b8f-55fc-ae5a-cd47c6389687","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1"},"revision":1,"revision_timestamp":"2020-12-07T20:54:12.006Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-12-07T20:23:01.043Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-module-builder","sortable_version":["1","0","36","0"],"version":"1.0.36","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/bb8bb535334fb012df0550a528692f4826893b91b055ac73ffb37dd00322a7b6/perl-module-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"bb8bb535334fb012df0550a528692f4826893b91b055ac73ffb37dd00322a7b6","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-module-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","36","0"],"version":"1.0.36"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Created new version 1.0.36 from 1.0.35.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"f7c88044-fdcd-5023-a0ce-9c4a6fcc2708","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:48:13.169Z","ingredient_id":"4c0fd8d2-5c39-5ecf-958e-325efdea1ef2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2"},"name":"perl-module-lib","normalized_name":"perl-module-lib","primary_namespace":"builder-lib","description":"Builds Perl modules on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-12-07T20:54:42.776Z","ingredient_id":"4c0fd8d2-5c39-5ecf-958e-325efdea1ef2","ingredient_version_id":"ed446cc4-4e4d-5986-ad77-ed04a3b2e58b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2/versions/ed446cc4-4e4d-5986-ad77-ed04a3b2e58b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2"},"revision":2,"revision_timestamp":"2020-12-10T17:22:10.292Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-12-07T20:25:59.954Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-module-lib","sortable_version":["1","0","36","0"],"version":"1.0.36","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/abdb22574b2300f30e98ab9239892f379c0c60bf33634a2b49518bddc730413d/perl-module-lib.tar.gz","scanner_license_expression":"unknown","source_checksum":"abdb22574b2300f30e98ab9239892f379c0c60bf33634a2b49518bddc730413d","status":"stable","provided_features":[{"feature":"perl-module-lib","is_activestate_version":false,"is_default_provider":true,"namespace":"builder-lib","sortable_version":["1","0","36","0"],"version":"1.0.36"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"Created new version 1.0.36 from 1.0.35.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c894fa23-0416-556d-9ca5-fdf9375595bc","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"9c514f0f-5abb-546a-840a-1c97f2010c78"},{"dependency_types":["build"],"ingredient_version_id":"b8f76881-09d4-53fd-8cc6-e595b6d69132"},{"dependency_types":["build"],"ingredient_version_id":"fa7a0c73-1e93-5e08-8f6b-a009e82d7179"},{"dependency_types":["build"],"ingredient_version_id":"fcfb451f-d86d-5977-ae48-f27610f7d5ab"}],"ingredient":{"creation_timestamp":"2020-11-04T00:07:57.937Z","ingredient_id":"bcdc3172-a686-5b04-aace-400fc127d5a4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bcdc3172-a686-5b04-aace-400fc127d5a4"},"name":"Testing","normalized_name":"Testing","primary_namespace":"bundles/perl","description":"Modules and tools for automating testing, test frameworks, etc."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-11-04T00:07:57.937Z","ingredient_id":"bcdc3172-a686-5b04-aace-400fc127d5a4","ingredient_version_id":"21141224-b8b8-565c-8fdf-4ded24fcbd8d","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bcdc3172-a686-5b04-aace-400fc127d5a4/versions/21141224-b8b8-565c-8fdf-4ded24fcbd8d","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bcdc3172-a686-5b04-aace-400fc127d5a4"},"revision":3,"revision_timestamp":"2020-11-04T23:20:03.446Z","copyright_text":"To be added.","is_binary_only":true,"license_expression":"Artistic-2.0","release_timestamp":"2017-12-29T00:00:00.000Z","sortable_version":["1","0","0"],"version":"1.00","activestate_license_expression":"[\"Artistic-2.0\"]","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/internal/3b96afde8004eb24d11bfd06c63048414c1cb6e8abedf0730e5141fc6c16f540/void.tar.gz","scanner_license_expression":"[\"Artistic-2.0\"]","source_checksum":"3b96afde8004eb24d11bfd06c63048414c1cb6e8abedf0730e5141fc6c16f540","status":"stable","provided_features":[{"feature":"Testing","is_activestate_version":false,"is_default_provider":true,"namespace":"bundles/perl","sortable_version":["1","0","0"],"version":"1.00"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"Testing","namespace":"bundles/perl","version_requirements":[{"comparator":"eq","version":"1.00"}]}]},{"alternatives":[],"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:32.665Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"name":"perl","normalized_name":"perl","primary_namespace":"language","description":"Practical Extraction and Report Language"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-01-29T18:11:47.039Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206/versions/86005392-bdbf-59bd-a716-70ce7fcd3a66","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"revision":3,"revision_timestamp":"2021-02-03T21:14:56.873Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/S/SH/SHAY/perl-5.32.1.tar.gz","sortable_version":["5","32","1"],"version":"5.32.1","activestate_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/language/03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c/perl-5.32.1.tar.gz","scanner_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","source_checksum":"03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c","status":"stable","provided_features":[{"feature":"alternative-built-language","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1","0"],"version":"5.32.1"},{"feature":"perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1"],"version":"5.32.1"},{"feature":"Amiga::ARexx","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","50","0"],"version":"0.05"},{"feature":"Amiga::Exec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"App::Cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","676","0"],"version":"1.676"},{"feature":"App::Prove","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Archive::Tar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Attribute::Handlers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"AutoLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","740","0"],"version":"5.74"},{"feature":"AutoSplit","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"B","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","820","0"],"version":"1.82"},{"feature":"B::Concise","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.004"},{"feature":"B::Deparse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"B::Op_private","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"B::Showlex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"B::Terse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"B::Xref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Benchmark","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"CPAN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"CPAN::Author","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","500"],"version":"5.5005"},{"feature":"CPAN::CacheMgr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::DeferredCode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::Distribution","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Distroprefs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","0","100"],"version":"6.0001"},{"feature":"CPAN::Distrostatus","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::RecursiveDependency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Exception::blocked_urllist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"CPAN::Exception::yaml_not_installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::yaml_process_error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::FTP::netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"CPAN::FirstTime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","531","500"],"version":"5.5315"},{"feature":"CPAN::HTTP::Client","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HTTP::Credentials","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HandleConfig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","100"],"version":"5.5011"},{"feature":"CPAN::Index","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","120","0"],"version":"2.12"},{"feature":"CPAN::InfoObj","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Kwalify","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Converter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::History","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Merge","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Prereqs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Requirements","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","140","0"],"version":"2.140"},{"feature":"CPAN::Meta::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Validator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","18","0"],"version":"0.018"},{"feature":"CPAN::Mirrors","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Nox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","970","0"],"version":"0.97"},{"feature":"CPAN::Plugin::Specfile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"CPAN::Prompt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Shell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","900"],"version":"5.5009"},{"feature":"CPAN::Tarzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"Carp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Carp::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Class::Struct","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","660","0"],"version":"0.66"},{"feature":"Compress::Raw::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Raw::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"Config::Extensions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"Config::Perl::V","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"Cwd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"DB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"DBM_Filter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"DBM_Filter::compress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::int32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DB_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","855","0"],"version":"1.855"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","176","0"],"version":"2.176"},{"feature":"Devel::PPPort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","620","0"],"version":"3.62"},{"feature":"Devel::Peek","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Devel::SelfStubber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Digest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::MD5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","580","0"],"version":"2.58"},{"feature":"Digest::SHA","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","20","0"],"version":"6.02"},{"feature":"Digest::base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"DirHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Dumpvalue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"DynaLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"Encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","80","0"],"version":"3.08"},{"feature":"Encode::Alias","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"Encode::Byte","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::CJKConstants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::CN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::CN::HZ","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"Encode::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.05"},{"feature":"Encode::EBCDIC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::Encoder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::GSM0338","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"Encode::Guess","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::JP::H2Z","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::JP::JIS7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::KR::2022_KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::MIME::Header","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"Encode::MIME::Header::ISO_2022_JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Encode::MIME::Name","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Encode::Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::TW","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"Encode::Unicode::UTF7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"English","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Errno","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"Exporter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"Exporter::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","250","0"],"version":"0.25"},{"feature":"ExtUtils::Constant::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"ExtUtils::Constant::ProxySubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"ExtUtils::Constant::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"ExtUtils::Constant::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"ExtUtils::Embed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","350","0"],"version":"1.35"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","730","0"],"version":"1.73"},{"feature":"ExtUtils::Miniperl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::ParseXS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::CountLines","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Eval","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::Typemaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::InputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::OutputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Type","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::XSSymSet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.4"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"Fatal","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"Fcntl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","140","0"],"version":"1.14"},{"feature":"File::Basename","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","850","0"],"version":"2.85"},{"feature":"File::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","600"],"version":"1.1006"},{"feature":"File::Copy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","350","0"],"version":"2.35"},{"feature":"File::DosGlob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"File::Fetch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.00"},{"feature":"File::Find","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","380","0"],"version":"1.38"},{"feature":"File::Glob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"File::GlobMapper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"File::Path","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Temp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","231","100"],"version":"0.2311"},{"feature":"File::stat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"FileCache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"FileHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Filter::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","960","0"],"version":"0.96"},{"feature":"Filter::Util::Call","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","600","0"],"version":"1.60"},{"feature":"FindBin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"GDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","520","0"],"version":"2.52"},{"feature":"Getopt::Std","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"HTTP::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","76","0"],"version":"0.076"},{"feature":"Hash::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","240","0"],"version":"0.24"},{"feature":"Hash::Util::FieldHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"I18N::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"I18N::LangTags","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","450","0"],"version":"0.45"},{"feature":"I18N::LangTags::Detect","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"I18N::LangTags::List","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","400","0"],"version":"0.40"},{"feature":"I18N::Langinfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","190","0"],"version":"0.19"},{"feature":"IO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Compress::Adapter::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base::Common","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::RawDeflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Extra","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Dir","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Pipe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Poll","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Seekable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Select","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::INET","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::IP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"IO::Socket::UNIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Uncompress::Adapter::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyUncompress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Gunzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::RawInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Unzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"IPC::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"IPC::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::Open2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"IPC::Open3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"IPC::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SharedMem","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SysV","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Locale::Maketext","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Locale::Maketext::Guts","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::GutsLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","100"],"version":"0.21_01"},{"feature":"MIME::Base64","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"MIME::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"Math::BigFloat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigFloat::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigInt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Calc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::FastCalc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","500","900"],"version":"0.5009"},{"feature":"Math::BigInt::Lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigRat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","261","400"],"version":"0.2614"},{"feature":"Math::Complex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","590","200"],"version":"1.5902"},{"feature":"Math::Trig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","100"],"version":"1.03_01"},{"feature":"Memoize::AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Expire","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireTest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Module::CoreList","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::CoreList::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::Load","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"Module::Load::Conditional","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","740","0"],"version":"0.74"},{"feature":"Module::Loaded","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","80","0"],"version":"0.08"},{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","37"],"version":"1.000037"},{"feature":"Moped::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10","0"],"version":"0.01"},{"feature":"NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"NEXT","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","670","100"],"version":"0.67_01"},{"feature":"Net::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Domain","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::A","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::E","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::I","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::L","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::dataconn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::NNTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::POP3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Ping","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","740","0"],"version":"2.74"},{"feature":"Net::SMTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Time","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::hostent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Net::netent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::protoent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::servent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"O","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"ODBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"OS2::DLL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"OS2::ExtAttr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::PrfDB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"OS2::REXX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Opcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","490","0"],"version":"1.49"},{"feature":"POSIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","970","0"],"version":"1.97"},{"feature":"Params::Check","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","380","0"],"version":"0.38"},{"feature":"Parse::CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"Perl::OSType","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.010"},{"feature":"PerlIO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"PerlIO::encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","0"],"version":"0.28"},{"feature":"PerlIO::mmap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.017"},{"feature":"PerlIO::scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","310","0"],"version":"0.31"},{"feature":"PerlIO::via","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"PerlIO::via::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"Pod::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","740","0"],"version":"1.74"},{"feature":"Pod::Escapes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Pod::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Functions::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Html","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Perldoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","100"],"version":"3.2801"},{"feature":"Pod::Perldoc::BaseTo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::GetOptsOO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToChecker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToMan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToNroff","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToPod","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToRtf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTerm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTk","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToXml","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::BlackBox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsXML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLBatch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLLegacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Pod::Simple::LinkSection","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Methody","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Progress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserEndToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserStartToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserTextToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::RTF","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Search","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::SimpleTree","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TextContent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TiedOutFH","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Transcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeDumb","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeSmart","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XHTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XMLOutStream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Usage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.01"},{"feature":"SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"Safe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","430","0"],"version":"2.43"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Search::Dict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"SelectSaver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"SelfLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.030"},{"feature":"Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","230","0"],"version":"3.23"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Sys::Hostname","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Sys::Syslog","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"TAP::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::ParallelSession","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness::Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Aggregator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Grammar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::IteratorFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Multiplexer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Bailout","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Comment","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Pragma","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Unknown","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::ResultFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Job","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Spinner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Source","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Executable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::RawTAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Reader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Writer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Term::ANSIColor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Term::Cap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Term::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","403","0"],"version":"1.403"},{"feature":"Term::ReadLine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","310","0"],"version":"1.31"},{"feature":"Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","114","0"],"version":"2.114"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Text::Abbrev","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Text::Balanced","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Text::ParseWords","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","300","0"],"version":"3.30"},{"feature":"Text::Tabs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Text::Wrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Thread","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","50","0"],"version":"3.05"},{"feature":"Thread::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","140","0"],"version":"3.14"},{"feature":"Thread::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","130","0"],"version":"2.13"},{"feature":"Tie::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Tie::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Tie::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","200","0"],"version":"4.2"},{"feature":"Tie::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::Hash::NamedCapture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"Tie::Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"Tie::RefHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.40"},{"feature":"Tie::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::StdHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","600","0"],"version":"4.6"},{"feature":"Tie::SubstrHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Time::HiRes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","976","600"],"version":"1.9766"},{"feature":"Time::Local","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Time::Piece","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::Seconds","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::gmtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"Time::localtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Time::tm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"UNIVERSAL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["13","0","0"],"version":"13.0.0"},{"feature":"Unicode::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Big5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::GB2312","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::JISX0208","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Korean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Pinyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Stroke","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Zhuyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Normalize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","280","0"],"version":"1.28"},{"feature":"Unicode::UCD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","750","0"],"version":"0.75"},{"feature":"User::grent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"User::pwent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"VMS::DCLsym","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"VMS::Filespec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"VMS::Stdio","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","450","0"],"version":"2.45"},{"feature":"Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","540","0"],"version":"0.54"},{"feature":"Win32API::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","120","301"],"version":"0.1203_01"},{"feature":"Win32API::File::inc::ExtUtils::Myconst2perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1"},{"feature":"Win32CORE","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"XS::APItest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"XS::Typemap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"XSLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","300","0"],"version":"0.30"},{"feature":"_charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"attributes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"autodie","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::GuardStack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception::system","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::hints","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autouse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"bigint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bignum","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bigrat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"blib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"bytes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"deprecate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"diagnostics","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","370","0"],"version":"1.37"},{"feature":"encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","0","0"],"version":"3.00"},{"feature":"encoding::warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"experimental","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","22","0"],"version":"0.022"},{"feature":"feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"fields","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"filetest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"if","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","900"],"version":"0.0609"},{"feature":"integer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"less","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","650","0"],"version":"0.65"},{"feature":"locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"mro","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","250","0"],"version":"1.25"},{"feature":"ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"open","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"ops","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"overload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"overloading","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","238","0"],"version":"0.238"},{"feature":"perlfaq","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","11","70"],"version":"5.20201107"},{"feature":"re","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"sigtrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"sort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"strict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"subs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"threads","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","260","0"],"version":"2.26"},{"feature":"threads::shared","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","240","0"],"version":"1.24"},{"feature":"vars","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"vmsish","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"warnings::register","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Bump again","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"perl","namespace":"language","version_requirements":[{"comparator":"eq","version":"5.32.1"}]}]},{"alternatives":[],"artifact_id":"48951744-f839-5031-8cf4-6e82a4be2089","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2020-05-28T03:10:35.310Z","ingredient_id":"15bb23b0-0232-5fb9-b791-3e5a905aa4a7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15bb23b0-0232-5fb9-b791-3e5a905aa4a7"},"name":"Data-UUID","normalized_name":"Data-UUID","primary_namespace":"language/perl","description":"Globally/Universally Unique Identifiers (GUIDs/UUIDs)"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-28T03:10:35.310Z","ingredient_id":"15bb23b0-0232-5fb9-b791-3e5a905aa4a7","ingredient_version_id":"e8527602-630b-57ab-b21f-a185719a6c91","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15bb23b0-0232-5fb9-b791-3e5a905aa4a7/versions/e8527602-630b-57ab-b21f-a185719a6c91","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15bb23b0-0232-5fb9-b791-3e5a905aa4a7"},"revision":6,"revision_timestamp":"2020-10-28T19:35:01.617Z","copyright_text":"TODO","documentation_uri":"https://metacpan.org/release/Ricardo SIGNES 😄/Data-UUID-1.226","is_binary_only":false,"license_expression":"[\"BSD-3-Clause\"]","release_timestamp":"2020-04-13T01:43:57.000Z","source_uri":"https://cpan.metacpan.org/authors/id/R/RJ/RJBS/Data-UUID-1.226.tar.gz","sortable_version":["1","226","0"],"version":"1.226","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/093d57ffa0d411a94bafafae495697db26f5c9d0277198fe3f7cf2be22996453/Data-UUID-1.226.tar.gz","scanner_license_expression":"[\"BSD-3-Clause\"]","source_checksum":"093d57ffa0d411a94bafafae495697db26f5c9d0277198fe3f7cf2be22996453","status":"stable","provided_features":[{"feature":"Data-UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","226","0"],"version":"1.226"},{"feature":"Data::UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","226","0"],"version":"1.226"}],"author_platform_user_id":"a19a07b9-313a-4e8f-916b-633457d72be8","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"0029ae25-8497-5130-8268-1f0fe26ccc77","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:20.957Z","ingredient_id":"c3ce160c-83dc-521f-9f12-116d103c0d5a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c3ce160c-83dc-521f-9f12-116d103c0d5a"},"name":"Importer","normalized_name":"Importer","primary_namespace":"language/perl","description":"Alternative but compatible interface to modules that export symbols."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-17T21:14:23.110Z","ingredient_id":"c3ce160c-83dc-521f-9f12-116d103c0d5a","ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c3ce160c-83dc-521f-9f12-116d103c0d5a/versions/2be11022-8f99-5eff-b80e-77f0fade3d27","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c3ce160c-83dc-521f-9f12-116d103c0d5a"},"revision":2,"revision_timestamp":"2020-11-04T20:14:53.251Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Importer-0.025","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2018-02-19T04:44:43.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Importer-0.025.tar.gz","sortable_version":["0","25","0"],"version":"0.025","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/0745138c487d74033d0cbeb36f06595036dc7e688f1a5dbec9cc2fa799e13946/Importer-0.025.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"0745138c487d74033d0cbeb36f06595036dc7e688f1a5dbec9cc2fa799e13946","status":"stable","provided_features":[{"feature":"Importer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","25","0"],"version":"0.025"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Data Acquisition import run with commit ID 0000000000000000000000000000000000000000 and reason: Could not be determined from the database query","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"6591f01d-939d-5080-bb1a-7816ff4d020b","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2020-07-24T03:05:37.269Z","ingredient_id":"2e19a04a-565b-5140-85d3-d102bb043ea8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2e19a04a-565b-5140-85d3-d102bb043ea8"},"name":"Long-Jump","normalized_name":"Long-Jump","primary_namespace":"language/perl","description":"Mechanism for returning to a specific point from a deeply nested stack."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-07-24T03:05:37.269Z","ingredient_id":"2e19a04a-565b-5140-85d3-d102bb043ea8","ingredient_version_id":"6c89ed56-ef22-541a-bf87-9ff4e10ee371","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2e19a04a-565b-5140-85d3-d102bb043ea8/versions/6c89ed56-ef22-541a-bf87-9ff4e10ee371","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2e19a04a-565b-5140-85d3-d102bb043ea8"},"revision":3,"revision_timestamp":"2020-10-28T19:26:23.384Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Long-Jump-0.000001","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2019-09-29T23:36:56.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Long-Jump-0.000001.tar.gz","sortable_version":["0","0","1"],"version":"0.000001","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/d5d6456d86992b559d8f66fc90960f919292cd3803c13403faac575762c77af4/Long-Jump-0.000001.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"d5d6456d86992b559d8f66fc90960f919292cd3803c13403faac575762c77af4","status":"stable","provided_features":[{"feature":"Long-Jump","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","1"],"version":"0.000001"},{"feature":"Long::Jump","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","1"],"version":"0.000001"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"7c541a6a-4dfd-5135-8b98-2b44b5d1a816","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:52.524Z","ingredient_id":"8967b3df-1d60-5fe5-a9d2-d1506eaee353","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8967b3df-1d60-5fe5-a9d2-d1506eaee353"},"name":"Module-Pluggable","normalized_name":"Module-Pluggable","primary_namespace":"language/perl","description":"automatically give your module the ability to have plugins"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:52.524Z","ingredient_id":"8967b3df-1d60-5fe5-a9d2-d1506eaee353","ingredient_version_id":"0f028feb-10aa-531d-9660-b56c19fb7b43","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8967b3df-1d60-5fe5-a9d2-d1506eaee353/versions/0f028feb-10aa-531d-9660-b56c19fb7b43","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8967b3df-1d60-5fe5-a9d2-d1506eaee353"},"revision":7,"revision_timestamp":"2020-10-28T19:20:35.640Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2015-08-05T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/S/SI/SIMONW/Module-Pluggable-5.2.tar.gz","sortable_version":["5","200","0"],"version":"5.2","activestate_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","camel_extras":{"mm_fullext":"Module/Pluggable"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/b3f2ad45e4fd10b3fb90d912d78d8b795ab295480db56dc64e86b9fa75c5a6df/Module-Pluggable-5.2.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"b3f2ad45e4fd10b3fb90d912d78d8b795ab295480db56dc64e86b9fa75c5a6df","status":"stable","provided_features":[{"feature":"Devel::InnerPackage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","200","0"],"version":"5.2"},{"feature":"Module-Pluggable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","200","0"],"version":"5.2"},{"feature":"Module::Pluggable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","200","0"],"version":"5.2"},{"feature":"Module::Pluggable::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","200","0"],"version":"5.2"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"7f8a7197-b277-5621-a6f3-7f2ef32d871b","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:53:43.175Z","ingredient_id":"419b3d3f-2c08-58dc-b06a-5890d25878ab","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/419b3d3f-2c08-58dc-b06a-5890d25878ab"},"name":"Scope-Guard","normalized_name":"Scope-Guard","primary_namespace":"language/perl","description":"lexically-scoped resource management"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:53:43.175Z","ingredient_id":"419b3d3f-2c08-58dc-b06a-5890d25878ab","ingredient_version_id":"1ff5b410-a933-53c7-b3a1-f11524b53213","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/419b3d3f-2c08-58dc-b06a-5890d25878ab/versions/1ff5b410-a933-53c7-b3a1-f11524b53213","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/419b3d3f-2c08-58dc-b06a-5890d25878ab"},"revision":5,"revision_timestamp":"2020-10-28T19:21:37.794Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2015-07-19T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/C/CH/CHOCOLATE/Scope-Guard-0.21.tar.gz","sortable_version":["0","210","0"],"version":"0.21","activestate_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","camel_extras":{"mm_fullext":"Scope/Guard"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/8c9b1bea5c56448e2c3fadc65d05be9e4690a3823a80f39d2f10fdd8f777d278/Scope-Guard-0.21.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"8c9b1bea5c56448e2c3fadc65d05be9e4690a3823a80f39d2f10fdd8f777d278","status":"stable","provided_features":[{"feature":"Scope-Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","0"],"version":"0.21"},{"feature":"Scope::Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","0"],"version":"0.21"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"29983a5b-49c4-5cf4-a2c5-2490647d6910","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime"],"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:53:51.949Z","ingredient_id":"bd0582e7-a354-5e28-868e-c772965b793f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bd0582e7-a354-5e28-868e-c772965b793f"},"name":"Sub-Info","normalized_name":"Sub-Info","primary_namespace":"language/perl","description":"Tool for inspecting subroutines."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-28T00:53:33.249Z","ingredient_id":"bd0582e7-a354-5e28-868e-c772965b793f","ingredient_version_id":"9e33e514-0b22-504b-8409-6d0bdbf86108","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bd0582e7-a354-5e28-868e-c772965b793f/versions/9e33e514-0b22-504b-8409-6d0bdbf86108","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bd0582e7-a354-5e28-868e-c772965b793f"},"revision":4,"revision_timestamp":"2021-02-16T16:39:17.261Z","copyright_text":"TODO","documentation_uri":"https://metacpan.org/release/Chad Granum/Sub-Info-0.002","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2016-12-24T12:17:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Sub-Info-0.002.tar.gz","sortable_version":["0","2","0"],"version":"0.002","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Sub/Info"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/ea3056d696bdeff21a99d340d5570887d39a8cc47bff23adfc82df6758cdd0ea/Sub-Info-0.002.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"ea3056d696bdeff21a99d340d5570887d39a8cc47bff23adfc82df6758cdd0ea","status":"stable","provided_features":[{"feature":"Sub-Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.002"},{"feature":"Sub::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.002"}],"author_platform_user_id":"8fd0aa9c-0483-4ee7-9197-96c9194c0318","comment":"Add build dependencies for Auto-intstall - Importer","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"4d95557d-2200-5a56-a809-4ea3d3502b20","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime"],"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:02.753Z","ingredient_id":"d8ad5efe-897b-5342-8ad1-f4abbd328ab4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d8ad5efe-897b-5342-8ad1-f4abbd328ab4"},"name":"Term-Table","normalized_name":"Term-Table","primary_namespace":"language/perl","description":"Format a header and rows into a table"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-17T21:15:15.752Z","ingredient_id":"d8ad5efe-897b-5342-8ad1-f4abbd328ab4","ingredient_version_id":"7e483f34-00ad-523a-91be-e9ddf74366a5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d8ad5efe-897b-5342-8ad1-f4abbd328ab4/versions/7e483f34-00ad-523a-91be-e9ddf74366a5","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d8ad5efe-897b-5342-8ad1-f4abbd328ab4"},"revision":3,"revision_timestamp":"2021-02-19T04:13:53.554Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Term-Table-0.015","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2019-11-19T07:59:44.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Term-Table-0.015.tar.gz","sortable_version":["0","15","0"],"version":"0.015","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/d8a18b2801f91f0e5d747147ce786964a76f91d18568652908a3dc06a9b948d5/Term-Table-0.015.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"d8a18b2801f91f0e5d747147ce786964a76f91d18568652908a3dc06a9b948d5","status":"stable","provided_features":[{"feature":"Term-Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::Cell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::CellStack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::LineBreak","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::Spacer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"}],"author_platform_user_id":"8fd0aa9c-0483-4ee7-9197-96c9194c0318","comment":"Data Acquisition import run with commit ID 0000000000000000000000000000000000000000 and reason: Could not be determined from the database query","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"288aa0db-c0e4-55e7-8f67-fc2da409be70","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"1ff5b410-a933-53c7-b3a1-f11524b53213"},{"dependency_types":["runtime"],"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27"},{"dependency_types":["runtime"],"ingredient_version_id":"4bd9f2db-1c09-5a14-82a3-7cb6d966d18c"},{"dependency_types":["runtime"],"ingredient_version_id":"6c89ed56-ef22-541a-bf87-9ff4e10ee371"},{"dependency_types":["runtime"],"ingredient_version_id":"7e483f34-00ad-523a-91be-e9ddf74366a5"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"},{"dependency_types":["runtime"],"ingredient_version_id":"d85188d8-231d-589f-9bdd-fc5667cc2d2f"},{"dependency_types":["runtime"],"ingredient_version_id":"e8527602-630b-57ab-b21f-a185719a6c91"},{"dependency_types":["runtime"],"ingredient_version_id":"ee3bc68e-abb3-58ff-aa9c-60b7412df7e2"},{"dependency_types":["runtime"],"ingredient_version_id":"fa7a0c73-1e93-5e08-8f6b-a009e82d7179"}],"ingredient":{"creation_timestamp":"2020-05-28T03:57:35.831Z","ingredient_id":"7cc539a3-0ee6-5e80-a948-dbd38b3f26db","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7cc539a3-0ee6-5e80-a948-dbd38b3f26db"},"name":"Test2-Harness","normalized_name":"Test2-Harness","primary_namespace":"language/perl","description":"A new and improved test harness with better Test2 integration."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-01-13T02:09:51.439Z","ingredient_id":"7cc539a3-0ee6-5e80-a948-dbd38b3f26db","ingredient_version_id":"9c514f0f-5abb-546a-840a-1c97f2010c78","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7cc539a3-0ee6-5e80-a948-dbd38b3f26db/versions/9c514f0f-5abb-546a-840a-1c97f2010c78","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7cc539a3-0ee6-5e80-a948-dbd38b3f26db"},"revision":2,"revision_timestamp":"2021-02-02T23:55:10.154Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Test2-Harness-1.000042","is_binary_only":false,"license_expression":"Artistic-1.0-Perl, GPL-1.0-or-later","release_timestamp":"2020-11-18T06:47:53.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test2-Harness-1.000042.tar.gz","sortable_version":["1","0","42"],"version":"1.000042","activestate_license_expression":"Artistic-1.0-Perl, GPL-1.0-or-later","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/aaf231a68af1a6ffd6a11188875fcf572e373e43c8285945227b9d687b43db2d/Test2-Harness-1.000042.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"aaf231a68af1a6ffd6a11188875fcf572e373e43c8285945227b9d687b43db2d","status":"stable","provided_features":[{"feature":"App::Yath","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::auditor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::collector","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::failed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::help","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::init","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::projects","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::reload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::replay","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::runner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::spawn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::speedtag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::start","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::stop","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::times","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::watch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::which","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Converting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Option","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Display","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Finder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Logging","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Persist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::PreCommand","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Runner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Workspace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::Git","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::Notify","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::SelfTest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::SysInfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::YathUI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2-Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Formatter::QVF","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Formatter::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Formatter::Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Formatter::Test2::Composer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Auditor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Auditor::TimeTracker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Auditor::Watcher","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Collector","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Collector::JobDir","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Collector::TapParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Finder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::IPC::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Log","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Log::CoverageAggregator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Renderer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Renderer::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::DepTracer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Job","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Preload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Preload::Stage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Preloader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Preloader::Stage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Resource","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Spawn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Spawn::Run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::State","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Settings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Settings::Prefix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::TestFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File::JSON","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File::JSONL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File::Value","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::JSON","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::Term","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Tools::HarnessTester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"}],"author_platform_user_id":"2e044215-1b51-498f-a440-ae0cc11bdd4c","comment":"Fix improper Perl core version","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"282e3768-e12a-51ed-831f-7cbc212ba8bd","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2020-08-04T05:03:47.447Z","ingredient_id":"475ab2a1-ee4c-5337-b9c0-5991daa7d9ad","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/475ab2a1-ee4c-5337-b9c0-5991daa7d9ad"},"name":"Test2-Plugin-MemUsage","normalized_name":"Test2-Plugin-MemUsage","primary_namespace":"language/perl","description":"Collect and display memory usage information."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-08-04T05:03:47.447Z","ingredient_id":"475ab2a1-ee4c-5337-b9c0-5991daa7d9ad","ingredient_version_id":"d85188d8-231d-589f-9bdd-fc5667cc2d2f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/475ab2a1-ee4c-5337-b9c0-5991daa7d9ad/versions/d85188d8-231d-589f-9bdd-fc5667cc2d2f","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/475ab2a1-ee4c-5337-b9c0-5991daa7d9ad"},"revision":3,"revision_timestamp":"2020-10-28T19:33:54.008Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Test2-Plugin-MemUsage-0.002003","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2020-02-26T16:09:51.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test2-Plugin-MemUsage-0.002003.tar.gz","sortable_version":["0","2","3"],"version":"0.002003","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/5e0662d5a823ae081641f5ce82843111eec1831cd31f883a6c6de54afdf87c25/Test2-Plugin-MemUsage-0.002003.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"5e0662d5a823ae081641f5ce82843111eec1831cd31f883a6c6de54afdf87c25","status":"stable","provided_features":[{"feature":"Test2-Plugin-MemUsage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","3"],"version":"0.002003"},{"feature":"Test2::Plugin::MemUsage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","3"],"version":"0.002003"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"5ad88c8a-bc8f-50a0-9f61-74856cd28017","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:23.311Z","ingredient_id":"ad9a26f2-c23b-54b1-ada2-3327ff7fd40d","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ad9a26f2-c23b-54b1-ada2-3327ff7fd40d"},"name":"Test2-Plugin-NoWarnings","normalized_name":"Test2-Plugin-NoWarnings","primary_namespace":"language/perl","description":"Fail if tests warn"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-28T00:53:49.862Z","ingredient_id":"ad9a26f2-c23b-54b1-ada2-3327ff7fd40d","ingredient_version_id":"b8f76881-09d4-53fd-8cc6-e595b6d69132","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ad9a26f2-c23b-54b1-ada2-3327ff7fd40d/versions/b8f76881-09d4-53fd-8cc6-e595b6d69132","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ad9a26f2-c23b-54b1-ada2-3327ff7fd40d"},"revision":3,"revision_timestamp":"2020-10-28T19:31:31.379Z","copyright_text":"TODO","documentation_uri":"https://metacpan.org/release/Dave Rolsky/Test2-Plugin-NoWarnings-0.06","is_binary_only":false,"license_expression":"[\"Artistic-2.0\"]","release_timestamp":"2017-06-04T22:24:22.000Z","source_uri":"https://cpan.metacpan.org/authors/id/D/DR/DROLSKY/Test2-Plugin-NoWarnings-0.06.tar.gz","sortable_version":["0","60","0"],"version":"0.06","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Test2/Plugin/NoWarnings"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/8288c1d934f69a03224598fbb715adc079c0d1609bfbaea6c88682aab1995800/Test2-Plugin-NoWarnings-0.06.tar.gz","scanner_license_expression":"[\"Artistic-2.0\"]","source_checksum":"8288c1d934f69a03224598fbb715adc079c0d1609bfbaea6c88682aab1995800","status":"stable","provided_features":[{"feature":"Test2-Plugin-NoWarnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"Test2::Event::Warning","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"Test2::Plugin::NoWarnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c3e652a7-676e-594f-b87f-93d19122f3f4","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"},{"dependency_types":["runtime"],"ingredient_version_id":"e8527602-630b-57ab-b21f-a185719a6c91"}],"ingredient":{"creation_timestamp":"2020-08-04T05:03:50.581Z","ingredient_id":"cfacafbc-90b3-50d6-a0d3-3320ec24434c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/cfacafbc-90b3-50d6-a0d3-3320ec24434c"},"name":"Test2-Plugin-UUID","normalized_name":"Test2-Plugin-UUID","primary_namespace":"language/perl","description":"Use REAL UUIDs in Test2"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-08-04T05:03:50.581Z","ingredient_id":"cfacafbc-90b3-50d6-a0d3-3320ec24434c","ingredient_version_id":"4bd9f2db-1c09-5a14-82a3-7cb6d966d18c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/cfacafbc-90b3-50d6-a0d3-3320ec24434c/versions/4bd9f2db-1c09-5a14-82a3-7cb6d966d18c","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/cfacafbc-90b3-50d6-a0d3-3320ec24434c"},"revision":3,"revision_timestamp":"2020-10-28T19:24:08.293Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Test2-Plugin-UUID-0.002001","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2019-08-16T22:46:14.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test2-Plugin-UUID-0.002001.tar.gz","sortable_version":["0","2","1"],"version":"0.002001","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/4c6c8d484d7153d8779dc155a992b203095b5c5aa1cfb1ee8bcedcd0601878c9/Test2-Plugin-UUID-0.002001.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"4c6c8d484d7153d8779dc155a992b203095b5c5aa1cfb1ee8bcedcd0601878c9","status":"stable","provided_features":[{"feature":"Test2-Plugin-UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","1"],"version":"0.002001"},{"feature":"Test2::Plugin::UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","1"],"version":"0.002001"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"30dc7965-0a69-5686-831a-e563fa73a98c","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"0f028feb-10aa-531d-9660-b56c19fb7b43"},{"dependency_types":["runtime"],"ingredient_version_id":"1ff5b410-a933-53c7-b3a1-f11524b53213"},{"dependency_types":["build","runtime"],"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27"},{"dependency_types":["runtime"],"ingredient_version_id":"7e483f34-00ad-523a-91be-e9ddf74366a5"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["runtime"],"ingredient_version_id":"9e33e514-0b22-504b-8409-6d0bdbf86108"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:24.108Z","ingredient_id":"9bd2d82e-5607-5b1e-9f58-05d8ce6a171b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9bd2d82e-5607-5b1e-9f58-05d8ce6a171b"},"name":"Test2-Suite","normalized_name":"Test2-Suite","primary_namespace":"language/perl","description":"Distribution with a rich set of tools built upon the Test2 framework."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-17T20:03:44.338Z","ingredient_id":"9bd2d82e-5607-5b1e-9f58-05d8ce6a171b","ingredient_version_id":"fa7a0c73-1e93-5e08-8f6b-a009e82d7179","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9bd2d82e-5607-5b1e-9f58-05d8ce6a171b/versions/fa7a0c73-1e93-5e08-8f6b-a009e82d7179","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9bd2d82e-5607-5b1e-9f58-05d8ce6a171b"},"revision":2,"revision_timestamp":"2021-02-19T04:22:07.305Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Test2-Suite-0.000127","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2019-10-31T11:27:54.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test2-Suite-0.000127.tar.gz","sortable_version":["0","0","127"],"version":"0.000127","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/09443e7c99f9bef2c3f5999b919800db7d265b2c55f177726d3e5a61d8dbe690/Test2-Suite-0.000127.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"09443e7c99f9bef2c3f5999b919800db7d265b2c55f177726d3e5a61d8dbe690","status":"stable","provided_features":[{"feature":"Test2-Suite","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest::Event::Attach","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest::Event::Detach","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Bundle::Extended","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Bundle::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Bundle::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Bag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Bool","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Custom","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::DeepRef","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Delta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::EventMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Float","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Negatable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Number","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::OrderedSubset","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Pattern","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Ref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Set","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::String","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Undef","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Wildcard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::EndToEnd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::Hubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Contributing","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing::Introduction","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing::Migrating","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing::Planning","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing::Todo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::FirstTool","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Nesting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Plugin::TestExit","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Plugin::TestingDone","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Plugin::ToolCompletes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Plugin::ToolStarts","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::TestBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Testing","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Mock","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::BailOnFail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::DieOnFail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::ExitSummary","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::SRand","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::Times","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::UTF8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::AuthorTesting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::EnvVar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::Fork","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::Perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::RealFork","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::Threads","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Suite","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Todo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::AsyncSubtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Basic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Class","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::ClassicCompare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Defer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Exports","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::GenTemp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Grab","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Mock","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Ref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Target","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Grabber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Ref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Stash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Sub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Table::Cell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Table::LineBreak","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Term","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Times","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::V0","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::BlockBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Build","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Runner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Task","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Task::Action","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Task::Group","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"}],"author_platform_user_id":"8fd0aa9c-0483-4ee7-9197-96c9194c0318","comment":"Data Acquisition import run with commit ID 0000000000000000000000000000000000000000 and reason: Could not be determined from the database query","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"3ac7b175-6fc9-569c-bb15-785fe14298a2","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["runtime"],"ingredient_version_id":"bac128cd-1439-5857-b5b5-5633763f78d5"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"},{"dependency_types":["runtime"],"ingredient_version_id":"e41f38b7-11e6-52e8-9f12-eba3533f3055"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:59.206Z","ingredient_id":"378500a3-1420-5d36-9033-97913dba50c4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/378500a3-1420-5d36-9033-97913dba50c4"},"name":"Win32-Console-ANSI","normalized_name":"Win32-Console-ANSI","primary_namespace":"language/perl","description":"Perl extension to emulate ANSI console on Win32 system."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:54:59.206Z","ingredient_id":"378500a3-1420-5d36-9033-97913dba50c4","ingredient_version_id":"e0f207c2-9922-51e3-95cf-e586da39436e","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/378500a3-1420-5d36-9033-97913dba50c4/versions/e0f207c2-9922-51e3-95cf-e586da39436e","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/378500a3-1420-5d36-9033-97913dba50c4"},"revision":8,"revision_timestamp":"2020-10-28T19:34:30.379Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-10-24T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/J/JL/JLMOREL/Win32-Console-ANSI-1.11.tar.gz","sortable_version":["1","110","0"],"version":"1.11","activestate_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","camel_extras":{"mm_fullext":"Win32/Console/ANSI","require_os":["MSWin32","MSWin32"]},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/18b547c7548e1de70965a600bdf37ba27fe1ee5913ca1374a576033d545c60c4/Win32-Console-ANSI-1.11.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"18b547c7548e1de70965a600bdf37ba27fe1ee5913ca1374a576033d545c60c4","status":"stable","provided_features":[{"feature":"Win32-Console-ANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"Win32::Console::ANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"}],"author_platform_user_id":"a19a07b9-313a-4e8f-916b-633457d72be8","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"Win32-Console-ANSI","namespace":"language/perl","version_requirements":null}]},{"alternatives":[],"artifact_id":"d806994e-1154-5b81-9104-b8d4d4dd72a4","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:55:05.526Z","ingredient_id":"af49cff4-b49e-5283-b849-26aa66f7e082","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/af49cff4-b49e-5283-b849-26aa66f7e082"},"name":"Win32-Pipe","normalized_name":"Win32-Pipe","primary_namespace":"language/perl","description":"Win32 Named Pipe"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-28T00:54:06.553Z","ingredient_id":"af49cff4-b49e-5283-b849-26aa66f7e082","ingredient_version_id":"bac128cd-1439-5857-b5b5-5633763f78d5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/af49cff4-b49e-5283-b849-26aa66f7e082/versions/bac128cd-1439-5857-b5b5-5633763f78d5","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/af49cff4-b49e-5283-b849-26aa66f7e082"},"revision":4,"revision_timestamp":"2020-11-03T18:12:27.020Z","copyright_text":"TODO","documentation_uri":"https://metacpan.org/release/Jan Dubois/Win32-Pipe-0.025","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2013-12-05T09:18:51.000Z","source_uri":"https://cpan.metacpan.org/authors/id/J/JD/JDB/Win32-Pipe-0.025.tar.gz","sortable_version":["0","25","0"],"version":"0.025","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Win32/Pipe","require_os":["MSWin32","MSWin32"]},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/63bd454c4e29a856b28a764cf8f7ca0873b060045f394c5a3583111ac49da252/Win32-Pipe-0.025.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"63bd454c4e29a856b28a764cf8f7ca0873b060045f394c5a3583111ac49da252","status":"stable","provided_features":[{"feature":"Win32-Pipe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","25","0"],"version":"0.025"},{"feature":"Win32::Pipe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","25","0"],"version":"0.025"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":[{"creation_timestamp":"2020-11-03T18:12:26.459Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/4cc8004c-0c2b-4bdc-b431-0504b9f8b93b"},"patch_id":"4cc8004c-0c2b-4bdc-b431-0504b9f8b93b","conditions":null,"content":"s3://platform-sources/patches/b791da67a771fa2bc3957ca75d089edee1a8cfc426416a527067a05a34866e49.patch","description":"Win32-Pipe ~ In the CPipe class, szError is defined as an array of strings\n(LPSTR szError[ERROR_TEXT_SIZE]) but is used everywhere as a string\nof length ERROR_TEXT_SIZE, being explicitly cast to char * in a\nnumber of places. Newer MinGW GCC versions catch this when an\nattempt is made to null terminate the string (array of strings)\nwith a 0 character which is a char, not a char * and quite\nrightly call out the illegal implied cast.\n\nChange szError to be of type CHAR[] to reflect the actual usage.","sequence_number":1}],"resolved_requirements":[]},{"alternatives":[],"artifact_id":"08f7470e-bd8b-5ef1-a94d-a04960d355eb","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:55:05.914Z","ingredient_id":"1abb3432-3102-5dac-9dd7-cc34c7978b7f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/1abb3432-3102-5dac-9dd7-cc34c7978b7f"},"name":"Win32-Process","normalized_name":"Win32-Process","primary_namespace":"language/perl","description":"Create and manipulate processes"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:55:05.914Z","ingredient_id":"1abb3432-3102-5dac-9dd7-cc34c7978b7f","ingredient_version_id":"e41f38b7-11e6-52e8-9f12-eba3533f3055","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/1abb3432-3102-5dac-9dd7-cc34c7978b7f/versions/e41f38b7-11e6-52e8-9f12-eba3533f3055","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/1abb3432-3102-5dac-9dd7-cc34c7978b7f"},"revision":5,"revision_timestamp":"2020-10-28T19:34:40.682Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-Perl OR GPL-1.0-or-later","release_timestamp":"2013-12-11T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/J/JD/JDB/Win32-Process-0.16.tar.gz","sortable_version":["0","160","0"],"version":"0.16","activestate_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","camel_extras":{"mm_fullext":"Win32/Process","require_os":["MSWin32","MSWin32"]},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/d9030c50aff11b63f6b3e482b9d81a68472812eddc346e3273c4996814ece6e3/Win32-Process-0.16.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"d9030c50aff11b63f6b3e482b9d81a68472812eddc346e3273c4996814ece6e3","status":"stable","provided_features":[{"feature":"Win32-Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","160","0"],"version":"0.16"},{"feature":"Win32::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","160","0"],"version":"0.16"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c1e8c6c4-ea11-55a4-b415-97da2d32121e","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2020-08-04T03:41:54.942Z","ingredient_id":"d467d24f-854c-5970-acac-acda9cb97d15","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d467d24f-854c-5970-acac-acda9cb97d15"},"name":"goto-file","normalized_name":"goto-file","primary_namespace":"language/perl","description":"Stop parsing the current file and move on to a different one.","website":"https://github.com/exodist/goto-file"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-08-04T03:41:54.942Z","ingredient_id":"d467d24f-854c-5970-acac-acda9cb97d15","ingredient_version_id":"ee3bc68e-abb3-58ff-aa9c-60b7412df7e2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d467d24f-854c-5970-acac-acda9cb97d15/versions/ee3bc68e-abb3-58ff-aa9c-60b7412df7e2","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d467d24f-854c-5970-acac-acda9cb97d15"},"revision":3,"revision_timestamp":"2020-10-28T19:35:27.454Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/goto-file-0.005","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2017-10-24T15:33:30.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/goto-file-0.005.tar.gz","sortable_version":["0","5","0"],"version":"0.005","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/c6cdd5ee4a6cdcbdbf314d92a4f9985dbcdf9e4258048cae76125c052aa31f77/goto-file-0.005.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"c6cdd5ee4a6cdcbdbf314d92a4f9985dbcdf9e4258048cae76125c052aa31f77","status":"stable","provided_features":[{"feature":"goto-file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","5","0"],"version":"0.005"},{"feature":"goto::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","5","0"],"version":"0.005"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]}],"solver_version":1} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-bundle.json b/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-bundle.json deleted file mode 100644 index d181ba904e..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-bundle.json +++ /dev/null @@ -1 +0,0 @@ -{"camel_flags":[],"from_recipe_store":true,"image":{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"},"is_indemnified":false,"platform":{"cpu_architecture":{"cpu_architecture_id":"4cdba18d-0851-4925-9ae5-9c8a2987828a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a"},"bit_width":"64","name":"x86","provided_features":[{"feature":"x86 64-bit","is_activestate_version":false,"is_default_provider":true,"namespace":"cpu-architecture","sortable_version":["1","0"],"version":"1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"cpu_extensions":[],"creation_timestamp":"2021-01-15T18:05:36.924Z","display_name":"CentOS 8, Linux 4.18.0, glibc 2.28 x86 64-bit","end_of_support_date":"2025-12-31","images":[{"image_id":"00216735-694e-4ef8-a7d5-7724b9200be0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/00216735-694e-4ef8-a7d5-7724b9200be0"},"name":"docker-registry.activestate.build/activestate/centos-8-build","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","1","0"],"version":"1.1","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"eq","sortable_version":[]}]}],"revision":1,"revision_timestamp":"2021-01-15T18:07:52.645Z"},{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"}],"is_user_visible":true,"kernel":{"kernel_id":"ef737274-fff9-4164-b72b-88067613f822","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822"},"name":"Linux"},"kernel_version":{"kernel_version_id":"61f9365e-03ed-448f-9a24-2b845727e4f5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/61f9365e-03ed-448f-9a24-2b845727e4f5"},"sortable_version":["4","18","0","0"],"version":"4.18.0","provided_features":[{"feature":"Linux","is_activestate_version":false,"is_default_provider":true,"namespace":"kernel","sortable_version":["4","18","0","0"],"version":"4.18.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:04.588Z"},"libc":{"libc_id":"09a2eb42-ad34-4734-a93e-4b97395577df","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df"},"name":"glibc"},"libc_version":{"libc_version_id":"22d234e7-145e-4688-9d05-ee164b4ffa12","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/22d234e7-145e-4688-9d05-ee164b4ffa12"},"sortable_version":["2","28","0"],"version":"2.28","provided_features":[{"feature":"glibc","is_activestate_version":false,"is_default_provider":true,"namespace":"libc","sortable_version":["2","28","0"],"version":"2.28"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:19.136Z"},"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/7c998ec2-7491-4e75-be4d-8885800ef5f2"},"operating_system":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99"},"operating_system_id":"7b3a2dbb-d543-48d6-8390-7e7b63751e99","has_libc":true,"name":"CentOS"},"operating_system_version":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/42cab97b-9d80-407f-89a8-230836868e88"},"operating_system_version_id":"42cab97b-9d80-407f-89a8-230836868e88","sortable_version":["8","0"],"version":"8","provided_features":[{"feature":"CentOS","is_activestate_version":false,"is_default_provider":true,"namespace":"operating-system","sortable_version":["8","0"],"version":"8"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:50.448Z"},"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},"recipe_id":"410f6ec8-2e41-5085-9ffe-b6860b7f60d3","recipe_store_timestamp":"2021-02-20T07:48:45.559Z","resolved_ingredients":[{"alternatives":[],"artifact_id":"8c2f830d-1b31-5448-a0a4-aa9d8fcacc4b","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-09-30T17:54:34.749Z","ingredient_id":"888f7a88-fdc8-58f7-8e34-1e28425f3c5a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/888f7a88-fdc8-58f7-8e34-1e28425f3c5a"},"name":"noop-builder","normalized_name":"noop-builder","primary_namespace":"builder","description":"Does the thing - which is nothing - successfully! Hooray!","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:54:34.749Z","ingredient_id":"888f7a88-fdc8-58f7-8e34-1e28425f3c5a","ingredient_version_id":"fcfb451f-d86d-5977-ae48-f27610f7d5ab","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/888f7a88-fdc8-58f7-8e34-1e28425f3c5a/versions/fcfb451f-d86d-5977-ae48-f27610f7d5ab","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/888f7a88-fdc8-58f7-8e34-1e28425f3c5a"},"revision":2,"revision_timestamp":"2020-10-30T17:03:52.420Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-06-25T07:05:14.000Z","source_uri":"https://github.com/ActiveState/platform-builders/tree/noop-builder-1.0.0/builder/noop-builder","sortable_version":["1","0","0","0"],"version":"1.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077/noop-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"noop-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial upload.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"cf3d86c1-2587-564e-a7b2-0cf109ce263e","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:47:40.385Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"name":"perl-core-builder","normalized_name":"perl-core-builder","primary_namespace":"builder","description":"Builds the core Perl interpreter on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:58:38.567Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31/versions/d5ac8c7c-b025-5418-ab77-a139e60e1d41","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"revision":2,"revision_timestamp":"2020-10-30T17:04:06.702Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-06-25T07:05:14.000Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-core-builder","sortable_version":["1","0","23","0"],"version":"1.0.23","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374/perl-core-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-core-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","23","0"],"version":"1.0.23"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial builder for perl 5.30+","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"a1ebbc88-daeb-5588-8086-c99de70eabf7","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"ed446cc4-4e4d-5986-ad77-ed04a3b2e58b"}],"ingredient":{"creation_timestamp":"2020-08-10T23:48:55.390Z","ingredient_id":"196722f9-5600-5d89-9c47-42460922fdb1","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1"},"name":"perl-module-builder","normalized_name":"perl-module-builder","primary_namespace":"builder","description":"Builds Perl modules on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-12-07T20:54:12.006Z","ingredient_id":"196722f9-5600-5d89-9c47-42460922fdb1","ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1/versions/c4164b54-9b8f-55fc-ae5a-cd47c6389687","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1"},"revision":1,"revision_timestamp":"2020-12-07T20:54:12.006Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-12-07T20:23:01.043Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-module-builder","sortable_version":["1","0","36","0"],"version":"1.0.36","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/bb8bb535334fb012df0550a528692f4826893b91b055ac73ffb37dd00322a7b6/perl-module-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"bb8bb535334fb012df0550a528692f4826893b91b055ac73ffb37dd00322a7b6","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-module-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","36","0"],"version":"1.0.36"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Created new version 1.0.36 from 1.0.35.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"f7c88044-fdcd-5023-a0ce-9c4a6fcc2708","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:48:13.169Z","ingredient_id":"4c0fd8d2-5c39-5ecf-958e-325efdea1ef2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2"},"name":"perl-module-lib","normalized_name":"perl-module-lib","primary_namespace":"builder-lib","description":"Builds Perl modules on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-12-07T20:54:42.776Z","ingredient_id":"4c0fd8d2-5c39-5ecf-958e-325efdea1ef2","ingredient_version_id":"ed446cc4-4e4d-5986-ad77-ed04a3b2e58b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2/versions/ed446cc4-4e4d-5986-ad77-ed04a3b2e58b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2"},"revision":2,"revision_timestamp":"2020-12-10T17:22:10.292Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-12-07T20:25:59.954Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-module-lib","sortable_version":["1","0","36","0"],"version":"1.0.36","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/abdb22574b2300f30e98ab9239892f379c0c60bf33634a2b49518bddc730413d/perl-module-lib.tar.gz","scanner_license_expression":"unknown","source_checksum":"abdb22574b2300f30e98ab9239892f379c0c60bf33634a2b49518bddc730413d","status":"stable","provided_features":[{"feature":"perl-module-lib","is_activestate_version":false,"is_default_provider":true,"namespace":"builder-lib","sortable_version":["1","0","36","0"],"version":"1.0.36"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"Created new version 1.0.36 from 1.0.35.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c894fa23-0416-556d-9ca5-fdf9375595bc","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"9c514f0f-5abb-546a-840a-1c97f2010c78"},{"dependency_types":["build"],"ingredient_version_id":"b8f76881-09d4-53fd-8cc6-e595b6d69132"},{"dependency_types":["build"],"ingredient_version_id":"fa7a0c73-1e93-5e08-8f6b-a009e82d7179"},{"dependency_types":["build"],"ingredient_version_id":"fcfb451f-d86d-5977-ae48-f27610f7d5ab"}],"ingredient":{"creation_timestamp":"2020-11-04T00:07:57.937Z","ingredient_id":"bcdc3172-a686-5b04-aace-400fc127d5a4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bcdc3172-a686-5b04-aace-400fc127d5a4"},"name":"Testing","normalized_name":"Testing","primary_namespace":"bundles/perl","description":"Modules and tools for automating testing, test frameworks, etc."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-11-04T00:07:57.937Z","ingredient_id":"bcdc3172-a686-5b04-aace-400fc127d5a4","ingredient_version_id":"21141224-b8b8-565c-8fdf-4ded24fcbd8d","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bcdc3172-a686-5b04-aace-400fc127d5a4/versions/21141224-b8b8-565c-8fdf-4ded24fcbd8d","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bcdc3172-a686-5b04-aace-400fc127d5a4"},"revision":3,"revision_timestamp":"2020-11-04T23:20:03.446Z","copyright_text":"To be added.","is_binary_only":true,"license_expression":"Artistic-2.0","release_timestamp":"2017-12-29T00:00:00.000Z","sortable_version":["1","0","0"],"version":"1.00","activestate_license_expression":"[\"Artistic-2.0\"]","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/internal/3b96afde8004eb24d11bfd06c63048414c1cb6e8abedf0730e5141fc6c16f540/void.tar.gz","scanner_license_expression":"[\"Artistic-2.0\"]","source_checksum":"3b96afde8004eb24d11bfd06c63048414c1cb6e8abedf0730e5141fc6c16f540","status":"stable","provided_features":[{"feature":"Testing","is_activestate_version":false,"is_default_provider":true,"namespace":"bundles/perl","sortable_version":["1","0","0"],"version":"1.00"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"Testing","namespace":"bundles/perl","version_requirements":[{"comparator":"eq","version":"1.00"}]}]},{"alternatives":[],"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:32.665Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"name":"perl","normalized_name":"perl","primary_namespace":"language","description":"Practical Extraction and Report Language"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-01-29T18:11:47.039Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206/versions/86005392-bdbf-59bd-a716-70ce7fcd3a66","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"revision":3,"revision_timestamp":"2021-02-03T21:14:56.873Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/S/SH/SHAY/perl-5.32.1.tar.gz","sortable_version":["5","32","1"],"version":"5.32.1","activestate_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/language/03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c/perl-5.32.1.tar.gz","scanner_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","source_checksum":"03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c","status":"stable","provided_features":[{"feature":"alternative-built-language","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1","0"],"version":"5.32.1"},{"feature":"perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1"],"version":"5.32.1"},{"feature":"Amiga::ARexx","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","50","0"],"version":"0.05"},{"feature":"Amiga::Exec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"App::Cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","676","0"],"version":"1.676"},{"feature":"App::Prove","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Archive::Tar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Attribute::Handlers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"AutoLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","740","0"],"version":"5.74"},{"feature":"AutoSplit","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"B","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","820","0"],"version":"1.82"},{"feature":"B::Concise","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.004"},{"feature":"B::Deparse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"B::Op_private","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"B::Showlex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"B::Terse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"B::Xref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Benchmark","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"CPAN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"CPAN::Author","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","500"],"version":"5.5005"},{"feature":"CPAN::CacheMgr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::DeferredCode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::Distribution","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Distroprefs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","0","100"],"version":"6.0001"},{"feature":"CPAN::Distrostatus","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::RecursiveDependency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Exception::blocked_urllist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"CPAN::Exception::yaml_not_installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::yaml_process_error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::FTP::netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"CPAN::FirstTime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","531","500"],"version":"5.5315"},{"feature":"CPAN::HTTP::Client","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HTTP::Credentials","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HandleConfig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","100"],"version":"5.5011"},{"feature":"CPAN::Index","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","120","0"],"version":"2.12"},{"feature":"CPAN::InfoObj","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Kwalify","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Converter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::History","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Merge","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Prereqs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Requirements","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","140","0"],"version":"2.140"},{"feature":"CPAN::Meta::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Validator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","18","0"],"version":"0.018"},{"feature":"CPAN::Mirrors","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Nox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","970","0"],"version":"0.97"},{"feature":"CPAN::Plugin::Specfile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"CPAN::Prompt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Shell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","900"],"version":"5.5009"},{"feature":"CPAN::Tarzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"Carp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Carp::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Class::Struct","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","660","0"],"version":"0.66"},{"feature":"Compress::Raw::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Raw::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"Config::Extensions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"Config::Perl::V","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"Cwd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"DB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"DBM_Filter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"DBM_Filter::compress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::int32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DB_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","855","0"],"version":"1.855"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","176","0"],"version":"2.176"},{"feature":"Devel::PPPort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","620","0"],"version":"3.62"},{"feature":"Devel::Peek","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Devel::SelfStubber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Digest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::MD5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","580","0"],"version":"2.58"},{"feature":"Digest::SHA","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","20","0"],"version":"6.02"},{"feature":"Digest::base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"DirHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Dumpvalue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"DynaLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"Encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","80","0"],"version":"3.08"},{"feature":"Encode::Alias","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"Encode::Byte","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::CJKConstants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::CN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::CN::HZ","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"Encode::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.05"},{"feature":"Encode::EBCDIC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::Encoder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::GSM0338","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"Encode::Guess","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::JP::H2Z","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::JP::JIS7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::KR::2022_KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::MIME::Header","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"Encode::MIME::Header::ISO_2022_JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Encode::MIME::Name","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Encode::Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::TW","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"Encode::Unicode::UTF7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"English","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Errno","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"Exporter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"Exporter::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","250","0"],"version":"0.25"},{"feature":"ExtUtils::Constant::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"ExtUtils::Constant::ProxySubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"ExtUtils::Constant::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"ExtUtils::Constant::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"ExtUtils::Embed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","350","0"],"version":"1.35"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","730","0"],"version":"1.73"},{"feature":"ExtUtils::Miniperl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::ParseXS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::CountLines","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Eval","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::Typemaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::InputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::OutputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Type","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::XSSymSet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.4"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"Fatal","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"Fcntl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","140","0"],"version":"1.14"},{"feature":"File::Basename","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","850","0"],"version":"2.85"},{"feature":"File::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","600"],"version":"1.1006"},{"feature":"File::Copy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","350","0"],"version":"2.35"},{"feature":"File::DosGlob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"File::Fetch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.00"},{"feature":"File::Find","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","380","0"],"version":"1.38"},{"feature":"File::Glob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"File::GlobMapper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"File::Path","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Temp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","231","100"],"version":"0.2311"},{"feature":"File::stat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"FileCache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"FileHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Filter::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","960","0"],"version":"0.96"},{"feature":"Filter::Util::Call","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","600","0"],"version":"1.60"},{"feature":"FindBin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"GDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","520","0"],"version":"2.52"},{"feature":"Getopt::Std","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"HTTP::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","76","0"],"version":"0.076"},{"feature":"Hash::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","240","0"],"version":"0.24"},{"feature":"Hash::Util::FieldHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"I18N::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"I18N::LangTags","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","450","0"],"version":"0.45"},{"feature":"I18N::LangTags::Detect","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"I18N::LangTags::List","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","400","0"],"version":"0.40"},{"feature":"I18N::Langinfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","190","0"],"version":"0.19"},{"feature":"IO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Compress::Adapter::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base::Common","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::RawDeflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Extra","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Dir","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Pipe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Poll","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Seekable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Select","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::INET","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::IP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"IO::Socket::UNIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Uncompress::Adapter::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyUncompress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Gunzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::RawInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Unzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"IPC::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"IPC::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::Open2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"IPC::Open3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"IPC::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SharedMem","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SysV","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Locale::Maketext","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Locale::Maketext::Guts","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::GutsLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","100"],"version":"0.21_01"},{"feature":"MIME::Base64","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"MIME::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"Math::BigFloat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigFloat::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigInt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Calc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::FastCalc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","500","900"],"version":"0.5009"},{"feature":"Math::BigInt::Lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigRat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","261","400"],"version":"0.2614"},{"feature":"Math::Complex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","590","200"],"version":"1.5902"},{"feature":"Math::Trig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","100"],"version":"1.03_01"},{"feature":"Memoize::AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Expire","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireTest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Module::CoreList","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::CoreList::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::Load","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"Module::Load::Conditional","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","740","0"],"version":"0.74"},{"feature":"Module::Loaded","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","80","0"],"version":"0.08"},{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","37"],"version":"1.000037"},{"feature":"Moped::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10","0"],"version":"0.01"},{"feature":"NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"NEXT","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","670","100"],"version":"0.67_01"},{"feature":"Net::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Domain","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::A","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::E","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::I","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::L","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::dataconn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::NNTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::POP3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Ping","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","740","0"],"version":"2.74"},{"feature":"Net::SMTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Time","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::hostent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Net::netent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::protoent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::servent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"O","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"ODBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"OS2::DLL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"OS2::ExtAttr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::PrfDB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"OS2::REXX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Opcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","490","0"],"version":"1.49"},{"feature":"POSIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","970","0"],"version":"1.97"},{"feature":"Params::Check","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","380","0"],"version":"0.38"},{"feature":"Parse::CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"Perl::OSType","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.010"},{"feature":"PerlIO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"PerlIO::encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","0"],"version":"0.28"},{"feature":"PerlIO::mmap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.017"},{"feature":"PerlIO::scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","310","0"],"version":"0.31"},{"feature":"PerlIO::via","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"PerlIO::via::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"Pod::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","740","0"],"version":"1.74"},{"feature":"Pod::Escapes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Pod::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Functions::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Html","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Perldoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","100"],"version":"3.2801"},{"feature":"Pod::Perldoc::BaseTo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::GetOptsOO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToChecker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToMan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToNroff","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToPod","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToRtf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTerm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTk","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToXml","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::BlackBox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsXML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLBatch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLLegacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Pod::Simple::LinkSection","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Methody","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Progress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserEndToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserStartToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserTextToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::RTF","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Search","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::SimpleTree","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TextContent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TiedOutFH","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Transcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeDumb","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeSmart","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XHTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XMLOutStream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Usage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.01"},{"feature":"SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"Safe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","430","0"],"version":"2.43"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Search::Dict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"SelectSaver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"SelfLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.030"},{"feature":"Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","230","0"],"version":"3.23"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Sys::Hostname","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Sys::Syslog","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"TAP::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::ParallelSession","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness::Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Aggregator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Grammar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::IteratorFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Multiplexer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Bailout","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Comment","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Pragma","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Unknown","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::ResultFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Job","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Spinner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Source","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Executable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::RawTAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Reader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Writer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Term::ANSIColor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Term::Cap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Term::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","403","0"],"version":"1.403"},{"feature":"Term::ReadLine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","310","0"],"version":"1.31"},{"feature":"Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","114","0"],"version":"2.114"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Text::Abbrev","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Text::Balanced","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Text::ParseWords","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","300","0"],"version":"3.30"},{"feature":"Text::Tabs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Text::Wrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Thread","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","50","0"],"version":"3.05"},{"feature":"Thread::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","140","0"],"version":"3.14"},{"feature":"Thread::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","130","0"],"version":"2.13"},{"feature":"Tie::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Tie::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Tie::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","200","0"],"version":"4.2"},{"feature":"Tie::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::Hash::NamedCapture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"Tie::Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"Tie::RefHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.40"},{"feature":"Tie::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::StdHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","600","0"],"version":"4.6"},{"feature":"Tie::SubstrHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Time::HiRes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","976","600"],"version":"1.9766"},{"feature":"Time::Local","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Time::Piece","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::Seconds","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::gmtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"Time::localtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Time::tm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"UNIVERSAL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["13","0","0"],"version":"13.0.0"},{"feature":"Unicode::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Big5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::GB2312","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::JISX0208","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Korean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Pinyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Stroke","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Zhuyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Normalize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","280","0"],"version":"1.28"},{"feature":"Unicode::UCD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","750","0"],"version":"0.75"},{"feature":"User::grent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"User::pwent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"VMS::DCLsym","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"VMS::Filespec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"VMS::Stdio","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","450","0"],"version":"2.45"},{"feature":"Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","540","0"],"version":"0.54"},{"feature":"Win32API::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","120","301"],"version":"0.1203_01"},{"feature":"Win32API::File::inc::ExtUtils::Myconst2perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1"},{"feature":"Win32CORE","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"XS::APItest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"XS::Typemap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"XSLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","300","0"],"version":"0.30"},{"feature":"_charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"attributes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"autodie","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::GuardStack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception::system","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::hints","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autouse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"bigint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bignum","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bigrat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"blib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"bytes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"deprecate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"diagnostics","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","370","0"],"version":"1.37"},{"feature":"encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","0","0"],"version":"3.00"},{"feature":"encoding::warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"experimental","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","22","0"],"version":"0.022"},{"feature":"feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"fields","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"filetest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"if","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","900"],"version":"0.0609"},{"feature":"integer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"less","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","650","0"],"version":"0.65"},{"feature":"locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"mro","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","250","0"],"version":"1.25"},{"feature":"ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"open","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"ops","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"overload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"overloading","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","238","0"],"version":"0.238"},{"feature":"perlfaq","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","11","70"],"version":"5.20201107"},{"feature":"re","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"sigtrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"sort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"strict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"subs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"threads","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","260","0"],"version":"2.26"},{"feature":"threads::shared","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","240","0"],"version":"1.24"},{"feature":"vars","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"vmsish","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"warnings::register","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Bump again","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"perl","namespace":"language","version_requirements":[{"comparator":"eq","version":"5.32.1"}]}]},{"alternatives":[],"artifact_id":"48951744-f839-5031-8cf4-6e82a4be2089","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2020-05-28T03:10:35.310Z","ingredient_id":"15bb23b0-0232-5fb9-b791-3e5a905aa4a7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15bb23b0-0232-5fb9-b791-3e5a905aa4a7"},"name":"Data-UUID","normalized_name":"Data-UUID","primary_namespace":"language/perl","description":"Globally/Universally Unique Identifiers (GUIDs/UUIDs)"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-28T03:10:35.310Z","ingredient_id":"15bb23b0-0232-5fb9-b791-3e5a905aa4a7","ingredient_version_id":"e8527602-630b-57ab-b21f-a185719a6c91","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15bb23b0-0232-5fb9-b791-3e5a905aa4a7/versions/e8527602-630b-57ab-b21f-a185719a6c91","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15bb23b0-0232-5fb9-b791-3e5a905aa4a7"},"revision":6,"revision_timestamp":"2020-10-28T19:35:01.617Z","copyright_text":"TODO","documentation_uri":"https://metacpan.org/release/Ricardo SIGNES 😄/Data-UUID-1.226","is_binary_only":false,"license_expression":"[\"BSD-3-Clause\"]","release_timestamp":"2020-04-13T01:43:57.000Z","source_uri":"https://cpan.metacpan.org/authors/id/R/RJ/RJBS/Data-UUID-1.226.tar.gz","sortable_version":["1","226","0"],"version":"1.226","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/093d57ffa0d411a94bafafae495697db26f5c9d0277198fe3f7cf2be22996453/Data-UUID-1.226.tar.gz","scanner_license_expression":"[\"BSD-3-Clause\"]","source_checksum":"093d57ffa0d411a94bafafae495697db26f5c9d0277198fe3f7cf2be22996453","status":"stable","provided_features":[{"feature":"Data-UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","226","0"],"version":"1.226"},{"feature":"Data::UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","226","0"],"version":"1.226"}],"author_platform_user_id":"a19a07b9-313a-4e8f-916b-633457d72be8","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"0029ae25-8497-5130-8268-1f0fe26ccc77","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:20.957Z","ingredient_id":"c3ce160c-83dc-521f-9f12-116d103c0d5a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c3ce160c-83dc-521f-9f12-116d103c0d5a"},"name":"Importer","normalized_name":"Importer","primary_namespace":"language/perl","description":"Alternative but compatible interface to modules that export symbols."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-17T21:14:23.110Z","ingredient_id":"c3ce160c-83dc-521f-9f12-116d103c0d5a","ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c3ce160c-83dc-521f-9f12-116d103c0d5a/versions/2be11022-8f99-5eff-b80e-77f0fade3d27","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c3ce160c-83dc-521f-9f12-116d103c0d5a"},"revision":2,"revision_timestamp":"2020-11-04T20:14:53.251Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Importer-0.025","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2018-02-19T04:44:43.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Importer-0.025.tar.gz","sortable_version":["0","25","0"],"version":"0.025","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/0745138c487d74033d0cbeb36f06595036dc7e688f1a5dbec9cc2fa799e13946/Importer-0.025.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"0745138c487d74033d0cbeb36f06595036dc7e688f1a5dbec9cc2fa799e13946","status":"stable","provided_features":[{"feature":"Importer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","25","0"],"version":"0.025"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Data Acquisition import run with commit ID 0000000000000000000000000000000000000000 and reason: Could not be determined from the database query","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"6591f01d-939d-5080-bb1a-7816ff4d020b","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2020-07-24T03:05:37.269Z","ingredient_id":"2e19a04a-565b-5140-85d3-d102bb043ea8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2e19a04a-565b-5140-85d3-d102bb043ea8"},"name":"Long-Jump","normalized_name":"Long-Jump","primary_namespace":"language/perl","description":"Mechanism for returning to a specific point from a deeply nested stack."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-07-24T03:05:37.269Z","ingredient_id":"2e19a04a-565b-5140-85d3-d102bb043ea8","ingredient_version_id":"6c89ed56-ef22-541a-bf87-9ff4e10ee371","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2e19a04a-565b-5140-85d3-d102bb043ea8/versions/6c89ed56-ef22-541a-bf87-9ff4e10ee371","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2e19a04a-565b-5140-85d3-d102bb043ea8"},"revision":3,"revision_timestamp":"2020-10-28T19:26:23.384Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Long-Jump-0.000001","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2019-09-29T23:36:56.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Long-Jump-0.000001.tar.gz","sortable_version":["0","0","1"],"version":"0.000001","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/d5d6456d86992b559d8f66fc90960f919292cd3803c13403faac575762c77af4/Long-Jump-0.000001.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"d5d6456d86992b559d8f66fc90960f919292cd3803c13403faac575762c77af4","status":"stable","provided_features":[{"feature":"Long-Jump","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","1"],"version":"0.000001"},{"feature":"Long::Jump","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","1"],"version":"0.000001"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"7c541a6a-4dfd-5135-8b98-2b44b5d1a816","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:52.524Z","ingredient_id":"8967b3df-1d60-5fe5-a9d2-d1506eaee353","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8967b3df-1d60-5fe5-a9d2-d1506eaee353"},"name":"Module-Pluggable","normalized_name":"Module-Pluggable","primary_namespace":"language/perl","description":"automatically give your module the ability to have plugins"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:52.524Z","ingredient_id":"8967b3df-1d60-5fe5-a9d2-d1506eaee353","ingredient_version_id":"0f028feb-10aa-531d-9660-b56c19fb7b43","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8967b3df-1d60-5fe5-a9d2-d1506eaee353/versions/0f028feb-10aa-531d-9660-b56c19fb7b43","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8967b3df-1d60-5fe5-a9d2-d1506eaee353"},"revision":7,"revision_timestamp":"2020-10-28T19:20:35.640Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2015-08-05T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/S/SI/SIMONW/Module-Pluggable-5.2.tar.gz","sortable_version":["5","200","0"],"version":"5.2","activestate_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","camel_extras":{"mm_fullext":"Module/Pluggable"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/b3f2ad45e4fd10b3fb90d912d78d8b795ab295480db56dc64e86b9fa75c5a6df/Module-Pluggable-5.2.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"b3f2ad45e4fd10b3fb90d912d78d8b795ab295480db56dc64e86b9fa75c5a6df","status":"stable","provided_features":[{"feature":"Devel::InnerPackage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","200","0"],"version":"5.2"},{"feature":"Module-Pluggable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","200","0"],"version":"5.2"},{"feature":"Module::Pluggable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","200","0"],"version":"5.2"},{"feature":"Module::Pluggable::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","200","0"],"version":"5.2"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"7f8a7197-b277-5621-a6f3-7f2ef32d871b","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:53:43.175Z","ingredient_id":"419b3d3f-2c08-58dc-b06a-5890d25878ab","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/419b3d3f-2c08-58dc-b06a-5890d25878ab"},"name":"Scope-Guard","normalized_name":"Scope-Guard","primary_namespace":"language/perl","description":"lexically-scoped resource management"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:53:43.175Z","ingredient_id":"419b3d3f-2c08-58dc-b06a-5890d25878ab","ingredient_version_id":"1ff5b410-a933-53c7-b3a1-f11524b53213","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/419b3d3f-2c08-58dc-b06a-5890d25878ab/versions/1ff5b410-a933-53c7-b3a1-f11524b53213","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/419b3d3f-2c08-58dc-b06a-5890d25878ab"},"revision":5,"revision_timestamp":"2020-10-28T19:21:37.794Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2015-07-19T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/C/CH/CHOCOLATE/Scope-Guard-0.21.tar.gz","sortable_version":["0","210","0"],"version":"0.21","activestate_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","camel_extras":{"mm_fullext":"Scope/Guard"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/8c9b1bea5c56448e2c3fadc65d05be9e4690a3823a80f39d2f10fdd8f777d278/Scope-Guard-0.21.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"8c9b1bea5c56448e2c3fadc65d05be9e4690a3823a80f39d2f10fdd8f777d278","status":"stable","provided_features":[{"feature":"Scope-Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","0"],"version":"0.21"},{"feature":"Scope::Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","0"],"version":"0.21"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"29983a5b-49c4-5cf4-a2c5-2490647d6910","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime"],"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:53:51.949Z","ingredient_id":"bd0582e7-a354-5e28-868e-c772965b793f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bd0582e7-a354-5e28-868e-c772965b793f"},"name":"Sub-Info","normalized_name":"Sub-Info","primary_namespace":"language/perl","description":"Tool for inspecting subroutines."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-28T00:53:33.249Z","ingredient_id":"bd0582e7-a354-5e28-868e-c772965b793f","ingredient_version_id":"9e33e514-0b22-504b-8409-6d0bdbf86108","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bd0582e7-a354-5e28-868e-c772965b793f/versions/9e33e514-0b22-504b-8409-6d0bdbf86108","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/bd0582e7-a354-5e28-868e-c772965b793f"},"revision":4,"revision_timestamp":"2021-02-16T16:39:17.261Z","copyright_text":"TODO","documentation_uri":"https://metacpan.org/release/Chad Granum/Sub-Info-0.002","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2016-12-24T12:17:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Sub-Info-0.002.tar.gz","sortable_version":["0","2","0"],"version":"0.002","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Sub/Info"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/ea3056d696bdeff21a99d340d5570887d39a8cc47bff23adfc82df6758cdd0ea/Sub-Info-0.002.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"ea3056d696bdeff21a99d340d5570887d39a8cc47bff23adfc82df6758cdd0ea","status":"stable","provided_features":[{"feature":"Sub-Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.002"},{"feature":"Sub::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.002"}],"author_platform_user_id":"8fd0aa9c-0483-4ee7-9197-96c9194c0318","comment":"Add build dependencies for Auto-intstall - Importer","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"4d95557d-2200-5a56-a809-4ea3d3502b20","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime"],"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:02.753Z","ingredient_id":"d8ad5efe-897b-5342-8ad1-f4abbd328ab4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d8ad5efe-897b-5342-8ad1-f4abbd328ab4"},"name":"Term-Table","normalized_name":"Term-Table","primary_namespace":"language/perl","description":"Format a header and rows into a table"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-17T21:15:15.752Z","ingredient_id":"d8ad5efe-897b-5342-8ad1-f4abbd328ab4","ingredient_version_id":"7e483f34-00ad-523a-91be-e9ddf74366a5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d8ad5efe-897b-5342-8ad1-f4abbd328ab4/versions/7e483f34-00ad-523a-91be-e9ddf74366a5","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d8ad5efe-897b-5342-8ad1-f4abbd328ab4"},"revision":3,"revision_timestamp":"2021-02-19T04:13:53.554Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Term-Table-0.015","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2019-11-19T07:59:44.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Term-Table-0.015.tar.gz","sortable_version":["0","15","0"],"version":"0.015","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/d8a18b2801f91f0e5d747147ce786964a76f91d18568652908a3dc06a9b948d5/Term-Table-0.015.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"d8a18b2801f91f0e5d747147ce786964a76f91d18568652908a3dc06a9b948d5","status":"stable","provided_features":[{"feature":"Term-Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::Cell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::CellStack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::LineBreak","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::Spacer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"},{"feature":"Term::Table::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.015"}],"author_platform_user_id":"8fd0aa9c-0483-4ee7-9197-96c9194c0318","comment":"Data Acquisition import run with commit ID 0000000000000000000000000000000000000000 and reason: Could not be determined from the database query","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"288aa0db-c0e4-55e7-8f67-fc2da409be70","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"1ff5b410-a933-53c7-b3a1-f11524b53213"},{"dependency_types":["runtime"],"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27"},{"dependency_types":["runtime"],"ingredient_version_id":"4bd9f2db-1c09-5a14-82a3-7cb6d966d18c"},{"dependency_types":["runtime"],"ingredient_version_id":"6c89ed56-ef22-541a-bf87-9ff4e10ee371"},{"dependency_types":["runtime"],"ingredient_version_id":"7e483f34-00ad-523a-91be-e9ddf74366a5"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"},{"dependency_types":["runtime"],"ingredient_version_id":"d85188d8-231d-589f-9bdd-fc5667cc2d2f"},{"dependency_types":["runtime"],"ingredient_version_id":"e8527602-630b-57ab-b21f-a185719a6c91"},{"dependency_types":["runtime"],"ingredient_version_id":"ee3bc68e-abb3-58ff-aa9c-60b7412df7e2"},{"dependency_types":["runtime"],"ingredient_version_id":"fa7a0c73-1e93-5e08-8f6b-a009e82d7179"}],"ingredient":{"creation_timestamp":"2020-05-28T03:57:35.831Z","ingredient_id":"7cc539a3-0ee6-5e80-a948-dbd38b3f26db","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7cc539a3-0ee6-5e80-a948-dbd38b3f26db"},"name":"Test2-Harness","normalized_name":"Test2-Harness","primary_namespace":"language/perl","description":"A new and improved test harness with better Test2 integration."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-01-13T02:09:51.439Z","ingredient_id":"7cc539a3-0ee6-5e80-a948-dbd38b3f26db","ingredient_version_id":"9c514f0f-5abb-546a-840a-1c97f2010c78","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7cc539a3-0ee6-5e80-a948-dbd38b3f26db/versions/9c514f0f-5abb-546a-840a-1c97f2010c78","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7cc539a3-0ee6-5e80-a948-dbd38b3f26db"},"revision":2,"revision_timestamp":"2021-02-02T23:55:10.154Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Test2-Harness-1.000042","is_binary_only":false,"license_expression":"Artistic-1.0-Perl, GPL-1.0-or-later","release_timestamp":"2020-11-18T06:47:53.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test2-Harness-1.000042.tar.gz","sortable_version":["1","0","42"],"version":"1.000042","activestate_license_expression":"Artistic-1.0-Perl, GPL-1.0-or-later","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/aaf231a68af1a6ffd6a11188875fcf572e373e43c8285945227b9d687b43db2d/Test2-Harness-1.000042.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"aaf231a68af1a6ffd6a11188875fcf572e373e43c8285945227b9d687b43db2d","status":"stable","provided_features":[{"feature":"App::Yath","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::auditor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::collector","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::failed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::help","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::init","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::projects","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::reload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::replay","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::runner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::spawn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::speedtag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::start","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::stop","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::times","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::watch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Command::which","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Converting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Option","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Display","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Finder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Logging","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Persist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::PreCommand","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Runner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Options::Workspace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::Git","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::Notify","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::SelfTest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::SysInfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Plugin::YathUI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"App::Yath::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2-Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Formatter::QVF","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Formatter::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Formatter::Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Formatter::Test2::Composer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Auditor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Auditor::TimeTracker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Auditor::Watcher","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Collector","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Collector::JobDir","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Collector::TapParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Finder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::IPC::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Log","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Log::CoverageAggregator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Renderer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Renderer::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::DepTracer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Job","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Preload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Preload::Stage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Preloader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Preloader::Stage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Resource","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Spawn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::Spawn::Run","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Runner::State","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Settings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Settings::Prefix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::TestFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File::JSON","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File::JSONL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::File::Value","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::JSON","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::Term","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Harness::Util::UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"},{"feature":"Test2::Tools::HarnessTester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","42"],"version":"1.000042"}],"author_platform_user_id":"2e044215-1b51-498f-a440-ae0cc11bdd4c","comment":"Fix improper Perl core version","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"282e3768-e12a-51ed-831f-7cbc212ba8bd","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2020-08-04T05:03:47.447Z","ingredient_id":"475ab2a1-ee4c-5337-b9c0-5991daa7d9ad","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/475ab2a1-ee4c-5337-b9c0-5991daa7d9ad"},"name":"Test2-Plugin-MemUsage","normalized_name":"Test2-Plugin-MemUsage","primary_namespace":"language/perl","description":"Collect and display memory usage information."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-08-04T05:03:47.447Z","ingredient_id":"475ab2a1-ee4c-5337-b9c0-5991daa7d9ad","ingredient_version_id":"d85188d8-231d-589f-9bdd-fc5667cc2d2f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/475ab2a1-ee4c-5337-b9c0-5991daa7d9ad/versions/d85188d8-231d-589f-9bdd-fc5667cc2d2f","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/475ab2a1-ee4c-5337-b9c0-5991daa7d9ad"},"revision":3,"revision_timestamp":"2020-10-28T19:33:54.008Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Test2-Plugin-MemUsage-0.002003","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2020-02-26T16:09:51.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test2-Plugin-MemUsage-0.002003.tar.gz","sortable_version":["0","2","3"],"version":"0.002003","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/5e0662d5a823ae081641f5ce82843111eec1831cd31f883a6c6de54afdf87c25/Test2-Plugin-MemUsage-0.002003.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"5e0662d5a823ae081641f5ce82843111eec1831cd31f883a6c6de54afdf87c25","status":"stable","provided_features":[{"feature":"Test2-Plugin-MemUsage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","3"],"version":"0.002003"},{"feature":"Test2::Plugin::MemUsage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","3"],"version":"0.002003"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"5ad88c8a-bc8f-50a0-9f61-74856cd28017","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:23.311Z","ingredient_id":"ad9a26f2-c23b-54b1-ada2-3327ff7fd40d","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ad9a26f2-c23b-54b1-ada2-3327ff7fd40d"},"name":"Test2-Plugin-NoWarnings","normalized_name":"Test2-Plugin-NoWarnings","primary_namespace":"language/perl","description":"Fail if tests warn"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-28T00:53:49.862Z","ingredient_id":"ad9a26f2-c23b-54b1-ada2-3327ff7fd40d","ingredient_version_id":"b8f76881-09d4-53fd-8cc6-e595b6d69132","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ad9a26f2-c23b-54b1-ada2-3327ff7fd40d/versions/b8f76881-09d4-53fd-8cc6-e595b6d69132","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ad9a26f2-c23b-54b1-ada2-3327ff7fd40d"},"revision":3,"revision_timestamp":"2020-10-28T19:31:31.379Z","copyright_text":"TODO","documentation_uri":"https://metacpan.org/release/Dave Rolsky/Test2-Plugin-NoWarnings-0.06","is_binary_only":false,"license_expression":"[\"Artistic-2.0\"]","release_timestamp":"2017-06-04T22:24:22.000Z","source_uri":"https://cpan.metacpan.org/authors/id/D/DR/DROLSKY/Test2-Plugin-NoWarnings-0.06.tar.gz","sortable_version":["0","60","0"],"version":"0.06","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Test2/Plugin/NoWarnings"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/8288c1d934f69a03224598fbb715adc079c0d1609bfbaea6c88682aab1995800/Test2-Plugin-NoWarnings-0.06.tar.gz","scanner_license_expression":"[\"Artistic-2.0\"]","source_checksum":"8288c1d934f69a03224598fbb715adc079c0d1609bfbaea6c88682aab1995800","status":"stable","provided_features":[{"feature":"Test2-Plugin-NoWarnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"Test2::Event::Warning","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"Test2::Plugin::NoWarnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c3e652a7-676e-594f-b87f-93d19122f3f4","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"},{"dependency_types":["runtime"],"ingredient_version_id":"e8527602-630b-57ab-b21f-a185719a6c91"}],"ingredient":{"creation_timestamp":"2020-08-04T05:03:50.581Z","ingredient_id":"cfacafbc-90b3-50d6-a0d3-3320ec24434c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/cfacafbc-90b3-50d6-a0d3-3320ec24434c"},"name":"Test2-Plugin-UUID","normalized_name":"Test2-Plugin-UUID","primary_namespace":"language/perl","description":"Use REAL UUIDs in Test2"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-08-04T05:03:50.581Z","ingredient_id":"cfacafbc-90b3-50d6-a0d3-3320ec24434c","ingredient_version_id":"4bd9f2db-1c09-5a14-82a3-7cb6d966d18c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/cfacafbc-90b3-50d6-a0d3-3320ec24434c/versions/4bd9f2db-1c09-5a14-82a3-7cb6d966d18c","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/cfacafbc-90b3-50d6-a0d3-3320ec24434c"},"revision":3,"revision_timestamp":"2020-10-28T19:24:08.293Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Test2-Plugin-UUID-0.002001","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2019-08-16T22:46:14.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test2-Plugin-UUID-0.002001.tar.gz","sortable_version":["0","2","1"],"version":"0.002001","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/4c6c8d484d7153d8779dc155a992b203095b5c5aa1cfb1ee8bcedcd0601878c9/Test2-Plugin-UUID-0.002001.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"4c6c8d484d7153d8779dc155a992b203095b5c5aa1cfb1ee8bcedcd0601878c9","status":"stable","provided_features":[{"feature":"Test2-Plugin-UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","1"],"version":"0.002001"},{"feature":"Test2::Plugin::UUID","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","1"],"version":"0.002001"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"30dc7965-0a69-5686-831a-e563fa73a98c","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"0f028feb-10aa-531d-9660-b56c19fb7b43"},{"dependency_types":["runtime"],"ingredient_version_id":"1ff5b410-a933-53c7-b3a1-f11524b53213"},{"dependency_types":["build","runtime"],"ingredient_version_id":"2be11022-8f99-5eff-b80e-77f0fade3d27"},{"dependency_types":["runtime"],"ingredient_version_id":"7e483f34-00ad-523a-91be-e9ddf74366a5"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["runtime"],"ingredient_version_id":"9e33e514-0b22-504b-8409-6d0bdbf86108"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:24.108Z","ingredient_id":"9bd2d82e-5607-5b1e-9f58-05d8ce6a171b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9bd2d82e-5607-5b1e-9f58-05d8ce6a171b"},"name":"Test2-Suite","normalized_name":"Test2-Suite","primary_namespace":"language/perl","description":"Distribution with a rich set of tools built upon the Test2 framework."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-17T20:03:44.338Z","ingredient_id":"9bd2d82e-5607-5b1e-9f58-05d8ce6a171b","ingredient_version_id":"fa7a0c73-1e93-5e08-8f6b-a009e82d7179","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9bd2d82e-5607-5b1e-9f58-05d8ce6a171b/versions/fa7a0c73-1e93-5e08-8f6b-a009e82d7179","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9bd2d82e-5607-5b1e-9f58-05d8ce6a171b"},"revision":2,"revision_timestamp":"2021-02-19T04:22:07.305Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/Test2-Suite-0.000127","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2019-10-31T11:27:54.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test2-Suite-0.000127.tar.gz","sortable_version":["0","0","127"],"version":"0.000127","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/09443e7c99f9bef2c3f5999b919800db7d265b2c55f177726d3e5a61d8dbe690/Test2-Suite-0.000127.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"09443e7c99f9bef2c3f5999b919800db7d265b2c55f177726d3e5a61d8dbe690","status":"stable","provided_features":[{"feature":"Test2-Suite","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest::Event::Attach","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest::Event::Detach","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::AsyncSubtest::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Bundle::Extended","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Bundle::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Bundle::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Bag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Bool","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Custom","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::DeepRef","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Delta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::EventMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Float","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Negatable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Number","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::OrderedSubset","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Pattern","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Ref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Set","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::String","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Undef","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Compare::Wildcard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::EndToEnd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::Hubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Anatomy::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Contributing","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing::Introduction","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing::Migrating","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing::Planning","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Testing::Todo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::FirstTool","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Nesting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Plugin::TestExit","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Plugin::TestingDone","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Plugin::ToolCompletes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Plugin::ToolStarts","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::TestBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Manual::Tooling::Testing","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Mock","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::BailOnFail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::DieOnFail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::ExitSummary","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::SRand","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::Times","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Plugin::UTF8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::AuthorTesting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::EnvVar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::Fork","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::Perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::RealFork","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Require::Threads","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Suite","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Todo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::AsyncSubtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Basic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Class","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::ClassicCompare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Defer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Exports","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::GenTemp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Grab","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Mock","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Ref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Target","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Tools::Warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Grabber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Ref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Stash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Sub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Table::Cell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Table::LineBreak","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Term","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Util::Times","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::V0","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::BlockBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Build","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Runner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Task","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Task::Action","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"},{"feature":"Test2::Workflow::Task::Group","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","0","127"],"version":"0.000127"}],"author_platform_user_id":"8fd0aa9c-0483-4ee7-9197-96c9194c0318","comment":"Data Acquisition import run with commit ID 0000000000000000000000000000000000000000 and reason: Could not be determined from the database query","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c1e8c6c4-ea11-55a4-b415-97da2d32121e","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2020-08-04T03:41:54.942Z","ingredient_id":"d467d24f-854c-5970-acac-acda9cb97d15","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d467d24f-854c-5970-acac-acda9cb97d15"},"name":"goto-file","normalized_name":"goto-file","primary_namespace":"language/perl","description":"Stop parsing the current file and move on to a different one.","website":"https://github.com/exodist/goto-file"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-08-04T03:41:54.942Z","ingredient_id":"d467d24f-854c-5970-acac-acda9cb97d15","ingredient_version_id":"ee3bc68e-abb3-58ff-aa9c-60b7412df7e2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d467d24f-854c-5970-acac-acda9cb97d15/versions/ee3bc68e-abb3-58ff-aa9c-60b7412df7e2","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d467d24f-854c-5970-acac-acda9cb97d15"},"revision":3,"revision_timestamp":"2020-10-28T19:35:27.454Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Chad Granum/goto-file-0.005","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2017-10-24T15:33:30.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/goto-file-0.005.tar.gz","sortable_version":["0","5","0"],"version":"0.005","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/c6cdd5ee4a6cdcbdbf314d92a4f9985dbcdf9e4258048cae76125c052aa31f77/goto-file-0.005.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"c6cdd5ee4a6cdcbdbf314d92a4f9985dbcdf9e4258048cae76125c052aa31f77","status":"stable","provided_features":[{"feature":"goto-file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","5","0"],"version":"0.005"},{"feature":"goto::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","5","0"],"version":"0.005"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]}],"solver_version":1} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-package.json b/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-package.json deleted file mode 100644 index 0b84a41d44..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-package.json +++ /dev/null @@ -1 +0,0 @@ -{"camel_flags":[],"from_recipe_store":true,"image":{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"},"is_indemnified":false,"platform":{"cpu_architecture":{"cpu_architecture_id":"4cdba18d-0851-4925-9ae5-9c8a2987828a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a"},"bit_width":"64","name":"x86","provided_features":[{"feature":"x86 64-bit","is_activestate_version":false,"is_default_provider":true,"namespace":"cpu-architecture","sortable_version":["1","0"],"version":"1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"cpu_extensions":[],"creation_timestamp":"2021-01-15T18:05:36.924Z","display_name":"CentOS 8, Linux 4.18.0, glibc 2.28 x86 64-bit","end_of_support_date":"2025-12-31","images":[{"image_id":"00216735-694e-4ef8-a7d5-7724b9200be0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/00216735-694e-4ef8-a7d5-7724b9200be0"},"name":"docker-registry.activestate.build/activestate/centos-8-build","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","1","0"],"version":"1.1","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"eq","sortable_version":[]}]}],"revision":1,"revision_timestamp":"2021-01-15T18:07:52.645Z"},{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"}],"is_user_visible":true,"kernel":{"kernel_id":"ef737274-fff9-4164-b72b-88067613f822","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822"},"name":"Linux"},"kernel_version":{"kernel_version_id":"61f9365e-03ed-448f-9a24-2b845727e4f5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/61f9365e-03ed-448f-9a24-2b845727e4f5"},"sortable_version":["4","18","0","0"],"version":"4.18.0","provided_features":[{"feature":"Linux","is_activestate_version":false,"is_default_provider":true,"namespace":"kernel","sortable_version":["4","18","0","0"],"version":"4.18.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:04.588Z"},"libc":{"libc_id":"09a2eb42-ad34-4734-a93e-4b97395577df","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df"},"name":"glibc"},"libc_version":{"libc_version_id":"22d234e7-145e-4688-9d05-ee164b4ffa12","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/22d234e7-145e-4688-9d05-ee164b4ffa12"},"sortable_version":["2","28","0"],"version":"2.28","provided_features":[{"feature":"glibc","is_activestate_version":false,"is_default_provider":true,"namespace":"libc","sortable_version":["2","28","0"],"version":"2.28"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:19.136Z"},"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/7c998ec2-7491-4e75-be4d-8885800ef5f2"},"operating_system":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99"},"operating_system_id":"7b3a2dbb-d543-48d6-8390-7e7b63751e99","has_libc":true,"name":"CentOS"},"operating_system_version":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/42cab97b-9d80-407f-89a8-230836868e88"},"operating_system_version_id":"42cab97b-9d80-407f-89a8-230836868e88","sortable_version":["8","0"],"version":"8","provided_features":[{"feature":"CentOS","is_activestate_version":false,"is_default_provider":true,"namespace":"operating-system","sortable_version":["8","0"],"version":"8"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:50.448Z"},"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},"recipe_id":"b50600fa-f2ef-5079-afbb-550bf3b8295d","recipe_store_timestamp":"2021-02-20T07:46:16.324Z","resolved_ingredients":[{"alternatives":[],"artifact_id":"cf3d86c1-2587-564e-a7b2-0cf109ce263e","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:47:40.385Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"name":"perl-core-builder","normalized_name":"perl-core-builder","primary_namespace":"builder","description":"Builds the core Perl interpreter on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:58:38.567Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31/versions/d5ac8c7c-b025-5418-ab77-a139e60e1d41","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"revision":2,"revision_timestamp":"2020-10-30T17:04:06.702Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-06-25T07:05:14.000Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-core-builder","sortable_version":["1","0","23","0"],"version":"1.0.23","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374/perl-core-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-core-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","23","0"],"version":"1.0.23"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial builder for perl 5.30+","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"a1ebbc88-daeb-5588-8086-c99de70eabf7","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"ed446cc4-4e4d-5986-ad77-ed04a3b2e58b"}],"ingredient":{"creation_timestamp":"2020-08-10T23:48:55.390Z","ingredient_id":"196722f9-5600-5d89-9c47-42460922fdb1","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1"},"name":"perl-module-builder","normalized_name":"perl-module-builder","primary_namespace":"builder","description":"Builds Perl modules on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-12-07T20:54:12.006Z","ingredient_id":"196722f9-5600-5d89-9c47-42460922fdb1","ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1/versions/c4164b54-9b8f-55fc-ae5a-cd47c6389687","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1"},"revision":1,"revision_timestamp":"2020-12-07T20:54:12.006Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-12-07T20:23:01.043Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-module-builder","sortable_version":["1","0","36","0"],"version":"1.0.36","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/bb8bb535334fb012df0550a528692f4826893b91b055ac73ffb37dd00322a7b6/perl-module-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"bb8bb535334fb012df0550a528692f4826893b91b055ac73ffb37dd00322a7b6","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-module-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","36","0"],"version":"1.0.36"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Created new version 1.0.36 from 1.0.35.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"f7c88044-fdcd-5023-a0ce-9c4a6fcc2708","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:48:13.169Z","ingredient_id":"4c0fd8d2-5c39-5ecf-958e-325efdea1ef2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2"},"name":"perl-module-lib","normalized_name":"perl-module-lib","primary_namespace":"builder-lib","description":"Builds Perl modules on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-12-07T20:54:42.776Z","ingredient_id":"4c0fd8d2-5c39-5ecf-958e-325efdea1ef2","ingredient_version_id":"ed446cc4-4e4d-5986-ad77-ed04a3b2e58b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2/versions/ed446cc4-4e4d-5986-ad77-ed04a3b2e58b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2"},"revision":2,"revision_timestamp":"2020-12-10T17:22:10.292Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-12-07T20:25:59.954Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-module-lib","sortable_version":["1","0","36","0"],"version":"1.0.36","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/abdb22574b2300f30e98ab9239892f379c0c60bf33634a2b49518bddc730413d/perl-module-lib.tar.gz","scanner_license_expression":"unknown","source_checksum":"abdb22574b2300f30e98ab9239892f379c0c60bf33634a2b49518bddc730413d","status":"stable","provided_features":[{"feature":"perl-module-lib","is_activestate_version":false,"is_default_provider":true,"namespace":"builder-lib","sortable_version":["1","0","36","0"],"version":"1.0.36"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"Created new version 1.0.36 from 1.0.35.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:32.665Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"name":"perl","normalized_name":"perl","primary_namespace":"language","description":"Practical Extraction and Report Language"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-01-29T18:11:47.039Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206/versions/86005392-bdbf-59bd-a716-70ce7fcd3a66","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"revision":3,"revision_timestamp":"2021-02-03T21:14:56.873Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/S/SH/SHAY/perl-5.32.1.tar.gz","sortable_version":["5","32","1"],"version":"5.32.1","activestate_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/language/03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c/perl-5.32.1.tar.gz","scanner_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","source_checksum":"03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c","status":"stable","provided_features":[{"feature":"alternative-built-language","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1","0"],"version":"5.32.1"},{"feature":"perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1"],"version":"5.32.1"},{"feature":"Amiga::ARexx","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","50","0"],"version":"0.05"},{"feature":"Amiga::Exec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"App::Cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","676","0"],"version":"1.676"},{"feature":"App::Prove","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Archive::Tar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Attribute::Handlers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"AutoLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","740","0"],"version":"5.74"},{"feature":"AutoSplit","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"B","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","820","0"],"version":"1.82"},{"feature":"B::Concise","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.004"},{"feature":"B::Deparse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"B::Op_private","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"B::Showlex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"B::Terse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"B::Xref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Benchmark","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"CPAN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"CPAN::Author","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","500"],"version":"5.5005"},{"feature":"CPAN::CacheMgr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::DeferredCode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::Distribution","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Distroprefs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","0","100"],"version":"6.0001"},{"feature":"CPAN::Distrostatus","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::RecursiveDependency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Exception::blocked_urllist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"CPAN::Exception::yaml_not_installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::yaml_process_error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::FTP::netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"CPAN::FirstTime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","531","500"],"version":"5.5315"},{"feature":"CPAN::HTTP::Client","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HTTP::Credentials","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HandleConfig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","100"],"version":"5.5011"},{"feature":"CPAN::Index","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","120","0"],"version":"2.12"},{"feature":"CPAN::InfoObj","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Kwalify","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Converter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::History","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Merge","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Prereqs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Requirements","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","140","0"],"version":"2.140"},{"feature":"CPAN::Meta::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Validator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","18","0"],"version":"0.018"},{"feature":"CPAN::Mirrors","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Nox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","970","0"],"version":"0.97"},{"feature":"CPAN::Plugin::Specfile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"CPAN::Prompt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Shell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","900"],"version":"5.5009"},{"feature":"CPAN::Tarzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"Carp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Carp::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Class::Struct","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","660","0"],"version":"0.66"},{"feature":"Compress::Raw::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Raw::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"Config::Extensions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"Config::Perl::V","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"Cwd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"DB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"DBM_Filter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"DBM_Filter::compress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::int32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DB_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","855","0"],"version":"1.855"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","176","0"],"version":"2.176"},{"feature":"Devel::PPPort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","620","0"],"version":"3.62"},{"feature":"Devel::Peek","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Devel::SelfStubber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Digest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::MD5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","580","0"],"version":"2.58"},{"feature":"Digest::SHA","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","20","0"],"version":"6.02"},{"feature":"Digest::base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"DirHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Dumpvalue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"DynaLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"Encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","80","0"],"version":"3.08"},{"feature":"Encode::Alias","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"Encode::Byte","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::CJKConstants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::CN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::CN::HZ","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"Encode::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.05"},{"feature":"Encode::EBCDIC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::Encoder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::GSM0338","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"Encode::Guess","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::JP::H2Z","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::JP::JIS7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::KR::2022_KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::MIME::Header","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"Encode::MIME::Header::ISO_2022_JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Encode::MIME::Name","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Encode::Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::TW","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"Encode::Unicode::UTF7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"English","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Errno","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"Exporter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"Exporter::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","250","0"],"version":"0.25"},{"feature":"ExtUtils::Constant::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"ExtUtils::Constant::ProxySubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"ExtUtils::Constant::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"ExtUtils::Constant::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"ExtUtils::Embed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","350","0"],"version":"1.35"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","730","0"],"version":"1.73"},{"feature":"ExtUtils::Miniperl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::ParseXS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::CountLines","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Eval","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::Typemaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::InputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::OutputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Type","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::XSSymSet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.4"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"Fatal","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"Fcntl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","140","0"],"version":"1.14"},{"feature":"File::Basename","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","850","0"],"version":"2.85"},{"feature":"File::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","600"],"version":"1.1006"},{"feature":"File::Copy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","350","0"],"version":"2.35"},{"feature":"File::DosGlob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"File::Fetch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.00"},{"feature":"File::Find","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","380","0"],"version":"1.38"},{"feature":"File::Glob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"File::GlobMapper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"File::Path","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Temp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","231","100"],"version":"0.2311"},{"feature":"File::stat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"FileCache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"FileHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Filter::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","960","0"],"version":"0.96"},{"feature":"Filter::Util::Call","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","600","0"],"version":"1.60"},{"feature":"FindBin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"GDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","520","0"],"version":"2.52"},{"feature":"Getopt::Std","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"HTTP::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","76","0"],"version":"0.076"},{"feature":"Hash::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","240","0"],"version":"0.24"},{"feature":"Hash::Util::FieldHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"I18N::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"I18N::LangTags","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","450","0"],"version":"0.45"},{"feature":"I18N::LangTags::Detect","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"I18N::LangTags::List","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","400","0"],"version":"0.40"},{"feature":"I18N::Langinfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","190","0"],"version":"0.19"},{"feature":"IO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Compress::Adapter::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base::Common","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::RawDeflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Extra","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Dir","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Pipe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Poll","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Seekable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Select","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::INET","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::IP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"IO::Socket::UNIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Uncompress::Adapter::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyUncompress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Gunzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::RawInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Unzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"IPC::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"IPC::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::Open2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"IPC::Open3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"IPC::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SharedMem","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SysV","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Locale::Maketext","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Locale::Maketext::Guts","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::GutsLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","100"],"version":"0.21_01"},{"feature":"MIME::Base64","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"MIME::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"Math::BigFloat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigFloat::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigInt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Calc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::FastCalc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","500","900"],"version":"0.5009"},{"feature":"Math::BigInt::Lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigRat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","261","400"],"version":"0.2614"},{"feature":"Math::Complex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","590","200"],"version":"1.5902"},{"feature":"Math::Trig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","100"],"version":"1.03_01"},{"feature":"Memoize::AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Expire","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireTest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Module::CoreList","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::CoreList::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::Load","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"Module::Load::Conditional","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","740","0"],"version":"0.74"},{"feature":"Module::Loaded","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","80","0"],"version":"0.08"},{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","37"],"version":"1.000037"},{"feature":"Moped::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10","0"],"version":"0.01"},{"feature":"NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"NEXT","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","670","100"],"version":"0.67_01"},{"feature":"Net::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Domain","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::A","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::E","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::I","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::L","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::dataconn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::NNTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::POP3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Ping","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","740","0"],"version":"2.74"},{"feature":"Net::SMTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Time","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::hostent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Net::netent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::protoent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::servent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"O","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"ODBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"OS2::DLL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"OS2::ExtAttr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::PrfDB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"OS2::REXX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Opcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","490","0"],"version":"1.49"},{"feature":"POSIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","970","0"],"version":"1.97"},{"feature":"Params::Check","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","380","0"],"version":"0.38"},{"feature":"Parse::CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"Perl::OSType","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.010"},{"feature":"PerlIO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"PerlIO::encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","0"],"version":"0.28"},{"feature":"PerlIO::mmap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.017"},{"feature":"PerlIO::scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","310","0"],"version":"0.31"},{"feature":"PerlIO::via","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"PerlIO::via::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"Pod::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","740","0"],"version":"1.74"},{"feature":"Pod::Escapes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Pod::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Functions::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Html","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Perldoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","100"],"version":"3.2801"},{"feature":"Pod::Perldoc::BaseTo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::GetOptsOO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToChecker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToMan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToNroff","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToPod","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToRtf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTerm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTk","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToXml","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::BlackBox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsXML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLBatch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLLegacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Pod::Simple::LinkSection","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Methody","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Progress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserEndToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserStartToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserTextToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::RTF","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Search","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::SimpleTree","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TextContent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TiedOutFH","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Transcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeDumb","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeSmart","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XHTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XMLOutStream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Usage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.01"},{"feature":"SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"Safe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","430","0"],"version":"2.43"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Search::Dict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"SelectSaver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"SelfLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.030"},{"feature":"Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","230","0"],"version":"3.23"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Sys::Hostname","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Sys::Syslog","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"TAP::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::ParallelSession","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness::Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Aggregator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Grammar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::IteratorFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Multiplexer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Bailout","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Comment","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Pragma","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Unknown","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::ResultFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Job","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Spinner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Source","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Executable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::RawTAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Reader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Writer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Term::ANSIColor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Term::Cap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Term::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","403","0"],"version":"1.403"},{"feature":"Term::ReadLine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","310","0"],"version":"1.31"},{"feature":"Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","114","0"],"version":"2.114"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Text::Abbrev","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Text::Balanced","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Text::ParseWords","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","300","0"],"version":"3.30"},{"feature":"Text::Tabs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Text::Wrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Thread","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","50","0"],"version":"3.05"},{"feature":"Thread::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","140","0"],"version":"3.14"},{"feature":"Thread::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","130","0"],"version":"2.13"},{"feature":"Tie::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Tie::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Tie::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","200","0"],"version":"4.2"},{"feature":"Tie::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::Hash::NamedCapture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"Tie::Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"Tie::RefHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.40"},{"feature":"Tie::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::StdHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","600","0"],"version":"4.6"},{"feature":"Tie::SubstrHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Time::HiRes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","976","600"],"version":"1.9766"},{"feature":"Time::Local","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Time::Piece","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::Seconds","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::gmtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"Time::localtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Time::tm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"UNIVERSAL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["13","0","0"],"version":"13.0.0"},{"feature":"Unicode::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Big5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::GB2312","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::JISX0208","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Korean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Pinyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Stroke","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Zhuyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Normalize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","280","0"],"version":"1.28"},{"feature":"Unicode::UCD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","750","0"],"version":"0.75"},{"feature":"User::grent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"User::pwent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"VMS::DCLsym","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"VMS::Filespec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"VMS::Stdio","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","450","0"],"version":"2.45"},{"feature":"Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","540","0"],"version":"0.54"},{"feature":"Win32API::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","120","301"],"version":"0.1203_01"},{"feature":"Win32API::File::inc::ExtUtils::Myconst2perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1"},{"feature":"Win32CORE","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"XS::APItest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"XS::Typemap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"XSLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","300","0"],"version":"0.30"},{"feature":"_charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"attributes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"autodie","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::GuardStack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception::system","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::hints","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autouse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"bigint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bignum","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bigrat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"blib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"bytes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"deprecate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"diagnostics","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","370","0"],"version":"1.37"},{"feature":"encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","0","0"],"version":"3.00"},{"feature":"encoding::warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"experimental","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","22","0"],"version":"0.022"},{"feature":"feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"fields","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"filetest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"if","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","900"],"version":"0.0609"},{"feature":"integer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"less","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","650","0"],"version":"0.65"},{"feature":"locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"mro","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","250","0"],"version":"1.25"},{"feature":"ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"open","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"ops","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"overload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"overloading","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","238","0"],"version":"0.238"},{"feature":"perlfaq","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","11","70"],"version":"5.20201107"},{"feature":"re","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"sigtrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"sort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"strict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"subs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"threads","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","260","0"],"version":"2.26"},{"feature":"threads::shared","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","240","0"],"version":"1.24"},{"feature":"vars","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"vmsish","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"warnings::register","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Bump again","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"perl","namespace":"language","version_requirements":[{"comparator":"eq","version":"5.32.1"}]}]},{"alternatives":[],"artifact_id":"41dbce7b-0d0f-597b-bb6f-411a4fb0b829","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:49:47.162Z","ingredient_id":"30c076f2-aeec-5c1d-bff1-0e289f201c27","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/30c076f2-aeec-5c1d-bff1-0e289f201c27"},"name":"Canary-Stability","normalized_name":"Canary-Stability","primary_namespace":"language/perl","description":"unknown"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:49:47.162Z","ingredient_id":"30c076f2-aeec-5c1d-bff1-0e289f201c27","ingredient_version_id":"9930b34d-2ad3-507f-912f-729e5bb4e3e1","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/30c076f2-aeec-5c1d-bff1-0e289f201c27/versions/9930b34d-2ad3-507f-912f-729e5bb4e3e1","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/30c076f2-aeec-5c1d-bff1-0e289f201c27"},"revision":5,"revision_timestamp":"2020-10-28T19:29:22.748Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2019-04-22T00:00:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/M/ML/MLEHMANN/Canary-Stability-2013.tar.gz","sortable_version":["2013","0","0"],"version":"2013","activestate_license_expression":"[\"UNKNOWN\"]","camel_extras":{"mm_fullext":"Canary/Stability"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/a5c91c62cf95fcb868f60eab5c832908f6905221013fea2bce3ff57046d7b6ea/Canary-Stability-2013.tar.gz","scanner_license_expression":"[\"UNKNOWN\"]","source_checksum":"a5c91c62cf95fcb868f60eab5c832908f6905221013fea2bce3ff57046d7b6ea","status":"stable","provided_features":[{"feature":"Canary-Stability","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","0","0"],"version":"2013"},{"feature":"Canary::Stability","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","0","0"],"version":"2013"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"bfe02625-c7d6-5604-ae04-2e5b4c9592a2","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["runtime"],"ingredient_version_id":"bc4acfbd-4c39-59fd-bc9c-62662b851b3d"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:21.454Z","ingredient_id":"d7097446-572b-5dd9-a9b8-3a3007254971","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d7097446-572b-5dd9-a9b8-3a3007254971"},"name":"JSON","normalized_name":"JSON","primary_namespace":"language/perl","description":"JSON (JavaScript Object Notation) encoder/decoder"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:21.454Z","ingredient_id":"d7097446-572b-5dd9-a9b8-3a3007254971","ingredient_version_id":"a64758c6-32a6-5c57-8c43-64a5e53d7309","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d7097446-572b-5dd9-a9b8-3a3007254971/versions/a64758c6-32a6-5c57-8c43-64a5e53d7309","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d7097446-572b-5dd9-a9b8-3a3007254971"},"revision":5,"revision_timestamp":"2020-10-28T19:30:10.278Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-12-21T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/I/IS/ISHIGAKI/JSON-2.97001.tar.gz","sortable_version":["2","970","10"],"version":"2.97001","activestate_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","camel_extras":{"mm_fullext":"JSON"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/e277d9385633574923f48c297e1b8acad3170c69fa590e31fa466040fc6f8f5a/JSON-2.97001.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"e277d9385633574923f48c297e1b8acad3170c69fa590e31fa466040fc6f8f5a","status":"stable","provided_features":[{"feature":"JSON","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","970","10"],"version":"2.97001"},{"feature":"JSON::Backend::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","970","10"],"version":"2.97001"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"JSON","namespace":"language/perl","version_requirements":[{"comparator":"eq","version":"2.97001"}]}]},{"alternatives":[],"artifact_id":"d51871fd-d270-5423-82b9-78b567c53636","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"09e2438e-36a3-534b-9626-f5a8825d84ad"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"9930b34d-2ad3-507f-912f-729e5bb4e3e1"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"},{"dependency_types":["runtime"],"ingredient_version_id":"f547017b-1726-5839-bb7f-214e420b2f66"}],"ingredient":{"creation_timestamp":"2020-05-28T03:27:37.165Z","ingredient_id":"7175217d-d9f2-5995-81ac-e02130308bff","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7175217d-d9f2-5995-81ac-e02130308bff"},"name":"JSON-XS","normalized_name":"JSON-XS","primary_namespace":"language/perl","description":"JSON serialising/deserialising, done correctly and fast"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-11-06T22:06:27.391Z","ingredient_id":"7175217d-d9f2-5995-81ac-e02130308bff","ingredient_version_id":"bc4acfbd-4c39-59fd-bc9c-62662b851b3d","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7175217d-d9f2-5995-81ac-e02130308bff/versions/bc4acfbd-4c39-59fd-bc9c-62662b851b3d","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7175217d-d9f2-5995-81ac-e02130308bff"},"revision":2,"revision_timestamp":"2020-11-06T22:08:22.659Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Marc A. Lehmann/JSON-XS-4.03","is_binary_only":false,"license_expression":"[\"UNKNOWN\"]","release_timestamp":"2020-10-27T22:06:42.000Z","source_uri":"https://cpan.metacpan.org/authors/id/M/ML/MLEHMANN/JSON-XS-4.03.tar.gz","sortable_version":["4","30","0"],"version":"4.03","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/515536f45f2fa1a7e88c8824533758d0121d267ab9cb453a1b5887c8a56b9068/JSON-XS-4.03.tar.gz","scanner_license_expression":"[\"UNKNOWN\"]","source_checksum":"515536f45f2fa1a7e88c8824533758d0121d267ab9cb453a1b5887c8a56b9068","status":"stable","provided_features":[{"feature":"JSON-XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","30","0"],"version":"4.03"},{"feature":"JSON::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","30","0"],"version":"4.03"}],"author_platform_user_id":"e51a58da-d22b-49c2-9fe6-f143159120eb","comment":"Data Acquisition import run with commit ID 480d651c28a7e7ec4c859026ee7769bf55b04eb3 and reason: Could not be determined from the database query","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c62e933c-7f68-5e94-8fcd-5f978e3825b4","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"09e2438e-36a3-534b-9626-f5a8825d84ad"},{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2020-05-28T04:02:06.763Z","ingredient_id":"39c3be00-6b88-5a55-84c4-73dc262804c8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/39c3be00-6b88-5a55-84c4-73dc262804c8"},"name":"Types-Serialiser","normalized_name":"Types-Serialiser","primary_namespace":"language/perl","description":"simple data types for common serialisation formats"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-28T04:02:06.763Z","ingredient_id":"39c3be00-6b88-5a55-84c4-73dc262804c8","ingredient_version_id":"f547017b-1726-5839-bb7f-214e420b2f66","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/39c3be00-6b88-5a55-84c4-73dc262804c8/versions/f547017b-1726-5839-bb7f-214e420b2f66","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/39c3be00-6b88-5a55-84c4-73dc262804c8"},"revision":3,"revision_timestamp":"2020-10-28T19:36:01.552Z","copyright_text":"TODO","documentation_uri":"https://metacpan.org/release/Marc A. Lehmann/Types-Serialiser-1.0","is_binary_only":false,"license_expression":"[\"UNKNOWN\"]","release_timestamp":"2013-12-01T02:33:51.000Z","source_uri":"https://cpan.metacpan.org/authors/id/M/ML/MLEHMANN/Types-Serialiser-1.0.tar.gz","sortable_version":["1","0","0"],"version":"1.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/7ad3347849d8a3da6470135018d6af5fd8e58b4057cd568c3813695f2a04730d/Types-Serialiser-1.0.tar.gz","scanner_license_expression":"[\"UNKNOWN\"]","source_checksum":"7ad3347849d8a3da6470135018d6af5fd8e58b4057cd568c3813695f2a04730d","status":"stable","provided_features":[{"feature":"Types-Serialiser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Types::Serialiser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Types::Serialiser::BooleanBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Types::Serialiser::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"added by migration to correct missing language core dependencies","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"279d6621-2756-5f82-b1d4-1bd7a41dfc57","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:55:32.137Z","ingredient_id":"e85cb0a8-36db-5b6c-85f3-eeb294932e62","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/e85cb0a8-36db-5b6c-85f3-eeb294932e62"},"name":"common-sense","normalized_name":"common-sense","primary_namespace":"language/perl","description":"save a tree AND a kitten, use common::sense!"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-11-06T22:12:09.083Z","ingredient_id":"e85cb0a8-36db-5b6c-85f3-eeb294932e62","ingredient_version_id":"09e2438e-36a3-534b-9626-f5a8825d84ad","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/e85cb0a8-36db-5b6c-85f3-eeb294932e62/versions/09e2438e-36a3-534b-9626-f5a8825d84ad","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/e85cb0a8-36db-5b6c-85f3-eeb294932e62"},"revision":2,"revision_timestamp":"2020-11-06T22:14:53.147Z","copyright_text":"Could not be determined","documentation_uri":"https://metacpan.org/release/Marc A. Lehmann/common-sense-3.75","is_binary_only":false,"license_expression":"[\"UNKNOWN\"]","release_timestamp":"2020-04-02T11:54:39.000Z","source_uri":"https://cpan.metacpan.org/authors/id/M/ML/MLEHMANN/common-sense-3.75.tar.gz","sortable_version":["3","750","0"],"version":"3.75","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/a86a1c4ca4f3006d7479064425a09fa5b6689e57261fcb994fe67d061cba0e7e/common-sense-3.75.tar.gz","scanner_license_expression":"[\"UNKNOWN\"]","source_checksum":"a86a1c4ca4f3006d7479064425a09fa5b6689e57261fcb994fe67d061cba0e7e","status":"stable","provided_features":[{"feature":"common-sense","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"common::sense","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"}],"author_platform_user_id":"e51a58da-d22b-49c2-9fe6-f143159120eb","comment":"Data Acquisition import run with commit ID 480d651c28a7e7ec4c859026ee7769bf55b04eb3 and reason: Could not be determined from the database query","is_stable_revision":true},"patches":null,"resolved_requirements":[]}],"solver_version":1} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-removed.json b/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-removed.json deleted file mode 100644 index 52f1bb3f8f..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-removed.json +++ /dev/null @@ -1 +0,0 @@ -{"camel_flags":[],"from_recipe_store":true,"image":{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"},"is_indemnified":false,"platform":{"cpu_architecture":{"cpu_architecture_id":"4cdba18d-0851-4925-9ae5-9c8a2987828a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a"},"bit_width":"64","name":"x86","provided_features":[{"feature":"x86 64-bit","is_activestate_version":false,"is_default_provider":true,"namespace":"cpu-architecture","sortable_version":["1","0"],"version":"1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"cpu_extensions":[],"creation_timestamp":"2021-01-15T18:05:36.924Z","display_name":"CentOS 8, Linux 4.18.0, glibc 2.28 x86 64-bit","end_of_support_date":"2025-12-31","images":[{"image_id":"00216735-694e-4ef8-a7d5-7724b9200be0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/00216735-694e-4ef8-a7d5-7724b9200be0"},"name":"docker-registry.activestate.build/activestate/centos-8-build","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","1","0"],"version":"1.1","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"eq","sortable_version":[]}]}],"revision":1,"revision_timestamp":"2021-01-15T18:07:52.645Z"},{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"}],"is_user_visible":true,"kernel":{"kernel_id":"ef737274-fff9-4164-b72b-88067613f822","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822"},"name":"Linux"},"kernel_version":{"kernel_version_id":"61f9365e-03ed-448f-9a24-2b845727e4f5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/61f9365e-03ed-448f-9a24-2b845727e4f5"},"sortable_version":["4","18","0","0"],"version":"4.18.0","provided_features":[{"feature":"Linux","is_activestate_version":false,"is_default_provider":true,"namespace":"kernel","sortable_version":["4","18","0","0"],"version":"4.18.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:04.588Z"},"libc":{"libc_id":"09a2eb42-ad34-4734-a93e-4b97395577df","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df"},"name":"glibc"},"libc_version":{"libc_version_id":"22d234e7-145e-4688-9d05-ee164b4ffa12","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/22d234e7-145e-4688-9d05-ee164b4ffa12"},"sortable_version":["2","28","0"],"version":"2.28","provided_features":[{"feature":"glibc","is_activestate_version":false,"is_default_provider":true,"namespace":"libc","sortable_version":["2","28","0"],"version":"2.28"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:19.136Z"},"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/7c998ec2-7491-4e75-be4d-8885800ef5f2"},"operating_system":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99"},"operating_system_id":"7b3a2dbb-d543-48d6-8390-7e7b63751e99","has_libc":true,"name":"CentOS"},"operating_system_version":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/42cab97b-9d80-407f-89a8-230836868e88"},"operating_system_version_id":"42cab97b-9d80-407f-89a8-230836868e88","sortable_version":["8","0"],"version":"8","provided_features":[{"feature":"CentOS","is_activestate_version":false,"is_default_provider":true,"namespace":"operating-system","sortable_version":["8","0"],"version":"8"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:50.448Z"},"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},"recipe_id":"aa21f7c8-85a7-5cc2-8ee8-f8bd3b342406","recipe_store_timestamp":"2021-02-04T17:59:12.286Z","resolved_ingredients":[{"alternatives":[],"artifact_id":"cf3d86c1-2587-564e-a7b2-0cf109ce263e","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:47:40.385Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"name":"perl-core-builder","normalized_name":"perl-core-builder","primary_namespace":"builder","description":"Builds the core Perl interpreter on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:58:38.567Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31/versions/d5ac8c7c-b025-5418-ab77-a139e60e1d41","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"revision":2,"revision_timestamp":"2020-10-30T17:04:06.702Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-06-25T07:05:14.000Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-core-builder","sortable_version":["1","0","23","0"],"version":"1.0.23","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374/perl-core-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-core-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","23","0"],"version":"1.0.23"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial builder for perl 5.30+","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:32.665Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"name":"perl","normalized_name":"perl","primary_namespace":"language","description":"Practical Extraction and Report Language"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-01-29T18:11:47.039Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206/versions/86005392-bdbf-59bd-a716-70ce7fcd3a66","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"revision":3,"revision_timestamp":"2021-02-03T21:14:56.873Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/S/SH/SHAY/perl-5.32.1.tar.gz","sortable_version":["5","32","1"],"version":"5.32.1","activestate_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/language/03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c/perl-5.32.1.tar.gz","scanner_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","source_checksum":"03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c","status":"stable","provided_features":[{"feature":"alternative-built-language","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1","0"],"version":"5.32.1"},{"feature":"perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1"],"version":"5.32.1"},{"feature":"Amiga::ARexx","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","50","0"],"version":"0.05"},{"feature":"Amiga::Exec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"App::Cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","676","0"],"version":"1.676"},{"feature":"App::Prove","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Archive::Tar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Attribute::Handlers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"AutoLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","740","0"],"version":"5.74"},{"feature":"AutoSplit","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"B","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","820","0"],"version":"1.82"},{"feature":"B::Concise","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.004"},{"feature":"B::Deparse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"B::Op_private","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"B::Showlex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"B::Terse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"B::Xref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Benchmark","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"CPAN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"CPAN::Author","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","500"],"version":"5.5005"},{"feature":"CPAN::CacheMgr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::DeferredCode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::Distribution","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Distroprefs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","0","100"],"version":"6.0001"},{"feature":"CPAN::Distrostatus","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::RecursiveDependency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Exception::blocked_urllist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"CPAN::Exception::yaml_not_installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::yaml_process_error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::FTP::netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"CPAN::FirstTime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","531","500"],"version":"5.5315"},{"feature":"CPAN::HTTP::Client","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HTTP::Credentials","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HandleConfig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","100"],"version":"5.5011"},{"feature":"CPAN::Index","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","120","0"],"version":"2.12"},{"feature":"CPAN::InfoObj","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Kwalify","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Converter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::History","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Merge","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Prereqs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Requirements","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","140","0"],"version":"2.140"},{"feature":"CPAN::Meta::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Validator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","18","0"],"version":"0.018"},{"feature":"CPAN::Mirrors","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Nox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","970","0"],"version":"0.97"},{"feature":"CPAN::Plugin::Specfile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"CPAN::Prompt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Shell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","900"],"version":"5.5009"},{"feature":"CPAN::Tarzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"Carp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Carp::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Class::Struct","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","660","0"],"version":"0.66"},{"feature":"Compress::Raw::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Raw::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"Config::Extensions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"Config::Perl::V","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"Cwd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"DB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"DBM_Filter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"DBM_Filter::compress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::int32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DB_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","855","0"],"version":"1.855"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","176","0"],"version":"2.176"},{"feature":"Devel::PPPort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","620","0"],"version":"3.62"},{"feature":"Devel::Peek","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Devel::SelfStubber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Digest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::MD5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","580","0"],"version":"2.58"},{"feature":"Digest::SHA","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","20","0"],"version":"6.02"},{"feature":"Digest::base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"DirHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Dumpvalue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"DynaLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"Encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","80","0"],"version":"3.08"},{"feature":"Encode::Alias","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"Encode::Byte","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::CJKConstants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::CN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::CN::HZ","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"Encode::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.05"},{"feature":"Encode::EBCDIC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::Encoder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::GSM0338","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"Encode::Guess","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::JP::H2Z","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::JP::JIS7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::KR::2022_KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::MIME::Header","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"Encode::MIME::Header::ISO_2022_JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Encode::MIME::Name","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Encode::Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::TW","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"Encode::Unicode::UTF7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"English","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Errno","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"Exporter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"Exporter::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","250","0"],"version":"0.25"},{"feature":"ExtUtils::Constant::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"ExtUtils::Constant::ProxySubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"ExtUtils::Constant::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"ExtUtils::Constant::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"ExtUtils::Embed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","350","0"],"version":"1.35"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","730","0"],"version":"1.73"},{"feature":"ExtUtils::Miniperl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::ParseXS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::CountLines","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Eval","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::Typemaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::InputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::OutputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Type","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::XSSymSet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.4"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"Fatal","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"Fcntl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","140","0"],"version":"1.14"},{"feature":"File::Basename","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","850","0"],"version":"2.85"},{"feature":"File::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","600"],"version":"1.1006"},{"feature":"File::Copy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","350","0"],"version":"2.35"},{"feature":"File::DosGlob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"File::Fetch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.00"},{"feature":"File::Find","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","380","0"],"version":"1.38"},{"feature":"File::Glob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"File::GlobMapper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"File::Path","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Temp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","231","100"],"version":"0.2311"},{"feature":"File::stat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"FileCache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"FileHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Filter::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","960","0"],"version":"0.96"},{"feature":"Filter::Util::Call","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","600","0"],"version":"1.60"},{"feature":"FindBin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"GDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","520","0"],"version":"2.52"},{"feature":"Getopt::Std","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"HTTP::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","76","0"],"version":"0.076"},{"feature":"Hash::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","240","0"],"version":"0.24"},{"feature":"Hash::Util::FieldHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"I18N::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"I18N::LangTags","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","450","0"],"version":"0.45"},{"feature":"I18N::LangTags::Detect","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"I18N::LangTags::List","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","400","0"],"version":"0.40"},{"feature":"I18N::Langinfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","190","0"],"version":"0.19"},{"feature":"IO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Compress::Adapter::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base::Common","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::RawDeflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Extra","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Dir","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Pipe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Poll","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Seekable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Select","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::INET","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::IP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"IO::Socket::UNIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Uncompress::Adapter::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyUncompress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Gunzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::RawInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Unzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"IPC::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"IPC::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::Open2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"IPC::Open3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"IPC::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SharedMem","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SysV","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Locale::Maketext","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Locale::Maketext::Guts","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::GutsLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","100"],"version":"0.21_01"},{"feature":"MIME::Base64","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"MIME::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"Math::BigFloat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigFloat::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigInt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Calc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::FastCalc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","500","900"],"version":"0.5009"},{"feature":"Math::BigInt::Lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigRat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","261","400"],"version":"0.2614"},{"feature":"Math::Complex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","590","200"],"version":"1.5902"},{"feature":"Math::Trig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","100"],"version":"1.03_01"},{"feature":"Memoize::AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Expire","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireTest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Module::CoreList","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::CoreList::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::Load","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"Module::Load::Conditional","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","740","0"],"version":"0.74"},{"feature":"Module::Loaded","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","80","0"],"version":"0.08"},{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","37"],"version":"1.000037"},{"feature":"Moped::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10","0"],"version":"0.01"},{"feature":"NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"NEXT","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","670","100"],"version":"0.67_01"},{"feature":"Net::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Domain","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::A","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::E","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::I","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::L","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::dataconn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::NNTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::POP3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Ping","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","740","0"],"version":"2.74"},{"feature":"Net::SMTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Time","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::hostent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Net::netent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::protoent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::servent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"O","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"ODBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"OS2::DLL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"OS2::ExtAttr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::PrfDB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"OS2::REXX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Opcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","490","0"],"version":"1.49"},{"feature":"POSIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","970","0"],"version":"1.97"},{"feature":"Params::Check","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","380","0"],"version":"0.38"},{"feature":"Parse::CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"Perl::OSType","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.010"},{"feature":"PerlIO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"PerlIO::encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","0"],"version":"0.28"},{"feature":"PerlIO::mmap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.017"},{"feature":"PerlIO::scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","310","0"],"version":"0.31"},{"feature":"PerlIO::via","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"PerlIO::via::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"Pod::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","740","0"],"version":"1.74"},{"feature":"Pod::Escapes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Pod::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Functions::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Html","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Perldoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","100"],"version":"3.2801"},{"feature":"Pod::Perldoc::BaseTo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::GetOptsOO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToChecker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToMan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToNroff","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToPod","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToRtf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTerm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTk","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToXml","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::BlackBox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsXML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLBatch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLLegacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Pod::Simple::LinkSection","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Methody","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Progress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserEndToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserStartToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserTextToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::RTF","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Search","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::SimpleTree","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TextContent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TiedOutFH","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Transcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeDumb","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeSmart","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XHTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XMLOutStream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Usage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.01"},{"feature":"SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"Safe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","430","0"],"version":"2.43"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Search::Dict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"SelectSaver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"SelfLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.030"},{"feature":"Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","230","0"],"version":"3.23"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Sys::Hostname","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Sys::Syslog","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"TAP::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::ParallelSession","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness::Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Aggregator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Grammar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::IteratorFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Multiplexer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Bailout","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Comment","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Pragma","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Unknown","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::ResultFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Job","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Spinner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Source","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Executable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::RawTAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Reader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Writer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Term::ANSIColor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Term::Cap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Term::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","403","0"],"version":"1.403"},{"feature":"Term::ReadLine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","310","0"],"version":"1.31"},{"feature":"Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","114","0"],"version":"2.114"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Text::Abbrev","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Text::Balanced","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Text::ParseWords","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","300","0"],"version":"3.30"},{"feature":"Text::Tabs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Text::Wrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Thread","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","50","0"],"version":"3.05"},{"feature":"Thread::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","140","0"],"version":"3.14"},{"feature":"Thread::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","130","0"],"version":"2.13"},{"feature":"Tie::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Tie::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Tie::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","200","0"],"version":"4.2"},{"feature":"Tie::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::Hash::NamedCapture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"Tie::Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"Tie::RefHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.40"},{"feature":"Tie::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::StdHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","600","0"],"version":"4.6"},{"feature":"Tie::SubstrHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Time::HiRes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","976","600"],"version":"1.9766"},{"feature":"Time::Local","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Time::Piece","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::Seconds","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::gmtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"Time::localtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Time::tm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"UNIVERSAL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["13","0","0"],"version":"13.0.0"},{"feature":"Unicode::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Big5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::GB2312","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::JISX0208","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Korean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Pinyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Stroke","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Zhuyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Normalize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","280","0"],"version":"1.28"},{"feature":"Unicode::UCD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","750","0"],"version":"0.75"},{"feature":"User::grent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"User::pwent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"VMS::DCLsym","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"VMS::Filespec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"VMS::Stdio","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","450","0"],"version":"2.45"},{"feature":"Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","540","0"],"version":"0.54"},{"feature":"Win32API::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","120","301"],"version":"0.1203_01"},{"feature":"Win32API::File::inc::ExtUtils::Myconst2perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1"},{"feature":"Win32CORE","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"XS::APItest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"XS::Typemap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"XSLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","300","0"],"version":"0.30"},{"feature":"_charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"attributes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"autodie","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::GuardStack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception::system","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::hints","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autouse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"bigint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bignum","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bigrat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"blib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"bytes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"deprecate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"diagnostics","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","370","0"],"version":"1.37"},{"feature":"encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","0","0"],"version":"3.00"},{"feature":"encoding::warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"experimental","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","22","0"],"version":"0.022"},{"feature":"feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"fields","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"filetest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"if","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","900"],"version":"0.0609"},{"feature":"integer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"less","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","650","0"],"version":"0.65"},{"feature":"locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"mro","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","250","0"],"version":"1.25"},{"feature":"ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"open","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"ops","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"overload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"overloading","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","238","0"],"version":"0.238"},{"feature":"perlfaq","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","11","70"],"version":"5.20201107"},{"feature":"re","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"sigtrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"sort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"strict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"subs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"threads","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","260","0"],"version":"2.26"},{"feature":"threads::shared","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","240","0"],"version":"1.24"},{"feature":"vars","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"vmsish","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"warnings::register","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Bump again","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"perl","namespace":"language","version_requirements":[{"comparator":"eq","version":"5.32.1"}]}]}],"solver_version":1} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-update.json b/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-update.json deleted file mode 100644 index 4c3c489cd7..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/perl-alternative-one-update.json +++ /dev/null @@ -1 +0,0 @@ -{"camel_flags":[],"from_recipe_store":true,"image":{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"},"is_indemnified":false,"platform":{"cpu_architecture":{"cpu_architecture_id":"4cdba18d-0851-4925-9ae5-9c8a2987828a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a"},"bit_width":"64","name":"x86","provided_features":[{"feature":"x86 64-bit","is_activestate_version":false,"is_default_provider":true,"namespace":"cpu-architecture","sortable_version":["1","0"],"version":"1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"cpu_extensions":[],"creation_timestamp":"2021-01-15T18:05:36.924Z","display_name":"CentOS 8, Linux 4.18.0, glibc 2.28 x86 64-bit","end_of_support_date":"2025-12-31","images":[{"image_id":"00216735-694e-4ef8-a7d5-7724b9200be0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/00216735-694e-4ef8-a7d5-7724b9200be0"},"name":"docker-registry.activestate.build/activestate/centos-8-build","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","1","0"],"version":"1.1","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"eq","sortable_version":[]}]}],"revision":1,"revision_timestamp":"2021-01-15T18:07:52.645Z"},{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","13","0"],"version":"1.13","provided_features":[{"feature":"GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"compiler","sortable_version":["8","3","0"],"version":"8.3"},{"feature":"GNU C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"GNU C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++03","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++11","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++14","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C89","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C++98","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO C99","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 77","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 90","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"},{"feature":"ISO Fortran 95","is_activestate_version":true,"is_default_provider":true,"namespace":"compiler","sortable_version":["0","0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1","0"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0","0"],"version":"0"}]}],"revision":1,"revision_timestamp":"2021-02-02T15:39:53.469Z"}],"is_user_visible":true,"kernel":{"kernel_id":"ef737274-fff9-4164-b72b-88067613f822","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822"},"name":"Linux"},"kernel_version":{"kernel_version_id":"61f9365e-03ed-448f-9a24-2b845727e4f5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/61f9365e-03ed-448f-9a24-2b845727e4f5"},"sortable_version":["4","18","0","0"],"version":"4.18.0","provided_features":[{"feature":"Linux","is_activestate_version":false,"is_default_provider":true,"namespace":"kernel","sortable_version":["4","18","0","0"],"version":"4.18.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:04.588Z"},"libc":{"libc_id":"09a2eb42-ad34-4734-a93e-4b97395577df","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df"},"name":"glibc"},"libc_version":{"libc_version_id":"22d234e7-145e-4688-9d05-ee164b4ffa12","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/22d234e7-145e-4688-9d05-ee164b4ffa12"},"sortable_version":["2","28","0"],"version":"2.28","provided_features":[{"feature":"glibc","is_activestate_version":false,"is_default_provider":true,"namespace":"libc","sortable_version":["2","28","0"],"version":"2.28"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:19.136Z"},"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/7c998ec2-7491-4e75-be4d-8885800ef5f2"},"operating_system":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99"},"operating_system_id":"7b3a2dbb-d543-48d6-8390-7e7b63751e99","has_libc":true,"name":"CentOS"},"operating_system_version":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/42cab97b-9d80-407f-89a8-230836868e88"},"operating_system_version_id":"42cab97b-9d80-407f-89a8-230836868e88","sortable_version":["8","0"],"version":"8","provided_features":[{"feature":"CentOS","is_activestate_version":false,"is_default_provider":true,"namespace":"operating-system","sortable_version":["8","0"],"version":"8"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:50.448Z"},"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},"recipe_id":"631c1698-0af4-5b38-ac98-2f8df4220b79","recipe_store_timestamp":"2021-02-20T07:47:23.762Z","resolved_ingredients":[{"alternatives":[],"artifact_id":"cf3d86c1-2587-564e-a7b2-0cf109ce263e","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:47:40.385Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"name":"perl-core-builder","normalized_name":"perl-core-builder","primary_namespace":"builder","description":"Builds the core Perl interpreter on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:58:38.567Z","ingredient_id":"a4128de4-f62c-5349-80e6-b072d5aa3e31","ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31/versions/d5ac8c7c-b025-5418-ab77-a139e60e1d41","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a4128de4-f62c-5349-80e6-b072d5aa3e31"},"revision":2,"revision_timestamp":"2020-10-30T17:04:06.702Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-06-25T07:05:14.000Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-core-builder","sortable_version":["1","0","23","0"],"version":"1.0.23","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374/perl-core-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"cb4bd9b790715ae38f4bbc1acffafb5b3d7d328fcfe29974e60ded1fece45374","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-core-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","23","0"],"version":"1.0.23"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial builder for perl 5.30+","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"a1ebbc88-daeb-5588-8086-c99de70eabf7","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"ed446cc4-4e4d-5986-ad77-ed04a3b2e58b"}],"ingredient":{"creation_timestamp":"2020-08-10T23:48:55.390Z","ingredient_id":"196722f9-5600-5d89-9c47-42460922fdb1","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1"},"name":"perl-module-builder","normalized_name":"perl-module-builder","primary_namespace":"builder","description":"Builds Perl modules on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-12-07T20:54:12.006Z","ingredient_id":"196722f9-5600-5d89-9c47-42460922fdb1","ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1/versions/c4164b54-9b8f-55fc-ae5a-cd47c6389687","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/196722f9-5600-5d89-9c47-42460922fdb1"},"revision":1,"revision_timestamp":"2020-12-07T20:54:12.006Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-12-07T20:23:01.043Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-module-builder","sortable_version":["1","0","36","0"],"version":"1.0.36","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/bb8bb535334fb012df0550a528692f4826893b91b055ac73ffb37dd00322a7b6/perl-module-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"bb8bb535334fb012df0550a528692f4826893b91b055ac73ffb37dd00322a7b6","status":"stable","provided_features":[{"feature":"alternative-builder","is_activestate_version":false,"is_default_provider":false,"namespace":"builder","sortable_version":["1","0","0","0"],"version":"1.0.0"},{"feature":"perl-module-builder","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["1","0","36","0"],"version":"1.0.36"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Created new version 1.0.36 from 1.0.35.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"f7c88044-fdcd-5023-a0ce-9c4a6fcc2708","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-08-10T23:48:13.169Z","ingredient_id":"4c0fd8d2-5c39-5ecf-958e-325efdea1ef2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2"},"name":"perl-module-lib","normalized_name":"perl-module-lib","primary_namespace":"builder-lib","description":"Builds Perl modules on the ActiveState platform.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-12-07T20:54:42.776Z","ingredient_id":"4c0fd8d2-5c39-5ecf-958e-325efdea1ef2","ingredient_version_id":"ed446cc4-4e4d-5986-ad77-ed04a3b2e58b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2/versions/ed446cc4-4e4d-5986-ad77-ed04a3b2e58b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c0fd8d2-5c39-5ecf-958e-325efdea1ef2"},"revision":2,"revision_timestamp":"2020-12-10T17:22:10.292Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"(MIT-1.0)","release_timestamp":"2020-12-07T20:25:59.954Z","source_uri":"https://github.com/ActiveState/platform-builders/builders/perl-module-lib","sortable_version":["1","0","36","0"],"version":"1.0.36","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/abdb22574b2300f30e98ab9239892f379c0c60bf33634a2b49518bddc730413d/perl-module-lib.tar.gz","scanner_license_expression":"unknown","source_checksum":"abdb22574b2300f30e98ab9239892f379c0c60bf33634a2b49518bddc730413d","status":"stable","provided_features":[{"feature":"perl-module-lib","is_activestate_version":false,"is_default_provider":true,"namespace":"builder-lib","sortable_version":["1","0","36","0"],"version":"1.0.36"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"Created new version 1.0.36 from 1.0.35.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"b30ab2e5-4074-572c-8146-da692b1c9e45","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"d5ac8c7c-b025-5418-ab77-a139e60e1d41"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:32.665Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"name":"perl","normalized_name":"perl","primary_namespace":"language","description":"Practical Extraction and Report Language"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-01-29T18:11:47.039Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206/versions/86005392-bdbf-59bd-a716-70ce7fcd3a66","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"revision":3,"revision_timestamp":"2021-02-03T21:14:56.873Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/S/SH/SHAY/perl-5.32.1.tar.gz","sortable_version":["5","32","1"],"version":"5.32.1","activestate_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/language/03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c/perl-5.32.1.tar.gz","scanner_license_expression":"[\" GPL-1.0-or-later\",\"Artistic-1.0-Perl\"]","source_checksum":"03b693901cd8ae807231b1787798cf1f2e0b8a56218d07b7da44f784a7caeb2c","status":"stable","provided_features":[{"feature":"alternative-built-language","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1","0"],"version":"5.32.1"},{"feature":"perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","32","1"],"version":"5.32.1"},{"feature":"Amiga::ARexx","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","50","0"],"version":"0.05"},{"feature":"Amiga::Exec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"App::Cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","676","0"],"version":"1.676"},{"feature":"App::Prove","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"App::Prove::State::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Archive::Tar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Archive::Tar::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","380","0"],"version":"2.38"},{"feature":"Attribute::Handlers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"AutoLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","740","0"],"version":"5.74"},{"feature":"AutoSplit","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"B","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","820","0"],"version":"1.82"},{"feature":"B::Concise","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.004"},{"feature":"B::Deparse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"B::Op_private","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"B::Showlex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"B::Terse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"B::Xref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Benchmark","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"CPAN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"CPAN::Author","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","500"],"version":"5.5005"},{"feature":"CPAN::CacheMgr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","200"],"version":"5.5002"},{"feature":"CPAN::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::DeferredCode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::Distribution","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Distroprefs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","0","100"],"version":"6.0001"},{"feature":"CPAN::Distrostatus","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::RecursiveDependency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Exception::blocked_urllist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"CPAN::Exception::yaml_not_installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Exception::yaml_process_error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::FTP::netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"CPAN::FirstTime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","531","500"],"version":"5.5315"},{"feature":"CPAN::HTTP::Client","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HTTP::Credentials","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::HandleConfig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","100"],"version":"5.5011"},{"feature":"CPAN::Index","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","120","0"],"version":"2.12"},{"feature":"CPAN::InfoObj","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Kwalify","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.50"},{"feature":"CPAN::LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","960","100"],"version":"1.9601"},{"feature":"CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Converter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::History","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Merge","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Prereqs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Requirements","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","140","0"],"version":"2.140"},{"feature":"CPAN::Meta::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::Validator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"CPAN::Meta::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","18","0"],"version":"0.018"},{"feature":"CPAN::Mirrors","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"CPAN::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Nox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","100"],"version":"5.5001"},{"feature":"CPAN::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","970","0"],"version":"0.97"},{"feature":"CPAN::Plugin::Specfile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"CPAN::Prompt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"CPAN::Shell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","900"],"version":"5.5009"},{"feature":"CPAN::Tarzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","501","300"],"version":"5.5013"},{"feature":"CPAN::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","0"],"version":"5.5"},{"feature":"CPAN::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","500","300"],"version":"5.5003"},{"feature":"Carp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Carp::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"Class::Struct","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","660","0"],"version":"0.66"},{"feature":"Compress::Raw::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Raw::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Compress::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","33","6"],"version":"5.033006"},{"feature":"Config::Extensions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"Config::Perl::V","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"Cwd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"DB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"DBM_Filter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"DBM_Filter::compress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::int32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DBM_Filter::utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"DB_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","855","0"],"version":"1.855"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","176","0"],"version":"2.176"},{"feature":"Devel::PPPort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","620","0"],"version":"3.62"},{"feature":"Devel::Peek","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Devel::SelfStubber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Digest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::MD5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","580","0"],"version":"2.58"},{"feature":"Digest::SHA","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","20","0"],"version":"6.02"},{"feature":"Digest::base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Digest::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"DirHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Dumpvalue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"DynaLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"Encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","80","0"],"version":"3.08"},{"feature":"Encode::Alias","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"Encode::Byte","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::CJKConstants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::CN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::CN::HZ","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"Encode::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.05"},{"feature":"Encode::EBCDIC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::Encoder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::GSM0338","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"Encode::Guess","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::JP::H2Z","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::JP::JIS7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","80","0"],"version":"2.08"},{"feature":"Encode::KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::KR::2022_KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Encode::MIME::Header","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","280","0"],"version":"2.28"},{"feature":"Encode::MIME::Header::ISO_2022_JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Encode::MIME::Name","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Encode::Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.02"},{"feature":"Encode::TW","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Encode::Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"Encode::Unicode::UTF7","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.10"},{"feature":"English","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Errno","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"Exporter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"Exporter::Heavy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","760","0"],"version":"5.76"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","235"],"version":"0.280235"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","250","0"],"version":"0.25"},{"feature":"ExtUtils::Constant::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","0"],"version":"0.06"},{"feature":"ExtUtils::Constant::ProxySubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"ExtUtils::Constant::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"ExtUtils::Constant::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"ExtUtils::Embed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","350","0"],"version":"1.35"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","730","0"],"version":"1.73"},{"feature":"ExtUtils::Miniperl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","200","0"],"version":"2.20"},{"feature":"ExtUtils::ParseXS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::CountLines","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Eval","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::ParseXS::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"ExtUtils::Typemaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::InputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::OutputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Type","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","380","0"],"version":"3.38"},{"feature":"ExtUtils::XSSymSet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.4"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","580","0"],"version":"7.58"},{"feature":"Fatal","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"Fcntl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","140","0"],"version":"1.14"},{"feature":"File::Basename","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","850","0"],"version":"2.85"},{"feature":"File::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","600"],"version":"1.1006"},{"feature":"File::Copy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","350","0"],"version":"2.35"},{"feature":"File::DosGlob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"File::Fetch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.00"},{"feature":"File::Find","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","380","0"],"version":"1.38"},{"feature":"File::Glob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"File::GlobMapper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.001"},{"feature":"File::Path","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","180","0"],"version":"2.18"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","800","0"],"version":"3.80"},{"feature":"File::Temp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","231","100"],"version":"0.2311"},{"feature":"File::stat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"FileCache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"FileHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.03"},{"feature":"Filter::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","960","0"],"version":"0.96"},{"feature":"Filter::Util::Call","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","600","0"],"version":"1.60"},{"feature":"FindBin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","520","0"],"version":"1.52"},{"feature":"GDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","190","0"],"version":"1.19"},{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","520","0"],"version":"2.52"},{"feature":"Getopt::Std","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"HTTP::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","76","0"],"version":"0.076"},{"feature":"Hash::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","240","0"],"version":"0.24"},{"feature":"Hash::Util::FieldHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"I18N::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"I18N::LangTags","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","450","0"],"version":"0.45"},{"feature":"I18N::LangTags::Detect","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","80","0"],"version":"1.08"},{"feature":"I18N::LangTags::List","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","400","0"],"version":"0.40"},{"feature":"I18N::Langinfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","190","0"],"version":"0.19"},{"feature":"IO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Compress::Adapter::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Base::Common","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Bzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Deflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Gzip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::RawDeflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zip::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Compress::Zlib::Extra","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Dir","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Pipe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Poll","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Seekable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Select","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::INET","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Socket::IP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"IO::Socket::UNIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","450","0"],"version":"1.45"},{"feature":"IO::Uncompress::Adapter::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Identity","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Adapter::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::AnyUncompress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Bunzip2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Gunzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Inflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::RawInflate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Uncompress::Unzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","100","0"],"version":"2.100"},{"feature":"IO::Zlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"IPC::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"IPC::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::Open2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"IPC::Open3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","210","0"],"version":"1.21"},{"feature":"IPC::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SharedMem","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"IPC::SysV","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","90","0"],"version":"2.09"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","50","0"],"version":"4.05"},{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Locale::Maketext","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Locale::Maketext::Guts","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::GutsLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","200","0"],"version":"1.20"},{"feature":"Locale::Maketext::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","210","100"],"version":"0.21_01"},{"feature":"MIME::Base64","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"MIME::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","160","0"],"version":"3.16"},{"feature":"Math::BigFloat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigFloat::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigInt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Calc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::FastCalc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","500","900"],"version":"0.5009"},{"feature":"Math::BigInt::Lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","999","818"],"version":"1.999818"},{"feature":"Math::BigInt::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"Math::BigRat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","261","400"],"version":"0.2614"},{"feature":"Math::Complex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","590","200"],"version":"1.5902"},{"feature":"Math::Trig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","100"],"version":"1.03_01"},{"feature":"Memoize::AnyDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Expire","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::ExpireTest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Memoize::Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Module::CoreList","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::CoreList::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","101","230"],"version":"5.20210123"},{"feature":"Module::Load","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"Module::Load::Conditional","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","740","0"],"version":"0.74"},{"feature":"Module::Loaded","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","80","0"],"version":"0.08"},{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","37"],"version":"1.000037"},{"feature":"Moped::Msg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10","0"],"version":"0.01"},{"feature":"NDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"NEXT","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","670","100"],"version":"0.67_01"},{"feature":"Net::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Domain","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::A","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::E","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::I","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::L","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::FTP::dataconn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::NNTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::POP3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Ping","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","740","0"],"version":"2.74"},{"feature":"Net::SMTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::Time","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","130","0"],"version":"3.13"},{"feature":"Net::hostent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Net::netent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::protoent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"Net::servent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"O","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"ODBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"OS2::DLL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"OS2::ExtAttr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::PrfDB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"OS2::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"OS2::REXX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Opcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","490","0"],"version":"1.49"},{"feature":"POSIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","970","0"],"version":"1.97"},{"feature":"Params::Check","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","380","0"],"version":"0.38"},{"feature":"Parse::CPAN::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","150","10"],"version":"2.150010"},{"feature":"Perl::OSType","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.010"},{"feature":"PerlIO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"PerlIO::encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","280","0"],"version":"0.28"},{"feature":"PerlIO::mmap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.017"},{"feature":"PerlIO::scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","310","0"],"version":"0.31"},{"feature":"PerlIO::via","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"PerlIO::via::QuotedPrint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","90","0"],"version":"0.09"},{"feature":"Pod::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","740","0"],"version":"1.74"},{"feature":"Pod::Escapes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Pod::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Functions::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Pod::Html","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Perldoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","100"],"version":"3.2801"},{"feature":"Pod::Perldoc::BaseTo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::GetOptsOO","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToChecker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToMan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToNroff","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToPod","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToRtf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTerm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTk","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToXml","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","280","0"],"version":"3.28"},{"feature":"Pod::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::BlackBox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Checker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsText","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::DumpAsXML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLBatch","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::HTMLLegacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Pod::Simple::LinkSection","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Methody","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Progress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserEndToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserStartToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserTextToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::PullParserToken","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::RTF","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Search","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::SimpleTree","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TextContent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TiedOutFH","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::Transcode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeDumb","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::TranscodeSmart","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XHTML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Simple::XMLOutStream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","420","0"],"version":"3.42"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","140","0"],"version":"4.14"},{"feature":"Pod::Usage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.01"},{"feature":"SDBM_File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"Safe","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","430","0"],"version":"2.43"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Search::Dict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"SelectSaver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"SelfLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","260","0"],"version":"1.26"},{"feature":"Socket","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.030"},{"feature":"Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","230","0"],"version":"3.23"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","550","0"],"version":"1.55"},{"feature":"Symbol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"Sys::Hostname","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","230","0"],"version":"1.23"},{"feature":"Sys::Syslog","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","360","0"],"version":"0.36"},{"feature":"TAP::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::ParallelSession","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Console::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::File::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Formatter::Session","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Harness::Env","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Object","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Aggregator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Grammar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Process","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Iterator::Stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::IteratorFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Multiplexer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Bailout","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Comment","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Pragma","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Unknown","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Result::YAML","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::ResultFactory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Job","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Scheduler::Spinner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::Source","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Executable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::Perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::SourceHandler::RawTAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Reader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"TAP::Parser::YAMLish::Writer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Term::ANSIColor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","10","0"],"version":"5.01"},{"feature":"Term::Cap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Term::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","403","0"],"version":"1.403"},{"feature":"Term::ReadLine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","170","0"],"version":"1.17"},{"feature":"Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","310","0"],"version":"1.31"},{"feature":"Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Info::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","114","0"],"version":"2.114"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Harness","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","430","0"],"version":"3.43"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"Text::Abbrev","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"Text::Balanced","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"Text::ParseWords","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","300","0"],"version":"3.30"},{"feature":"Text::Tabs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Text::Wrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2013","52","300"],"version":"2013.0523"},{"feature":"Thread","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","50","0"],"version":"3.05"},{"feature":"Thread::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","140","0"],"version":"3.14"},{"feature":"Thread::Semaphore","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","130","0"],"version":"2.13"},{"feature":"Tie::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"Tie::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","60","0"],"version":"1.06"},{"feature":"Tie::Handle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","200","0"],"version":"4.2"},{"feature":"Tie::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::Hash::NamedCapture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"Tie::Memoize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.1"},{"feature":"Tie::RefHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","400","0"],"version":"1.40"},{"feature":"Tie::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"Tie::StdHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","600","0"],"version":"4.6"},{"feature":"Tie::SubstrHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Time::HiRes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","976","600"],"version":"1.9766"},{"feature":"Time::Local","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","300","0"],"version":"1.30"},{"feature":"Time::Piece","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::Seconds","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","340","100"],"version":"1.3401"},{"feature":"Time::gmtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"Time::localtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"Time::tm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"UNIVERSAL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","130","0"],"version":"1.13"},{"feature":"Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["13","0","0"],"version":"13.0.0"},{"feature":"Unicode::Collate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Big5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::GB2312","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::JISX0208","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Korean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Pinyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Stroke","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::CJK::Zhuyin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Collate::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","290","0"],"version":"1.29"},{"feature":"Unicode::Normalize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","280","0"],"version":"1.28"},{"feature":"Unicode::UCD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","750","0"],"version":"0.75"},{"feature":"User::grent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"User::pwent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"VMS::DCLsym","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"VMS::Filespec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"VMS::Stdio","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","450","0"],"version":"2.45"},{"feature":"Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","540","0"],"version":"0.54"},{"feature":"Win32API::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","120","301"],"version":"0.1203_01"},{"feature":"Win32API::File::inc::ExtUtils::Myconst2perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1"},{"feature":"Win32CORE","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"XS::APItest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","150","0"],"version":"1.15"},{"feature":"XS::Typemap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","180","0"],"version":"0.18"},{"feature":"XSLoader","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","300","0"],"version":"0.30"},{"feature":"_charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"attributes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","330","0"],"version":"0.33"},{"feature":"autodie","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::Guard","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Scope::GuardStack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::exception::system","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::hints","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autodie::skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","320","0"],"version":"2.32"},{"feature":"autouse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","110","0"],"version":"1.11"},{"feature":"base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","270","0"],"version":"2.27"},{"feature":"bigint","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bignum","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"bigrat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","510","0"],"version":"0.51"},{"feature":"blib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"bytes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.07"},{"feature":"charnames","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","480","0"],"version":"1.48"},{"feature":"constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"deprecate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.04"},{"feature":"diagnostics","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","370","0"],"version":"1.37"},{"feature":"encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","0","0"],"version":"3.00"},{"feature":"encoding::warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","130","0"],"version":"0.13"},{"feature":"experimental","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","22","0"],"version":"0.022"},{"feature":"feature","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"fields","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","240","0"],"version":"2.24"},{"feature":"filetest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.03"},{"feature":"if","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","60","900"],"version":"0.0609"},{"feature":"integer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.01"},{"feature":"less","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.03"},{"feature":"lib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","650","0"],"version":"0.65"},{"feature":"locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","100","0"],"version":"1.10"},{"feature":"mro","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","250","0"],"version":"1.25"},{"feature":"ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","183"],"version":"1.302183"},{"feature":"open","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"ops","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.02"},{"feature":"overload","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","330","0"],"version":"1.33"},{"feature":"overloading","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","20","0"],"version":"0.02"},{"feature":"parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","238","0"],"version":"0.238"},{"feature":"perlfaq","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","202","11","70"],"version":"5.20201107"},{"feature":"re","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","410","0"],"version":"0.41"},{"feature":"sigtrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","90","0"],"version":"1.09"},{"feature":"sort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.04"},{"feature":"strict","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","120","0"],"version":"1.12"},{"feature":"subs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"threads","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","260","0"],"version":"2.26"},{"feature":"threads::shared","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","620","0"],"version":"1.62"},{"feature":"utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","240","0"],"version":"1.24"},{"feature":"vars","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.05"},{"feature":"version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","992","800"],"version":"0.9928"},{"feature":"vmsish","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"},{"feature":"warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","500","0"],"version":"1.50"},{"feature":"warnings::register","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","40","0"],"version":"1.04"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Bump again","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"perl","namespace":"language","version_requirements":[{"comparator":"eq","version":"5.32.1"}]}]},{"alternatives":[],"artifact_id":"f56acc9c-dd02-5cf8-97f9-a5cd015f4c7b","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime","test"],"ingredient_version_id":"86005392-bdbf-59bd-a716-70ce7fcd3a66"},{"dependency_types":["build"],"ingredient_version_id":"c4164b54-9b8f-55fc-ae5a-cd47c6389687"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:21.454Z","ingredient_id":"d7097446-572b-5dd9-a9b8-3a3007254971","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d7097446-572b-5dd9-a9b8-3a3007254971"},"name":"JSON","normalized_name":"JSON","primary_namespace":"language/perl","description":"JSON (JavaScript Object Notation) encoder/decoder"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-28T17:12:38.349Z","ingredient_id":"d7097446-572b-5dd9-a9b8-3a3007254971","ingredient_version_id":"9c52ef68-d833-59c7-a537-4d20efd2d728","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d7097446-572b-5dd9-a9b8-3a3007254971/versions/9c52ef68-d833-59c7-a537-4d20efd2d728","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d7097446-572b-5dd9-a9b8-3a3007254971"},"revision":4,"revision_timestamp":"2020-10-28T22:29:07.800Z","copyright_text":"TODO","documentation_uri":"https://metacpan.org/release/Kenichi Ishigaki/JSON-4.02","is_binary_only":false,"license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","release_timestamp":"2019-02-23T10:26:27.000Z","source_uri":"https://cpan.metacpan.org/authors/id/I/IS/ISHIGAKI/JSON-4.02.tar.gz","sortable_version":["4","20","0"],"version":"4.02","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"JSON"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/data-acquisition/444a88755a89ffa2a5424ab4ed1d11dca61808ebef57e81243424619a9e8627c/JSON-4.02.tar.gz","scanner_license_expression":"[\"Artistic-1.0-Perl, GPL-1.0-or-later\"]","source_checksum":"444a88755a89ffa2a5424ab4ed1d11dca61808ebef57e81243424619a9e8627c","status":"stable","provided_features":[{"feature":"JSON","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","20","0"],"version":"4.02"},{"feature":"JSON::Backend::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","20","0"],"version":"4.02"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"Adding alternative builder dependency if Perl version \u003e= 5.30","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"JSON","namespace":"language/perl","version_requirements":[{"comparator":"eq","version":"4.02"}]}]}],"solver_version":1} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/recipes/perl-recipe.json b/pkg/platform/runtime/testhelper/data/recipes/perl-recipe.json deleted file mode 100644 index fa3b32b605..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/perl-recipe.json +++ /dev/null @@ -1 +0,0 @@ -{"camel_flags":[],"from_recipe_store":true,"image":{"image_id":"0fceabb4-ca86-4846-9b0a-c23947770cdb","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/0fceabb4-ca86-4846-9b0a-c23947770cdb"},"name":"activestate/centos-7.6-build","platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a","type":"Docker","sortable_version":["1","0","4","0"],"version":"1.0.4","provided_features":[{"feature":"perl-build-tools","is_activestate_version":true,"is_default_provider":false,"namespace":"image","sortable_version":["0"],"version":"0"},{"feature":"python-build-tools","is_activestate_version":true,"is_default_provider":false,"namespace":"image","sortable_version":["0"],"version":"0"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"conditions":null,"revision":5,"revision_timestamp":"2020-01-30T20:00:03.523Z"},"is_indemnified":false,"platform":{"cpu_architecture":{"cpu_architecture_id":"4cdba18d-0851-4925-9ae5-9c8a2987828a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a"},"bit_width":"64","name":"x86","provided_features":[{"feature":"x86 64-bit","is_activestate_version":false,"is_default_provider":true,"namespace":"cpu-architecture","sortable_version":["1"],"version":"1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"cpu_extensions":[],"creation_timestamp":"2019-08-06T21:46:35.288Z","display_name":"CentOS 7.6.1810, Linux 4.15.0, glibc 2.17 x86 64-bit","images":[{"image_id":"0fceabb4-ca86-4846-9b0a-c23947770cdb","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/0fceabb4-ca86-4846-9b0a-c23947770cdb"},"name":"activestate/centos-7.6-build","platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a","type":"Docker","sortable_version":["1","0","4","0"],"version":"1.0.4","provided_features":[{"feature":"perl-build-tools","is_activestate_version":true,"is_default_provider":false,"namespace":"image","sortable_version":["0"],"version":"0"},{"feature":"python-build-tools","is_activestate_version":true,"is_default_provider":false,"namespace":"image","sortable_version":["0"],"version":"0"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"conditions":null,"revision":5,"revision_timestamp":"2020-01-30T20:00:03.523Z"}],"is_user_visible":true,"kernel":{"kernel_id":"ef737274-fff9-4164-b72b-88067613f822","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822"},"name":"Linux"},"kernel_version":{"kernel_version_id":"2450c462-66e0-4aca-97d4-9910a19996f6","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/2450c462-66e0-4aca-97d4-9910a19996f6"},"sortable_version":["4","15","0"],"version":"4.15.0","provided_features":[{"feature":"Linux","is_activestate_version":false,"is_default_provider":true,"namespace":"kernel","sortable_version":["4","15","0"],"version":"4.15.0"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"libc":{"libc_id":"09a2eb42-ad34-4734-a93e-4b97395577df","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df"},"name":"glibc"},"libc_version":{"libc_version_id":"277c8630-948f-449c-9d69-5cf2ce3eb7eb","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/277c8630-948f-449c-9d69-5cf2ce3eb7eb"},"sortable_version":["2","17"],"version":"2.17","provided_features":[{"feature":"glibc","is_activestate_version":false,"is_default_provider":true,"namespace":"libc","sortable_version":["2","17"],"version":"2.17"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a"},"operating_system":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99"},"operating_system_id":"7b3a2dbb-d543-48d6-8390-7e7b63751e99","has_libc":true,"name":"CentOS"},"operating_system_version":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/2cab2f48-fb0b-415f-85f8-ddd045969662"},"operating_system_version_id":"2cab2f48-fb0b-415f-85f8-ddd045969662","sortable_version":["7","6","1810"],"version":"7.6.1810","provided_features":[{"feature":"CentOS","is_activestate_version":false,"is_default_provider":true,"namespace":"operating-system","sortable_version":["7","6","1810"],"version":"7.6.1810"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a"},"recipe_id":"585b3357-14fa-58a8-96db-4f5aa602113e","recipe_store_timestamp":"2020-04-24T17:24:26.585Z","resolved_ingredients":[{"alternatives":["dd369889-16b0-54cd-afba-d728a046a06d","3e6b87ed-9e26-533b-a52c-a4b8fdf63d9d","4b58addf-2b8d-5aaf-82a8-26e1d3254fbf","5ae75a1f-f8fa-53f1-8ae2-dd8178ed0bfa","daaebcd8-5257-5a09-b465-811933dcbf7f","ab417a2b-817a-5e63-a2e8-37a523583f2d","04036655-15dd-51d1-9960-136c9a6362fb","027dc8d1-a3f3-5a84-9fc4-8427e2f8eb26","4b1d3022-e0e4-5712-8465-f079293a106b","27959e22-7e40-5773-94cb-9cb153634ed5","15d1bc46-a098-5605-9567-9c9c4d90c139","3c7b2306-4e8e-50e1-af45-e6a792c18de2","0a1a89f8-f1cd-539b-9d93-78a397554d55","ee9c369c-7cf8-596a-96e7-34657eecb88c","a83ef247-44b4-5b5e-9aa2-387ce6883473","ffad8bea-1902-5a72-88b4-6f65a534e983","dd9f1135-5d66-535e-9879-c5e6de540ab5","5cdb089d-9a96-5f59-8090-dcf27fc087a3","471f73ed-e484-580f-b193-5a0ab37868f6","f14f6343-d75b-575d-be41-b46c2816bc04","442603f4-4df6-5d00-b48b-64c686b12431","46e20268-dd9e-5846-92c1-0249e4027609","6695f243-5c22-5b89-8998-17f5ad116d43","77031f4b-5c5e-57da-a112-fd3fcdbeaada","762f875a-880c-5de4-9dbe-923c3c7d48b7","ed851561-e424-5568-bf97-1010bf2f6ee8","252eb7bc-e95b-591c-b946-b1de81ca9ad8","b5858882-da48-5a39-b763-cef92950137d","fc2cbe4c-e940-5159-a3aa-be38eca43c7b","1c12af61-fde7-596a-8dc5-ca77866dd9a4","cd6bbe3b-41d9-56c6-85a5-4dd835f0e184","67e717fa-97b9-543c-9edf-b9a92abae7d6"],"artifact_id":"29ee664e-709c-5785-a183-c3cdd0abf65b","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2019-10-21T19:16:38.749Z","ingredient_id":"20816534-c073-5d68-9eb7-11c1d6be09f5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/20816534-c073-5d68-9eb7-11c1d6be09f5"},"name":"camel","normalized_name":"camel","primary_namespace":"builder","description":"The camel unified build system","website":"https://platform.activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-04-15T17:51:24.223Z","ingredient_id":"20816534-c073-5d68-9eb7-11c1d6be09f5","ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/20816534-c073-5d68-9eb7-11c1d6be09f5/versions/49530255-f4fa-5363-a4cc-2eb63cf5d6be","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/20816534-c073-5d68-9eb7-11c1d6be09f5"},"revision":1,"revision_timestamp":"2020-04-15T17:51:24.223Z","copyright_text":"Copyright © ActiveState Inc, 2004-2020","documentation_uri":"https://github.com/ActiveState/camel/tree/2a0758c3955df8e765c03c0f123a98435d611473/docs","is_binary_only":false,"license_expression":"UNLICENSED","release_timestamp":"2020-04-15T17:50:31.254Z","source_uri":"https://github.com/ActiveState/camel/tree/2a0758c3955df8e765c03c0f123a98435d611473","sortable_version":["20200415","135030","779230"],"version":"20200415.135030.2a0758c3","activestate_license_expression":"UNLICENSED","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://INVALID","scanner_license_expression":"UNLICENSED","source_checksum":"2a0758c3955df8e765c03c0f123a98435d611473","provided_features":[{"feature":"camel","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["20200415","135030","779230"],"version":"20200415.135030.2a0758c3"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"a5f0e5a0-133d-53b7-9047-683182945840","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:49:18.182Z","ingredient_id":"327b0673-5f5e-5b26-960d-a6fb18acd1c8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/327b0673-5f5e-5b26-960d-a6fb18acd1c8"},"name":"ActiveState-EULAs","normalized_name":"ActiveState-EULAs","primary_namespace":"internal","description":"ActiveState End-User License Agreements"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:49:18.182Z","ingredient_id":"327b0673-5f5e-5b26-960d-a6fb18acd1c8","ingredient_version_id":"e4d5b18c-89a9-561d-b99d-95bdd924735b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/327b0673-5f5e-5b26-960d-a6fb18acd1c8/versions/e4d5b18c-89a9-561d-b99d-95bdd924735b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/327b0673-5f5e-5b26-960d-a6fb18acd1c8"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2019-06-05T00:00:00.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/EULAs/main.tar.gz","sortable_version":["20170627","0"],"version":"20170627","activestate_license_expression":"unknown","camel_extras":{"does_not_install":"yes","dont_build":["yes"],"ppm_pkg":"no"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/internal/9d5b13269bf9b47c8778435d9c79f3cc8686ff667761c6e334e051a01a33053b/main.tar.gz","scanner_license_expression":"unknown","source_checksum":"9d5b13269bf9b47c8778435d9c79f3cc8686ff667761c6e334e051a01a33053b","provided_features":[{"feature":"ActiveState-EULAs","is_activestate_version":false,"is_default_provider":true,"namespace":"internal","sortable_version":["20170627","0"],"version":"20170627"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"ActiveState-EULAs","namespace":"internal","version_requirements":[{"comparator":"gte","version":"0"}]}]},{"alternatives":[],"artifact_id":"3b2088aa-3a85-5a54-8236-a8e285ec2fca","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:32.665Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"name":"perl","normalized_name":"perl","primary_namespace":"language","description":"Practical Extraction and Report Language"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:57:41.140Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206/versions/d94f704f-ab76-5db3-a571-b9a019a1cc2a","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"revision":12,"revision_timestamp":"2019-12-18T22:06:31.939Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/S/SH/SHAY/perl-5.28.1.tar.gz","sortable_version":["5","28","1","0"],"version":"5.28.1","activestate_license_expression":"unknown","camel_extras":{"base64_binaries":["win32/perl.ico"],"cold_storage_dirs":{"src":"__SRC__"},"git_base":"63afdf6c0f65af480aa5bb9ccba9f46dae52f6fc v5.28.1","ppm_pkg":"no"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/languages/3ebf85fe65df2ee165b22596540b7d5d42f84d4b72d84834f74e2e0b8956c347/perl-5.28.1.tar.gz","scanner_license_expression":"unknown","source_checksum":"3ebf85fe65df2ee165b22596540b7d5d42f84d4b72d84834f74e2e0b8956c347","provided_features":[{"feature":"perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","28","1","0"],"version":"5.28.1"},{"feature":"Amiga::ARexx","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","4","0"],"version":"0.4"},{"feature":"Amiga::Exec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.2"},{"feature":"AnyDBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"App::Cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","67","0"],"version":"1.67"},{"feature":"App::Prove","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"App::Prove::State","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"App::Prove::State::Result","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"App::Prove::State::Result::Test","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"Archive::Tar","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.30"},{"feature":"Archive::Tar::Constant","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.30"},{"feature":"Archive::Tar::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.30"},{"feature":"Attribute::Handlers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"AutoLoader::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","74","0"],"version":"5.74"},{"feature":"AutoSplit::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","6","0"],"version":"1.6"},{"feature":"B::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","74","0"],"version":"1.74"},{"feature":"B::Concise","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"B::Debug","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","26","0"],"version":"1.26"},{"feature":"B::Deparse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","48","0"],"version":"1.48"},{"feature":"B::Op_private","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","28001","0"],"version":"5.28001"},{"feature":"B::Showlex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","5","0"],"version":"1.5"},{"feature":"B::Terse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"B::Xref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"Benchmark::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","22","0"],"version":"1.22"},{"feature":"CPAN::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.20"},{"feature":"CPAN::Author","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","2","0"],"version":"5.50.2"},{"feature":"CPAN::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","3","0"],"version":"5.50.3"},{"feature":"CPAN::CacheMgr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","2","0"],"version":"5.50.2"},{"feature":"CPAN::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","1","0"],"version":"5.50.1"},{"feature":"CPAN::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","1","0"],"version":"5.50.1"},{"feature":"CPAN::DeferredCode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","0"],"version":"5.50"},{"feature":"CPAN::Distribution","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","19","0"],"version":"2.19"},{"feature":"CPAN::Distroprefs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","1","0"],"version":"6.1"},{"feature":"CPAN::Distrostatus","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Exception::RecursiveDependency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","1","0"],"version":"5.50.1"},{"feature":"CPAN::Exception::blocked_urllist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"CPAN::Exception::yaml_not_installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Exception::yaml_process_error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","11","0"],"version":"5.50.11"},{"feature":"CPAN::FTP::netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"CPAN::FirstTime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","53","11","0"],"version":"5.53.11"},{"feature":"CPAN::HTTP::Client","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","96","1","0"],"version":"1.96.1"},{"feature":"CPAN::HTTP::Credentials","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","96","1","0"],"version":"1.96.1"},{"feature":"CPAN::HandleConfig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","8","0"],"version":"5.50.8"},{"feature":"CPAN::Index","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","12","0"],"version":"2.12"},{"feature":"CPAN::InfoObj","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Kwalify","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","50","0"],"version":"5.50"},{"feature":"CPAN::LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","96","1","0"],"version":"1.96.1"},{"feature":"CPAN::Meta","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Converter","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Feature","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::History","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Merge","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Prereqs","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Requirements","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","140","0"],"version":"2.140"},{"feature":"CPAN::Meta::Spec","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Validator","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::YAML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","18","0"],"version":"0.18"},{"feature":"CPAN::Mirrors","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","12","0"],"version":"2.12"},{"feature":"CPAN::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","3","0"],"version":"5.50.3"},{"feature":"CPAN::Nox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","1","0"],"version":"5.50.1"},{"feature":"CPAN::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","96","0"],"version":"0.96"},{"feature":"CPAN::Plugin::Specfile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"},{"feature":"CPAN::Prompt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","2","0"],"version":"5.50.2"},{"feature":"CPAN::Shell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","7","0"],"version":"5.50.7"},{"feature":"CPAN::Tarzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","12","0"],"version":"5.50.12"},{"feature":"CPAN::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","3","0"],"version":"5.50.3"},{"feature":"Carp::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"Class::Struct","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","65","0"],"version":"0.65"},{"feature":"Compress::Raw::Bzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"Compress::Raw::Zlib","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","76","0"],"version":"2.76"},{"feature":"Compress::Zlib","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"Config::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0"],"version":"1"},{"feature":"Config::Extensions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.2"},{"feature":"Config::Perl::V","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","29","0"],"version":"0.29"},{"feature":"Cwd::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"DB::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"DBM_Filter::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","6","0"],"version":"0.6"},{"feature":"DBM_Filter::compress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DBM_Filter::encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DBM_Filter::int32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DBM_Filter::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DBM_Filter::utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DB_File::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","840","0"],"version":"1.840"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","170","0"],"version":"2.170"},{"feature":"Demo::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Descriptions::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Devel::PPPort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","40","0"],"version":"3.40"},{"feature":"Devel::Peek","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","27","0"],"version":"1.27"},{"feature":"Devel::SelfStubber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","6","0"],"version":"1.6"},{"feature":"Digest::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","17","1","0"],"version":"1.17.1"},{"feature":"Digest::MD5","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","55","0"],"version":"2.55"},{"feature":"Digest::SHA","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["6","1","0"],"version":"6.1"},{"feature":"Digest::base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","16","0"],"version":"1.16"},{"feature":"Digest::file","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","16","0"],"version":"1.16"},{"feature":"DirHandle::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","5","0"],"version":"1.5"},{"feature":"Dumpvalue::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","18","0"],"version":"1.18"},{"feature":"DynaLoader::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","45","0"],"version":"1.45"},{"feature":"Encode::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","97","0"],"version":"2.97"},{"feature":"Encode::Alias","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","24","0"],"version":"2.24"},{"feature":"Encode::Byte","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","4","0"],"version":"2.4"},{"feature":"Encode::CJKConstants","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","2","0"],"version":"2.2"},{"feature":"Encode::CN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Encode::CN::HZ","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.10"},{"feature":"Encode::Config","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","5","0"],"version":"2.5"},{"feature":"Encode::EBCDIC","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","2","0"],"version":"2.2"},{"feature":"Encode::Encoder","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Encode::Encoding","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","8","0"],"version":"2.8"},{"feature":"Encode::GSM0338","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"Encode::Guess","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"Encode::JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","4","0"],"version":"2.4"},{"feature":"Encode::JP::H2Z","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","2","0"],"version":"2.2"},{"feature":"Encode::JP::JIS7","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","8","0"],"version":"2.8"},{"feature":"Encode::KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Encode::KR::2022_KR","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","4","0"],"version":"2.4"},{"feature":"Encode::MIME::Header","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","28","0"],"version":"2.28"},{"feature":"Encode::MIME::Header::ISO_2022_JP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","9","0"],"version":"1.9"},{"feature":"Encode::MIME::Name","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Encode::Symbol","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","2","0"],"version":"2.2"},{"feature":"Encode::TW","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Encode::Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","17","0"],"version":"2.17"},{"feature":"Encode::Unicode::UTF7","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.10"},{"feature":"English::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"Env::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"Errno::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0"],"version":"1"},{"feature":"Exporter::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","73","0"],"version":"5.73"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","25","0"],"version":"0.25"},{"feature":"ExtUtils::Constant::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","6","0"],"version":"0.6"},{"feature":"ExtUtils::Constant::ProxySubs","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","9","0"],"version":"0.9"},{"feature":"ExtUtils::Constant::Utils","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","4","0"],"version":"0.4"},{"feature":"ExtUtils::Constant::XS","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"ExtUtils::Embed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","35","1","0"],"version":"1.35.1"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.70"},{"feature":"ExtUtils::Miniperl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::ParseXS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::ParseXS::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::ParseXS::CountLines","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::ParseXS::Eval","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::ParseXS::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::Typemaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::InputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::OutputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Type","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::XSSymSet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"Fatal::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"Fcntl::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","13","0"],"version":"1.13"},{"feature":"File::Basename","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","85","0"],"version":"2.85"},{"feature":"File::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","6","0"],"version":"1.10.6"},{"feature":"File::Copy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","33","0"],"version":"2.33"},{"feature":"File::DosGlob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","12","0"],"version":"1.12"},{"feature":"File::Fetch","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","56","0"],"version":"0.56"},{"feature":"File::Find","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","34","0"],"version":"1.34"},{"feature":"File::Glob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","31","0"],"version":"1.31"},{"feature":"File::GlobMapper","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"File::Path","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0"],"version":"2.15"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Temp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","23","4","0"],"version":"0.23.4"},{"feature":"File::stat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"FileCache::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"FileHandle::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Filter::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","95","0"],"version":"0.95"},{"feature":"Filter::Util::Call","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","58","0"],"version":"1.58"},{"feature":"FindBin::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","51","0"],"version":"1.51"},{"feature":"GDBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","17","0"],"version":"1.17"},{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.50"},{"feature":"Getopt::Std","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","12","0"],"version":"1.12"},{"feature":"HTTP::Tiny","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","70","0"],"version":"0.70"},{"feature":"Hash::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","22","0"],"version":"0.22"},{"feature":"Hash::Util::FieldHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.20"},{"feature":"I18N::Collate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"I18N::LangTags","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","43","0"],"version":"0.43"},{"feature":"I18N::LangTags::Detect","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"I18N::LangTags::List","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.40"},{"feature":"I18N::Langinfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.17"},{"feature":"IO::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Compress::Adapter::Bzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Adapter::Deflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Adapter::Identity","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Base::Common","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Bzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Deflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Gzip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Gzip::Constants","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::RawDeflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Zip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Zip::Constants","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Zlib::Constants","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Zlib::Extra","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Dir","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Handle","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Pipe","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Poll","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Seekable","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Select","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Socket","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Socket::INET","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Socket::IP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","39","0"],"version":"0.39"},{"feature":"IO::Socket::UNIX","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Uncompress::Adapter::Bunzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Adapter::Identity","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Adapter::Inflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::AnyInflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::AnyUncompress","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Bunzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Gunzip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Inflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::RawInflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Unzip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Zlib","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"IPC::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"IPC::Msg","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"IPC::Open2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"IPC::Open3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.20"},{"feature":"IPC::Semaphore","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"IPC::SharedMem","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"IPC::SysV","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","97","1","0"],"version":"2.97.1"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","97001","0"],"version":"2.97001"},{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"Locale::Codes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Country","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Currency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::LangExt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::LangFam","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::LangVar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Language","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Script","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Country","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Currency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Language","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Maketext","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","29","0"],"version":"1.29"},{"feature":"Locale::Maketext::Guts","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.20"},{"feature":"Locale::Maketext::GutsLoader","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.20"},{"feature":"Locale::Maketext::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","21","1","0"],"version":"0.21.1"},{"feature":"Locale::Script","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"MIME::Base64","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","15","0"],"version":"3.15"},{"feature":"MIME::QuotedPrint","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","13","0"],"version":"3.13"},{"feature":"Math::BigFloat","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigFloat::Trace","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"Math::BigInt","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigInt::Calc","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigInt::CalcEmu","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigInt::FastCalc","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","50","6","0"],"version":"0.50.6"},{"feature":"Math::BigInt::Lib","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigInt::Trace","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"Math::BigRat","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","26","13","0"],"version":"0.26.13"},{"feature":"Math::Complex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","59","1","0"],"version":"1.59.1"},{"feature":"Math::Trig","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","23","0"],"version":"1.23"},{"feature":"Memoize::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","1","0"],"version":"1.3.1"},{"feature":"Memoize::AnyDBM_File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::Expire","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::ExpireFile","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::ExpireTest","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::NDBM_File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::SDBM_File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::Storable","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Module::CoreList","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","20181129","28","0"],"version":"5.20181129.28"},{"feature":"Module::CoreList::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","20181129","28","0"],"version":"5.20181129.28"},{"feature":"Module::Load","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","32","0"],"version":"0.32"},{"feature":"Module::Load::Conditional","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","68","0"],"version":"0.68"},{"feature":"Module::Loaded","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","8","0"],"version":"0.8"},{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","33","0"],"version":"1.33"},{"feature":"MyClass::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"NDBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","14","0"],"version":"1.14"},{"feature":"NEXT::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","67","1","0"],"version":"0.67.1"},{"feature":"Net::Cmd","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Config","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Domain","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::A","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::E","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::I","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::L","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::dataconn","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::NNTP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Netrc","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::POP3","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Ping","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","62","0"],"version":"2.62"},{"feature":"Net::SMTP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Time","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::hostent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"Net::netent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"Net::protoent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"Net::servent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"O::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"ODBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","15","0"],"version":"1.15"},{"feature":"Opcode::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","43","0"],"version":"1.43"},{"feature":"POSIX::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","84","0"],"version":"1.84"},{"feature":"Params::Check","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","38","0"],"version":"0.38"},{"feature":"Parse::CPAN::Meta","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"Perl::OSType","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"PerlIO::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"PerlIO::encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","26","0"],"version":"0.26"},{"feature":"PerlIO::mmap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","16","0"],"version":"0.16"},{"feature":"PerlIO::scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","29","0"],"version":"0.29"},{"feature":"PerlIO::via","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.17"},{"feature":"PerlIO::via::QuotedPrint","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","8","0"],"version":"0.8"},{"feature":"Pod::Checker","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"Pod::Escapes","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"Pod::Find","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","13","0"],"version":"1.13"},{"feature":"Pod::Html","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","24","0"],"version":"1.24"},{"feature":"Pod::InputObjects","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::ParseUtils","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Parser","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Perldoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","28","1","0"],"version":"3.28.1"},{"feature":"Pod::Perldoc::BaseTo","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::GetOptsOO","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToANSI","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToChecker","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToMan","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToNroff","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToPod","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToRtf","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTerm","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToText","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTk","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToXml","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::PlainText","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"Pod::Select","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Simple","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::BlackBox","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Checker","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Debug","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::DumpAsText","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::DumpAsXML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::HTML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::HTMLBatch","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::HTMLLegacy","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","1","0"],"version":"5.1"},{"feature":"Pod::Simple::LinkSection","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Methody","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Progress","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParser","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParserEndToken","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParserStartToken","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParserTextToken","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParserToken","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::RTF","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Search","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::SimpleTree","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Text","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::TextContent","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::TiedOutFH","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Transcode","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::TranscodeDumb","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::TranscodeSmart","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::XHTML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::XMLOutStream","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::Usage","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","69","0"],"version":"1.69"},{"feature":"SDBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","14","0"],"version":"1.14"},{"feature":"Safe::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.40"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"Search::Dict","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"SelectSaver::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"SelfLoader::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Socket::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","27","0"],"version":"2.27"},{"feature":"Storable::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","8","0"],"version":"3.8"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"Symbol::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"Sys::Hostname","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","22","1","0"],"version":"1.22.1"},{"feature":"Sys::Syslog","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","35","0"],"version":"0.35"},{"feature":"TAP::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Color","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Console","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Console::ParallelSession","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Console::Session","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::File::Session","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Session","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Harness","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Harness::Env","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Object","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Aggregator","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Grammar","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Iterator","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Iterator::Array","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Iterator::Process","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Iterator::Stream","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::IteratorFactory","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Multiplexer","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Bailout","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Comment","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Plan","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Pragma","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Test","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Unknown","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Version","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::YAML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::ResultFactory","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Scheduler","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Scheduler::Job","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Scheduler::Spinner","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Source","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::Executable","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::Handle","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::Perl","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::RawTAP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::YAMLish::Reader","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::YAMLish::Writer","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"Term::ANSIColor","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","6","0"],"version":"4.6"},{"feature":"Term::Cap","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","17","0"],"version":"1.17"},{"feature":"Term::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","403","0"],"version":"1.403"},{"feature":"Term::ReadLine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","17","0"],"version":"1.17"},{"feature":"Test2::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","31","0"],"version":"1.31"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","114","0"],"version":"2.114"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Harness","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Text::Abbrev","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"Text::Balanced","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Text::ParseWords","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","30","0"],"version":"3.30"},{"feature":"Text::Tabs","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2013","523","0"],"version":"2013.523"},{"feature":"Text::Wrap","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2013","523","0"],"version":"2013.523"},{"feature":"Thread::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","4","0"],"version":"3.4"},{"feature":"Thread::Queue","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","12","0"],"version":"3.12"},{"feature":"Thread::Semaphore","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","13","0"],"version":"2.13"},{"feature":"Tie::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"Tie::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"Tie::Handle","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","2","0"],"version":"4.2"},{"feature":"Tie::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","5","0"],"version":"1.5"},{"feature":"Tie::Hash::NamedCapture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10","0"],"version":"0.10"},{"feature":"Tie::Memoize","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"Tie::RefHash","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"Tie::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"Tie::StdHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","5","0"],"version":"4.5"},{"feature":"Tie::SubstrHash","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Time::HiRes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","97","59","0"],"version":"1.97.59"},{"feature":"Time::Local","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Time::Piece","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","32","4","0"],"version":"1.32.4"},{"feature":"Time::Seconds","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","32","4","0"],"version":"1.32.4"},{"feature":"Time::gmtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"Time::localtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Time::tm","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"UNIVERSAL::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","13","0"],"version":"1.13"},{"feature":"Unicode::Collate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Big5","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::GB2312","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::JISX0208","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Korean","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Pinyin","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Stroke","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Zhuyin","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::Locale","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Normalize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","26","0"],"version":"1.26"},{"feature":"Unicode::UCD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","70","0"],"version":"0.70"},{"feature":"User::grent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"User::pwent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"VMS::DCLsym","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","9","0"],"version":"1.9"},{"feature":"VMS::Filespec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","12","0"],"version":"1.12"},{"feature":"VMS::Stdio","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","44","0"],"version":"2.44"},{"feature":"Win32::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","52","0"],"version":"0.52"},{"feature":"Win32API::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","12","3","0"],"version":"0.12.3"},{"feature":"Win32CORE::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","4","0"],"version":"0.4"},{"feature":"XS::APItest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","98","0"],"version":"0.98"},{"feature":"XS::Typemap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","16","0"],"version":"0.16"},{"feature":"XSLoader::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.30"},{"feature":"_charnames::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","45","0"],"version":"1.45"},{"feature":"arybase::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.15"},{"feature":"attributes::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","33","0"],"version":"0.33"},{"feature":"autodie::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::Scope::Guard","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::Scope::GuardStack","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::Util","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","29002","0"],"version":"2.29002"},{"feature":"autodie::exception::system","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::hints","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","29001","0"],"version":"2.29001"},{"feature":"autodie::skip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autouse::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","11","0"],"version":"1.11"},{"feature":"base::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","27","0"],"version":"2.27"},{"feature":"bigint::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"bignum::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"bigrat::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"blib::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"bytes::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","6","0"],"version":"1.6"},{"feature":"charnames::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","45","0"],"version":"1.45"},{"feature":"constant::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","33","0"],"version":"1.33"},{"feature":"deprecate::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"diagnostics::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","36","0"],"version":"1.36"},{"feature":"encoding::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","22","0"],"version":"2.22"},{"feature":"encoding::warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","13","0"],"version":"0.13"},{"feature":"experimental::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","19","0"],"version":"0.19"},{"feature":"feature::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","52","0"],"version":"1.52"},{"feature":"fields::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","24","0"],"version":"2.24"},{"feature":"filetest::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"if::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","608","0"],"version":"0.608"},{"feature":"integer::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"less::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"lib::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","64","0"],"version":"0.64"},{"feature":"locale::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","9","0"],"version":"1.9"},{"feature":"mro::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","22","0"],"version":"1.22"},{"feature":"ok::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"open::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","11","0"],"version":"1.11"},{"feature":"ops::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"overload::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.30"},{"feature":"overloading::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.2"},{"feature":"parent::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","236","0"],"version":"0.236"},{"feature":"perlfaq::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","21011","0"],"version":"5.21011"},{"feature":"re::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","36","0"],"version":"0.36"},{"feature":"sigtrap::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"sort::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","4","0"],"version":"2.4"},{"feature":"strict::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","11","0"],"version":"1.11"},{"feature":"subs::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"threads::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","22","0"],"version":"2.22"},{"feature":"threads::shared","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","58","0"],"version":"1.58"},{"feature":"utf8::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","21","0"],"version":"1.21"},{"feature":"vars::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"version::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","99","23","0"],"version":"0.99.23"},{"feature":"version::regex","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","99","23","0"],"version":"0.99.23"},{"feature":"vmsish::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"warnings::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","42","0"],"version":"1.42"},{"feature":"warnings::register","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-12-18T22:06:26.788Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/cb5b6720-82e5-4546-a99a-9d39332c51af"},"patch_id":"cb5b6720-82e5-4546-a99a-9d39332c51af","conditions":null,"content":"s3://platform-sources/patches/d251ddaed91891b7b619b5d89d1bac3cb55b59bb1cda04791cc0da2cfec7c212.patch","description":"ActivePerl ~ ActivePerl 5.28 patch","sequence_number":1}],"resolved_requirements":[{"feature":"perl","namespace":"language","version_requirements":[{"comparator":"eq","version":"5.28.1"}]}]},{"alternatives":[],"artifact_id":"acb500a5-af3d-553c-bf07-4fde842cc44e","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:49:19.077Z","ingredient_id":"4c46f01f-87de-5ae2-bb45-58201d461e51","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c46f01f-87de-5ae2-bb45-58201d461e51"},"name":"ActiveState-RelocateTree","normalized_name":"ActiveState-RelocateTree","primary_namespace":"language/perl","description":"Move perl distribution to new location"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:49:19.077Z","ingredient_id":"4c46f01f-87de-5ae2-bb45-58201d461e51","ingredient_version_id":"d8b90b31-e26a-5e2f-81c7-1225e8a0a8f2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c46f01f-87de-5ae2-bb45-58201d461e51/versions/d8b90b31-e26a-5e2f-81c7-1225e8a0a8f2","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c46f01f-87de-5ae2-bb45-58201d461e51"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2009-05-06T17:15:51.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/as-mod/ActiveState-RelocateTree/main.tar.gz","sortable_version":["1","4","0"],"version":"1.4","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ActiveState/RelocateTree"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/ab994200dced4d26e41332754e863a902a8689753622229d73bf4b9b42eef1dd/main.tar.gz","scanner_license_expression":"unknown","source_checksum":"ab994200dced4d26e41332754e863a902a8689753622229d73bf4b9b42eef1dd","provided_features":[{"feature":"ActiveState-RelocateTree","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"ActiveState-RelocateTree","namespace":"language/perl","version_requirements":[{"comparator":"gte","version":"0"}]}]},{"alternatives":[],"artifact_id":"ef438bc7-bf38-5537-85f3-9ff07e715128","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"06d43cc3-8f67-575b-b34d-0ec60e9ae67e"},{"dependency_types":["build"],"ingredient_version_id":"1a882ae6-d86f-5431-a5cb-8caa0abeedf5"},{"dependency_types":["build"],"ingredient_version_id":"1cb4ca5e-4e4e-59fb-b2cb-5fdb54856ff0"},{"dependency_types":["build"],"ingredient_version_id":"3e08c8d3-fe88-5c33-82df-ded1e3d15a0b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"5b9149e8-2334-5454-a523-cd9787003344"},{"dependency_types":["build","runtime"],"ingredient_version_id":"84a01b55-1d92-53ae-a7cb-d591b7b54724"},{"dependency_types":["build"],"ingredient_version_id":"91cd893b-5b8c-5391-9c77-643fb85af0af"},{"dependency_types":["build"],"ingredient_version_id":"e4b6a074-ad51-5b69-95ce-7747c95471f8"},{"dependency_types":["runtime"],"ingredient_version_id":"f53173d3-f084-5b6f-927e-6db8c13aac9c"}],"ingredient":{"creation_timestamp":"2019-10-01T16:49:20.357Z","ingredient_id":"70829de1-9690-5b85-8d6f-1c5746a362e7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/70829de1-9690-5b85-8d6f-1c5746a362e7"},"name":"ActiveState-Test","normalized_name":"ActiveState-Test","primary_namespace":"language/perl","description":"ActiveState's Test modules"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:49:20.357Z","ingredient_id":"70829de1-9690-5b85-8d6f-1c5746a362e7","ingredient_version_id":"cf00c298-f30f-5900-8c36-6e9041654afc","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/70829de1-9690-5b85-8d6f-1c5746a362e7/versions/cf00c298-f30f-5900-8c36-6e9041654afc","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/70829de1-9690-5b85-8d6f-1c5746a362e7"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2013-04-28T14:16:37.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/as-mod/ActiveState-Test/main.tar.gz","sortable_version":["1","0","0"],"version":"1.0","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ActiveState/Test"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/565a38e09a10f3ae09afafaf29c01d60620c31c31b936d219e61c78c7aecbc57/main.tar.gz","scanner_license_expression":"unknown","source_checksum":"565a38e09a10f3ae09afafaf29c01d60620c31c31b936d219e61c78c7aecbc57","provided_features":[{"feature":"ActiveState-Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"ActiveState::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"ActiveState::Test::DBI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"},{"feature":"ActiveState::Test::X11Server","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"},{"feature":"ActiveState::Test::X11Server::Impl::Managed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"ActiveState-Test","namespace":"language/perl","version_requirements":[{"comparator":"gte","version":"0"}]}]},{"alternatives":[],"artifact_id":"84a58839-2df8-5e4d-ab88-f44c991e2539","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"a873d528-56e8-5c19-b5cb-383be3bb9074"},{"dependency_types":["build"],"ingredient_version_id":"cf00c298-f30f-5900-8c36-6e9041654afc"},{"dependency_types":["runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"},{"dependency_types":["build","runtime"],"ingredient_version_id":"f53173d3-f084-5b6f-927e-6db8c13aac9c"}],"ingredient":{"creation_timestamp":"2019-10-01T16:50:32.819Z","ingredient_id":"a65130b8-7a66-5e74-aaad-ed3b2ce8f039","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a65130b8-7a66-5e74-aaad-ed3b2ce8f039"},"name":"DBD-Pg","normalized_name":"DBD-Pg","primary_namespace":"language/perl","description":"DBI PostgreSQL interface"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:50:32.819Z","ingredient_id":"a65130b8-7a66-5e74-aaad-ed3b2ce8f039","ingredient_version_id":"6e9c11f1-db6a-536e-b607-0e1aa95dceb0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a65130b8-7a66-5e74-aaad-ed3b2ce8f039/versions/6e9c11f1-db6a-536e-b607-0e1aa95dceb0","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a65130b8-7a66-5e74-aaad-ed3b2ce8f039"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-Perl OR GPL-1.0-or-later","release_timestamp":"2017-09-24T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/T/TU/TURNSTEP/DBD-Pg-3.7.0.tar.gz","sortable_version":["3","7","0","0"],"version":"3.7.0","activestate_license_expression":"unknown","camel_extras":{"dont_build":["hpux","solaris"],"mm_fullext":"DBD/Pg"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/e36e0459c9cf0f12edafb74f4cef685876d0460dbe6b411e7109070c67e56459/DBD-Pg-3.7.0.tar.gz","scanner_license_expression":"unknown","source_checksum":"e36e0459c9cf0f12edafb74f4cef685876d0460dbe6b411e7109070c67e56459","provided_features":[{"feature":"Bundle::DBD::Pg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","7","0","0"],"version":"3.7.0"},{"feature":"DBD-Pg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","7","0","0"],"version":"3.7.0"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:50:30.233Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/5973ce13-45fb-4d96-a936-99de317bac86"},"patch_id":"5973ce13-45fb-4d96-a936-99de317bac86","conditions":null,"content":"DBD-Pg/3.7.0/0001-Add-a-very-simple-test-of-SSL-connections.patch","description":"[PATCH 1/7] Add a very simple test of SSL connections","sequence_number":1},{"creation_timestamp":"2019-10-01T16:50:30.584Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/37b9955e-9cce-444d-a218-84ea8a474254"},"patch_id":"37b9955e-9cce-444d-a218-84ea8a474254","conditions":null,"content":"DBD-Pg/3.7.0/0002-Add-an-AS-MAKEFILE.PL.patch","description":"[PATCH 2/7] Add an AS-MAKEFILE.PL\n\nThis file figures out what Pg server to connect to. It also sets the\nPOSTGRES_LIB env var to something that works for our build systems.","sequence_number":2},{"creation_timestamp":"2019-10-01T16:50:30.944Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/25720922-dcda-469d-a201-f9febb40e036"},"patch_id":"25720922-dcda-469d-a201-f9febb40e036","conditions":null,"content":"DBD-Pg/3.7.0/0003-Speed-up-test-which-runs-16k-SQL-statements.patch","description":"[PATCH 3/7] Speed up test which runs 16k SQL statements","sequence_number":3},{"creation_timestamp":"2019-10-01T16:50:31.306Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/ae975b82-2282-41b2-9551-5e87f9377604"},"patch_id":"ae975b82-2282-41b2-9551-5e87f9377604","conditions":null,"content":"DBD-Pg/3.7.0/0004-Don-t-quote-POSTGRES_LIB-on-Win32-and-skip-EXTRALIBS.patch","description":"[PATCH 4/7] Don't quote POSTGRES_LIB on Win32 and skip EXTRALIBS\n check","sequence_number":4},{"creation_timestamp":"2019-10-01T16:50:31.667Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/e5b252f2-0818-4397-bddb-20ea3707fb7b"},"patch_id":"e5b252f2-0818-4397-bddb-20ea3707fb7b","conditions":null,"content":"DBD-Pg/3.7.0/0005-Skip-alarm-using-test-on-Windows.patch","description":"[PATCH 5/7] Skip alarm-using test on Windows","sequence_number":5},{"creation_timestamp":"2019-10-01T16:50:32.023Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/0072ac8b-0163-47dd-9df7-ef9dee883b6f"},"patch_id":"0072ac8b-0163-47dd-9df7-ef9dee883b6f","conditions":null,"content":"DBD-Pg/3.7.0/0006-Skip-tests-for-lost-network-connections-that-fail-on.patch","description":"[PATCH 6/7] Skip tests for lost network connections that fail on\n Win32","sequence_number":6},{"creation_timestamp":"2019-10-01T16:50:32.384Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/cf9ab8f0-66cf-4d91-b1eb-7e993961bf92"},"patch_id":"cf9ab8f0-66cf-4d91-b1eb-7e993961bf92","conditions":null,"content":"DBD-Pg/3.7.0/0007-Rollup-patches-only-set-up-test-env-if-we-are-runnin.patch","description":"[PATCH 7/7] Rollup patches, only set up test env if we are running\n tests","sequence_number":7}],"resolved_requirements":[{"feature":"DBD-Pg","namespace":"language/perl","version_requirements":[{"comparator":"eq","version":"3.7.0"}]}]},{"alternatives":["23d7bf13-cc36-57ae-8c6a-779f7db8f7db"],"artifact_id":"4ed1a6b5-2310-5da2-9342-2b99c8ad2651","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:50:47.461Z","ingredient_id":"15f71af1-b236-5bdf-aa8a-057151757c0e","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15f71af1-b236-5bdf-aa8a-057151757c0e"},"name":"DBI","normalized_name":"DBI","primary_namespace":"language/perl","description":"Database independent interface for Perl"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:50:48.296Z","ingredient_id":"15f71af1-b236-5bdf-aa8a-057151757c0e","ingredient_version_id":"f53173d3-f084-5b6f-927e-6db8c13aac9c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15f71af1-b236-5bdf-aa8a-057151757c0e/versions/f53173d3-f084-5b6f-927e-6db8c13aac9c","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15f71af1-b236-5bdf-aa8a-057151757c0e"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2018-10-29T00:00:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/T/TI/TIMB/DBI-1.642.tar.gz","sortable_version":["1","642","0"],"version":"1.642","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"DBI"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/3f2025023a56286cebd15cb495e36ccd9b456c3cc229bf2ce1f69e9ebfc27f5d/DBI-1.642.tar.gz","scanner_license_expression":"unknown","source_checksum":"3f2025023a56286cebd15cb495e36ccd9b456c3cc229bf2ce1f69e9ebfc27f5d","provided_features":[{"feature":"Bundle::DBI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["12","8696","0"],"version":"12.8696"},{"feature":"DBD::DBM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","8","0"],"version":"0.8"},{"feature":"DBD::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","44","0"],"version":"0.44"},{"feature":"DBD::Gofer::Policy::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Policy::classic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Policy::pedantic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Policy::rush","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Transport::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","14121","0"],"version":"0.14121"},{"feature":"DBD::Gofer::Transport::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Transport::pipeone","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Transport::stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","14599","0"],"version":"0.14599"},{"feature":"DBD::Mem","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"},{"feature":"DBD::Proxy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2004","0"],"version":"0.2004"},{"feature":"DBI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","642","0"],"version":"1.642"},{"feature":"DBI::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","642","0"],"version":"1.642"},{"feature":"DBI::Const::GetInfo::ANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","8697","0"],"version":"2.8697"},{"feature":"DBI::Const::GetInfo::ODBC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","11374","0"],"version":"2.11374"},{"feature":"DBI::Const::GetInfoReturn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","8697","0"],"version":"2.8697"},{"feature":"DBI::Const::GetInfoType","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","8697","0"],"version":"2.8697"},{"feature":"DBI::DBD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["12","15129","0"],"version":"12.15129"},{"feature":"DBI::DBD::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14214","0"],"version":"2.14214"},{"feature":"DBI::DBD::SqlEngine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","6","0"],"version":"0.6"},{"feature":"DBI::Gofer::Execute","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","14283","0"],"version":"0.14283"},{"feature":"DBI::Gofer::Request","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","12537","0"],"version":"0.12537"},{"feature":"DBI::Gofer::Response","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","11566","0"],"version":"0.11566"},{"feature":"DBI::Gofer::Serializer::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","9950","0"],"version":"0.9950"},{"feature":"DBI::Gofer::Serializer::DataDumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","9950","0"],"version":"0.9950"},{"feature":"DBI::Gofer::Serializer::Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15586","0"],"version":"0.15586"},{"feature":"DBI::Gofer::Transport::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","12537","0"],"version":"0.12537"},{"feature":"DBI::Gofer::Transport::pipeone","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","12537","0"],"version":"0.12537"},{"feature":"DBI::Gofer::Transport::stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","12537","0"],"version":"0.12537"},{"feature":"DBI::Profile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","15065","0"],"version":"2.15065"},{"feature":"DBI::ProfileData","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","10008","0"],"version":"2.10008"},{"feature":"DBI::ProfileDumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","15325","0"],"version":"2.15325"},{"feature":"DBI::ProfileDumper::Apache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14121","0"],"version":"2.14121"},{"feature":"DBI::ProfileSubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","9396","0"],"version":"0.9396"},{"feature":"DBI::ProxyServer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3005","0"],"version":"0.3005"},{"feature":"DBI::PurePerl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14286","0"],"version":"2.14286"},{"feature":"DBI::SQL::Nano","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","15544","0"],"version":"1.15544"},{"feature":"DBI::Util::CacheMemory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10315","0"],"version":"0.10315"},{"feature":"DBI::Util::_accessor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","9479","0"],"version":"0.9479"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["27d48b7f-6d4c-50df-892f-7f500745dad0","cb035aad-a1f6-59e5-baf4-fbd8666c1f75","d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"68414965-5544-5af9-8d6c-32b9cce4df2b","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:50:51.494Z","ingredient_id":"6d0d1e25-b677-544c-9aab-fc8bf0eab142","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6d0d1e25-b677-544c-9aab-fc8bf0eab142"},"name":"Data-Dumper","normalized_name":"Data-Dumper","primary_namespace":"language/perl","description":"unknown"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:49.330Z","ingredient_id":"6d0d1e25-b677-544c-9aab-fc8bf0eab142","ingredient_version_id":"34a46b65-4429-5882-ba28-f7d09bb8a1d6","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6d0d1e25-b677-544c-9aab-fc8bf0eab142/versions/34a46b65-4429-5882-ba28-f7d09bb8a1d6","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6d0d1e25-b677-544c-9aab-fc8bf0eab142"},"revision":2,"revision_timestamp":"2019-12-06T22:01:07.334Z","copyright_text":"unknown","documentation_uri":"https://metacpan.org/pod/Data::Dumper","is_binary_only":false,"license_expression":"UNKNOWN","release_timestamp":"2018-11-10T10:10:30.000Z","source_uri":"https://cpan.metacpan.org/authors/id/X/XS/XSAWYERX/Data-Dumper-2.173.tar.gz","sortable_version":["2","173","0"],"version":"2.173","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/697608b39330988e519131be667ff47168aaaaf99f06bd2095d5b46ad05d76fa/Data-Dumper-2.173.tar.gz","scanner_license_expression":"unknown","source_checksum":"697608b39330988e519131be667ff47168aaaaf99f06bd2095d5b46ad05d76fa","provided_features":[{"feature":"Data-Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","173","0"],"version":"2.173"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","173","0"],"version":"2.173"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"44bca841-a181-5b72-bdd4-ab5d37ccb309","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:28.430Z","ingredient_id":"4a73e3d3-370c-55c1-9fec-f5d48fc4be9b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4a73e3d3-370c-55c1-9fec-f5d48fc4be9b"},"name":"ExtUtils-CBuilder","normalized_name":"ExtUtils-CBuilder","primary_namespace":"language/perl","description":"Compile and link C code for Perl modules"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:28.430Z","ingredient_id":"4a73e3d3-370c-55c1-9fec-f5d48fc4be9b","ingredient_version_id":"28f42dcf-0e80-5058-92a5-729ca91955a8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4a73e3d3-370c-55c1-9fec-f5d48fc4be9b/versions/28f42dcf-0e80-5058-92a5-729ca91955a8","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4a73e3d3-370c-55c1-9fec-f5d48fc4be9b"},"revision":4,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-11-22T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/A/AM/AMBS/ExtUtils-CBuilder-0.280230.tar.gz","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ExtUtils/CBuilder"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/1daae1d7709709a26139984b3c4c36e9ff22912cde6a393ea30ef40058dc9cd5/ExtUtils-CBuilder-0.280230.tar.gz","scanner_license_expression":"unknown","source_checksum":"1daae1d7709709a26139984b3c4c36e9ff22912cde6a393ea30ef40058dc9cd5","provided_features":[{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils-CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:51:27.984Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/059a0a2b-9ff8-4354-a993-e04088ffd3de"},"patch_id":"059a0a2b-9ff8-4354-a993-e04088ffd3de","conditions":null,"content":"ExtUtils-CBuilder-base-file.patch","description":"No description","sequence_number":1}],"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"20af464f-bda3-5072-b330-f4392b5e9850","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:32.487Z","ingredient_id":"59937b56-db73-5e9e-8d96-5966ed4593a8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/59937b56-db73-5e9e-8d96-5966ed4593a8"},"name":"ExtUtils-Install","normalized_name":"ExtUtils-Install","primary_namespace":"language/perl","description":"install files from here to there"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:32.487Z","ingredient_id":"59937b56-db73-5e9e-8d96-5966ed4593a8","ingredient_version_id":"9d19c878-dde6-5bc7-a0a1-aee1a15cf1a2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/59937b56-db73-5e9e-8d96-5966ed4593a8/versions/9d19c878-dde6-5bc7-a0a1-aee1a15cf1a2","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/59937b56-db73-5e9e-8d96-5966ed4593a8"},"revision":4,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-05-28T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/B/BI/BINGOS/ExtUtils-Install-2.14.tar.gz","sortable_version":["2","14","0"],"version":"2.14","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ExtUtils/Install"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/35412305cbae979aac3b6e2c70cb301ae461979a1d848a8a043f74518eb96aea/ExtUtils-Install-2.14.tar.gz","scanner_license_expression":"unknown","source_checksum":"35412305cbae979aac3b6e2c70cb301ae461979a1d848a8a043f74518eb96aea","provided_features":[{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils-Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:51:32.126Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/df7d561f-feaa-4bc7-bde6-2efafc070da8"},"patch_id":"df7d561f-feaa-4bc7-bde6-2efafc070da8","conditions":null,"content":"ExtUtils-Install-2.14-hpux-inuse-rename.patch","description":"Bug 85799, on HP-UX, first try to rename an in-use file\n instead of immediately giving up.","sequence_number":1}],"resolved_requirements":[]},{"alternatives":["5ae0af7e-aef3-5815-977e-ea78d2dfdd95","fd3ebb99-efb0-5fc4-8329-f36866b44290","b3f16eff-d588-5bbe-a33e-b34e1dbdf72e","d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"d2df2faa-b698-5599-b752-825d3e59cb63","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:37.136Z","ingredient_id":"8291f28e-f684-560c-8875-5c834a4740fd","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8291f28e-f684-560c-8875-5c834a4740fd"},"name":"ExtUtils-MakeMaker","normalized_name":"ExtUtils-MakeMaker","primary_namespace":"language/perl","description":"Create a module Makefile"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-10T18:45:23.625Z","ingredient_id":"8291f28e-f684-560c-8875-5c834a4740fd","ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8291f28e-f684-560c-8875-5c834a4740fd/versions/0067cb0b-fe9b-5c73-b853-bdd90d6e240b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8291f28e-f684-560c-8875-5c834a4740fd"},"revision":1,"revision_timestamp":"2019-12-10T18:45:23.625Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/ExtUtils::MakeMaker","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-09-11T09:16:48.000Z","source_uri":"https://cpan.metacpan.org/authors/id/B/BI/BINGOS/ExtUtils-MakeMaker-7.38.tar.gz","sortable_version":["7","380","0"],"version":"7.38","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/897d64af242331ebb69090f68a2b610091e1996952d02096ce7942072a35e02c/ExtUtils-MakeMaker-7.38.tar.gz","scanner_license_expression":"unknown","source_checksum":"897d64af242331ebb69090f68a2b610091e1996952d02096ce7942072a35e02c","provided_features":[{"feature":"ExtUtils-MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::_version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::charstar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::version::vpp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-12-10T15:57:44.636Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/aae9cf84-3381-45be-b044-a557232eca66"},"patch_id":"aae9cf84-3381-45be-b044-a557232eca66","conditions":null,"content":"s3://platform-sources/patches/c533f762465d39aee2a092a89e61a8d69ef51cc7d365f2d0d7a3231e09cd08f0.patch","description":"ExtUtils-MakeMaker ~ ExtUtils-MakeMaker-7.38-01-ldopts\nCarried forward from 7.30\nMake 'perl -MExtUtils::Embed -e ldopts' output a direct reference to libperl.a if using -lperl would pick up libperl.so.\nhttp://bugs.activestate.com/show_bug.cgi?id=39069\np4-change: 152627","sequence_number":1},{"creation_timestamp":"2019-12-10T15:58:48.730Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/7770ef1d-96a1-4f9b-a89c-7e1e51755a36"},"patch_id":"7770ef1d-96a1-4f9b-a89c-7e1e51755a36","conditions":null,"content":"s3://platform-sources/patches/d8467840f146ddd3e53228e2af5f83ac44af7a6f40912b5c096c6999d422e20c.patch","description":"ExtUtils-MakeMaker ~ ExtUtils-MakeMaker-7.38-02-html-pods\nCarried forward from 7.30\nSupport for HTML PODs","sequence_number":2},{"creation_timestamp":"2019-12-10T16:00:02.140Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/e1a5d58f-4c19-4177-a436-501a92b64b35"},"patch_id":"e1a5d58f-4c19-4177-a436-501a92b64b35","conditions":null,"content":"s3://platform-sources/patches/4e327d9c66c8ca64f42e754b46c96f9fbc01539f231d2afab5049711dda62051.patch","description":"ExtUtils-MakeMaker ~ ExtUtils-MakeMaker-7.38-03-htmldir\nCarried forward from 7.30\nMake sure MakeMaker sets up INSTALL.*HTMLDIR when using INSTALL_BASE\nWithout this change the html docs will be written to root level directories /bin, /lib, and /site (if they are writable; otherwise install will fail).\nThe INSTALL_BASE feature is used by local::lib (and cpanminus).","sequence_number":3},{"creation_timestamp":"2019-12-10T16:01:16.305Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/a4ae5e21-ee99-4e23-96eb-90ca47dfcdea"},"patch_id":"a4ae5e21-ee99-4e23-96eb-90ca47dfcdea","conditions":null,"content":"s3://platform-sources/patches/cde1c1d24b5308c81c1febb868c5b26565b032501b9536db83e8fb315d106195.patch","description":"ExtUtils-MakeMaker ~ ExtUtils-MakeMaker-7.38-skip-xs-on-AIX\nCarried forward from 7.30\nSkip EUMM XS tests on AIX.\nhttps://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker/pull/278","sequence_number":4}],"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"6be9481f-1484-5b4e-9407-05ef48c83c40","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:38.304Z","ingredient_id":"de5c5b9c-b323-501e-96bc-c4bdf75fe8b5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/de5c5b9c-b323-501e-96bc-c4bdf75fe8b5"},"name":"ExtUtils-Manifest","normalized_name":"ExtUtils-Manifest","primary_namespace":"language/perl","description":"utilities to write and check a MANIFEST file"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:38.304Z","ingredient_id":"de5c5b9c-b323-501e-96bc-c4bdf75fe8b5","ingredient_version_id":"c509e237-a516-5cf0-aaec-216a4daaeed4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/de5c5b9c-b323-501e-96bc-c4bdf75fe8b5/versions/c509e237-a516-5cf0-aaec-216a4daaeed4","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/de5c5b9c-b323-501e-96bc-c4bdf75fe8b5"},"revision":6,"revision_timestamp":"2019-11-05T00:50:49.251Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2014-12-31T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/E/ET/ETHER/ExtUtils-Manifest-1.70.tar.gz","sortable_version":["1","70","0"],"version":"1.70","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ExtUtils/Manifest","required":"1"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/eeff062050b223964cd8f624a90ae75df443612239df34a20ff87644f9f52b95/ExtUtils-Manifest-1.70.tar.gz","scanner_license_expression":"unknown","source_checksum":"eeff062050b223964cd8f624a90ae75df443612239df34a20ff87644f9f52b95","provided_features":[{"feature":"ExtUtils-Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.70"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.70"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"d78ed36e-672c-59e3-81c9-5761074f6c97","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:55.496Z","ingredient_id":"b58e146b-377e-54f5-9424-705f681840f3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/b58e146b-377e-54f5-9424-705f681840f3"},"name":"Getopt-Long","normalized_name":"Getopt-Long","primary_namespace":"language/perl","description":"Module to handle parsing command line options"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:55.496Z","ingredient_id":"b58e146b-377e-54f5-9424-705f681840f3","ingredient_version_id":"f21bbf0a-4665-5fb9-88b8-3eb9a22a7da7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/b58e146b-377e-54f5-9424-705f681840f3/versions/f21bbf0a-4665-5fb9-88b8-3eb9a22a7da7","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/b58e146b-377e-54f5-9424-705f681840f3"},"revision":4,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0 OR GPL-2.0-or-later","release_timestamp":"2017-05-27T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/J/JV/JV/Getopt-Long-2.50.tar.gz","sortable_version":["2","50","0"],"version":"2.50","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Getopt/Long"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/20881adb2b73e83825f9a0a3b141db11b3a555e1d3775b13d81d0481623e4b67/Getopt-Long-2.50.tar.gz","scanner_license_expression":"unknown","source_checksum":"20881adb2b73e83825f9a0a3b141db11b3a555e1d3775b13d81d0481623e4b67","provided_features":[{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.50"},{"feature":"Getopt-Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.50"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"e8b01fb8-3e62-5ac4-8e4b-422945b8cc9d","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"3b05243a-b6da-57ec-8c57-8de5221b8937"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"4b150af7-4abd-5bad-849c-94cde6b59fed"},{"dependency_types":["runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:57.424Z","ingredient_id":"7075b232-08c5-5ad7-bf90-943d1b32dcf0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7075b232-08c5-5ad7-bf90-943d1b32dcf0"},"name":"HTML-Parser","normalized_name":"HTML-Parser","primary_namespace":"language/perl","description":"HTML parser class"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:57.424Z","ingredient_id":"7075b232-08c5-5ad7-bf90-943d1b32dcf0","ingredient_version_id":"1cb4ca5e-4e4e-59fb-b2cb-5fdb54856ff0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7075b232-08c5-5ad7-bf90-943d1b32dcf0/versions/1cb4ca5e-4e4e-59fb-b2cb-5fdb54856ff0","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7075b232-08c5-5ad7-bf90-943d1b32dcf0"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2016-01-19T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/G/GA/GAAS/HTML-Parser-3.72.tar.gz","sortable_version":["3","72","0"],"version":"3.72","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTML/Parser"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/ec28c7e1d9e67c45eca197077f7cdc41ead1bb4c538c7f02a3296a4bb92f608b/HTML-Parser-3.72.tar.gz","scanner_license_expression":"unknown","source_checksum":"ec28c7e1d9e67c45eca197077f7cdc41ead1bb4c538c7f02a3296a4bb92f608b","provided_features":[{"feature":"HTML-Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","72","0"],"version":"3.72"},{"feature":"HTML::Entities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","69","0"],"version":"3.69"},{"feature":"HTML::Filter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","72","0"],"version":"3.72"},{"feature":"HTML::HeadParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","71","0"],"version":"3.71"},{"feature":"HTML::LinkExtor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","69","0"],"version":"3.69"},{"feature":"HTML::Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","72","0"],"version":"3.72"},{"feature":"HTML::PullParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","57","0"],"version":"3.57"},{"feature":"HTML::TokeParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","69","0"],"version":"3.69"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"9a4b00f2-45fd-5480-b790-302bec5db07d","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:58.616Z","ingredient_id":"642ba5a2-5d51-5c4e-87fa-3685665bd030","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/642ba5a2-5d51-5c4e-87fa-3685665bd030"},"name":"HTML-Tagset","normalized_name":"HTML-Tagset","primary_namespace":"language/perl","description":"data tables useful in parsing HTML"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:58.616Z","ingredient_id":"642ba5a2-5d51-5c4e-87fa-3685665bd030","ingredient_version_id":"4b150af7-4abd-5bad-849c-94cde6b59fed","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/642ba5a2-5d51-5c4e-87fa-3685665bd030/versions/4b150af7-4abd-5bad-849c-94cde6b59fed","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/642ba5a2-5d51-5c4e-87fa-3685665bd030"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2008-03-01T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/P/PE/PETDANCE/HTML-Tagset-3.20.tar.gz","sortable_version":["3","20","0"],"version":"3.20","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTML/Tagset"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/adb17dac9e36cd011f5243881c9739417fd102fce760f8de4e9be4c7131108e2/HTML-Tagset-3.20.tar.gz","scanner_license_expression":"unknown","source_checksum":"adb17dac9e36cd011f5243881c9739417fd102fce760f8de4e9be4c7131108e2","provided_features":[{"feature":"HTML-Tagset","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","20","0"],"version":"3.20"},{"feature":"HTML::Tagset","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","20","0"],"version":"3.20"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"701c6b1f-2b6c-56c9-ae5d-f3ae17cd3d1e","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:02.127Z","ingredient_id":"9ed3546f-abf3-546f-a532-d4badd1937f7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9ed3546f-abf3-546f-a532-d4badd1937f7"},"name":"HTTP-Date","normalized_name":"HTTP-Date","primary_namespace":"language/perl","description":"date conversion routines"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:02.127Z","ingredient_id":"9ed3546f-abf3-546f-a532-d4badd1937f7","ingredient_version_id":"91cd893b-5b8c-5391-9c77-643fb85af0af","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9ed3546f-abf3-546f-a532-d4badd1937f7/versions/91cd893b-5b8c-5391-9c77-643fb85af0af","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9ed3546f-abf3-546f-a532-d4badd1937f7"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-Perl OR GPL-1.0-or-later","release_timestamp":"2012-03-30T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/G/GA/GAAS/HTTP-Date-6.02.tar.gz","sortable_version":["6","2","0"],"version":"6.2","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTTP/Date"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/e8b9941da0f9f0c9c01068401a5e81341f0e3707d1c754f8e11f42a7e629e333/HTTP-Date-6.02.tar.gz","scanner_license_expression":"unknown","source_checksum":"e8b9941da0f9f0c9c01068401a5e81341f0e3707d1c754f8e11f42a7e629e333","provided_features":[{"feature":"HTTP-Date","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","2","0"],"version":"6.2"},{"feature":"HTTP::Date","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","2","0"],"version":"6.2"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c24ffb45-a21d-561f-ad66-d56556b2bdb4","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"50f0603e-048d-5f9a-ac44-9d32df97809d"},{"dependency_types":["build"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:02.612Z","ingredient_id":"80076996-fc73-50c2-850e-a606a139b302","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/80076996-fc73-50c2-850e-a606a139b302"},"name":"HTTP-Message","normalized_name":"HTTP-Message","primary_namespace":"language/perl","description":"HTTP style message (base class)"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:02.612Z","ingredient_id":"80076996-fc73-50c2-850e-a606a139b302","ingredient_version_id":"3e08c8d3-fe88-5c33-82df-ded1e3d15a0b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/80076996-fc73-50c2-850e-a606a139b302/versions/3e08c8d3-fe88-5c33-82df-ded1e3d15a0b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/80076996-fc73-50c2-850e-a606a139b302"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-12-20T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/O/OA/OALDERS/HTTP-Message-6.14.tar.gz","sortable_version":["6","14","0"],"version":"6.14","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTTP/Message"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/71aab9f10eb4b8ec6e8e3a85fc5acb46ba04db1c93eb99613b184078c5cf2ac9/HTTP-Message-6.14.tar.gz","scanner_license_expression":"unknown","source_checksum":"71aab9f10eb4b8ec6e8e3a85fc5acb46ba04db1c93eb99613b184078c5cf2ac9","provided_features":[{"feature":"HTTP-Message","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Headers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Headers::Auth","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Headers::ETag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Headers::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Message","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Request","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Request::Common","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Response","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Status","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"7d72ca66-ae36-5e6f-a491-d649bbdb8b8f","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["runtime"],"ingredient_version_id":"3e08c8d3-fe88-5c33-82df-ded1e3d15a0b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:03.039Z","ingredient_id":"2950e101-1150-5ab1-affe-ab6ac3d4b6e7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2950e101-1150-5ab1-affe-ab6ac3d4b6e7"},"name":"HTTP-Negotiate","normalized_name":"HTTP-Negotiate","primary_namespace":"language/perl","description":"choose a variant to serve"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:03.039Z","ingredient_id":"2950e101-1150-5ab1-affe-ab6ac3d4b6e7","ingredient_version_id":"e4b6a074-ad51-5b69-95ce-7747c95471f8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2950e101-1150-5ab1-affe-ab6ac3d4b6e7/versions/e4b6a074-ad51-5b69-95ce-7747c95471f8","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2950e101-1150-5ab1-affe-ab6ac3d4b6e7"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-Perl OR GPL-1.0-or-later","release_timestamp":"2012-02-18T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/G/GA/GAAS/HTTP-Negotiate-6.01.tar.gz","sortable_version":["6","1","0"],"version":"6.1","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTTP/Negotiate"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/1c729c1ea63100e878405cda7d66f9adfd3ed4f1d6cacaca0ee9152df728e016/HTTP-Negotiate-6.01.tar.gz","scanner_license_expression":"unknown","source_checksum":"1c729c1ea63100e878405cda7d66f9adfd3ed4f1d6cacaca0ee9152df728e016","provided_features":[{"feature":"HTTP-Negotiate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","1","0"],"version":"6.1"},{"feature":"HTTP::Negotiate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","1","0"],"version":"6.1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["96636fc0-a33a-5825-8f5d-5122b3812a0f"],"artifact_id":"8d011eb1-3d8e-5074-a8b2-d41586e53059","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["runtime"],"ingredient_version_id":"3b05243a-b6da-57ec-8c57-8de5221b8937"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"bebc32d9-b8e0-59dd-97b2-098496e9fd61"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:22.652Z","ingredient_id":"21072e99-9e15-5b56-a8fc-e83864695be8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/21072e99-9e15-5b56-a8fc-e83864695be8"},"name":"JSON-PP","normalized_name":"JSON-PP","primary_namespace":"language/perl","description":"JSON::XS compatible pure-Perl module."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-11-13T15:08:42.291Z","ingredient_id":"21072e99-9e15-5b56-a8fc-e83864695be8","ingredient_version_id":"50f0603e-048d-5f9a-ac44-9d32df97809d","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/21072e99-9e15-5b56-a8fc-e83864695be8/versions/50f0603e-048d-5f9a-ac44-9d32df97809d","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/21072e99-9e15-5b56-a8fc-e83864695be8"},"revision":1,"revision_timestamp":"2019-11-13T15:08:42.291Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/JSON::PP","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-06-29T09:52:40.000Z","source_uri":"https://cpan.metacpan.org/authors/id/I/IS/ISHIGAKI/JSON-PP-4.04.tar.gz","sortable_version":["4","40","0"],"version":"4.04","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/81311c56d7b94bbf8003cf421e87961efba576189198e516fd5426889650b66a/JSON-PP-4.04.tar.gz","scanner_license_expression":"unknown","source_checksum":"81311c56d7b94bbf8003cf421e87961efba576189198e516fd5426889650b66a","provided_features":[{"feature":"JSON-PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","40","0"],"version":"4.04"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","40","0"],"version":"4.04"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","40","0"],"version":"4.04"},{"feature":"JSON::PP::IncrParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","40","0"],"version":"4.04"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["a921e82c-9204-5b32-b7fb-3491c52b4e6b"],"artifact_id":"79b640e2-85c5-5e36-b466-cec860002061","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build","runtime"],"ingredient_version_id":"142400e9-5965-5a41-813a-427106fbf770"},{"dependency_types":["runtime"],"ingredient_version_id":"28f42dcf-0e80-5058-92a5-729ca91955a8"},{"dependency_types":["runtime"],"ingredient_version_id":"34a46b65-4429-5882-ba28-f7d09bb8a1d6"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"9d19c878-dde6-5bc7-a0a1-aee1a15cf1a2"},{"dependency_types":["build","runtime"],"ingredient_version_id":"ad8f2146-84db-5542-b4b7-c188f18784d7"},{"dependency_types":["runtime"],"ingredient_version_id":"b131cae2-42e2-564e-a217-1266ea60ff62"},{"dependency_types":["runtime"],"ingredient_version_id":"c509e237-a516-5cf0-aaec-216a4daaeed4"},{"dependency_types":["build","runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"},{"dependency_types":["runtime"],"ingredient_version_id":"f21bbf0a-4665-5fb9-88b8-3eb9a22a7da7"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:48.137Z","ingredient_id":"c709227b-f464-5cb3-b53f-de99f4244cb1","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c709227b-f464-5cb3-b53f-de99f4244cb1"},"name":"Module-Build","normalized_name":"Module-Build","primary_namespace":"language/perl","description":"Build and install Perl modules"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-12T22:59:25.654Z","ingredient_id":"c709227b-f464-5cb3-b53f-de99f4244cb1","ingredient_version_id":"5b9149e8-2334-5454-a523-cd9787003344","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c709227b-f464-5cb3-b53f-de99f4244cb1/versions/5b9149e8-2334-5454-a523-cd9787003344","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c709227b-f464-5cb3-b53f-de99f4244cb1"},"revision":3,"revision_timestamp":"2020-04-22T15:09:12.488Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Module::Build","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-04-15T22:52:38.000Z","source_uri":"https://cpan.metacpan.org/authors/id/L/LE/LEONT/Module-Build-0.4229.tar.gz","sortable_version":["0","422","900"],"version":"0.4229","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/1fe491a6cda914b01bc8e592faa2b5404e9f35915ca15322f8f2a8d8f9008c18/Module-Build-0.4229.tar.gz","scanner_license_expression":"unknown","source_checksum":"1fe491a6cda914b01bc8e592faa2b5404e9f35915ca15322f8f2a8d8f9008c18","provided_features":[{"feature":"Module::Build::PodParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::Default","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::PPMMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Notes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Cookbook","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Compat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module-Build","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"56135216-8f1d-5289-a8db-fae6e287dcbd","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:51.673Z","ingredient_id":"441965ba-8592-5986-b10d-7e1d959ddfd9","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/441965ba-8592-5986-b10d-7e1d959ddfd9"},"name":"Module-Metadata","normalized_name":"Module-Metadata","primary_namespace":"language/perl","description":"Gather package and POD information from perl module files"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:51.673Z","ingredient_id":"441965ba-8592-5986-b10d-7e1d959ddfd9","ingredient_version_id":"ad8f2146-84db-5542-b4b7-c188f18784d7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/441965ba-8592-5986-b10d-7e1d959ddfd9/versions/ad8f2146-84db-5542-b4b7-c188f18784d7","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/441965ba-8592-5986-b10d-7e1d959ddfd9"},"revision":4,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2016-07-24T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/E/ET/ETHER/Module-Metadata-1.000033.tar.gz","sortable_version":["1","33","0"],"version":"1.33","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Module/Metadata"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/bc96cc7949b52e2dac1595e806102640760917cfcd7497c7a023192156f3ff8e/Module-Metadata-1.000033.tar.gz","scanner_license_expression":"unknown","source_checksum":"bc96cc7949b52e2dac1595e806102640760917cfcd7497c7a023192156f3ff8e","provided_features":[{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","33","0"],"version":"1.33"},{"feature":"Module-Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","33","0"],"version":"1.33"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c561e3f0-2aba-5277-8315-279a9f06a8ca","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:59.671Z","ingredient_id":"d6b106ec-77df-51da-9864-5a040bf0711a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d6b106ec-77df-51da-9864-5a040bf0711a"},"name":"Net-HTTP","normalized_name":"Net-HTTP","primary_namespace":"language/perl","description":"Low-level HTTP connection (client)"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:59.671Z","ingredient_id":"d6b106ec-77df-51da-9864-5a040bf0711a","ingredient_version_id":"06d43cc3-8f67-575b-b34d-0ec60e9ae67e","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d6b106ec-77df-51da-9864-5a040bf0711a/versions/06d43cc3-8f67-575b-b34d-0ec60e9ae67e","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d6b106ec-77df-51da-9864-5a040bf0711a"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-09-01T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/O/OA/OALDERS/Net-HTTP-6.17.tar.gz","sortable_version":["6","17","0"],"version":"6.17","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Net/HTTP"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/1e8624b1618dc6f7f605f5545643ebb9b833930f4d7485d4124aa2f2f26d1611/Net-HTTP-6.17.tar.gz","scanner_license_expression":"unknown","source_checksum":"1e8624b1618dc6f7f605f5545643ebb9b833930f4d7485d4124aa2f2f26d1611","provided_features":[{"feature":"Net-HTTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"},{"feature":"Net::HTTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"},{"feature":"Net::HTTP::Methods","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"},{"feature":"Net::HTTP::NB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"},{"feature":"Net::HTTPS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["21a740ba-c54d-5a78-bc42-0fdb7dced2ba","d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"aea53a58-9da4-5c4a-9259-fc533a28cbc6","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:53:18.167Z","ingredient_id":"13dc7a1e-eef1-5153-b1ce-e7632febd346","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/13dc7a1e-eef1-5153-b1ce-e7632febd346"},"name":"PathTools","normalized_name":"PathTools","primary_namespace":"language/perl","description":"unknown"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:43.162Z","ingredient_id":"13dc7a1e-eef1-5153-b1ce-e7632febd346","ingredient_version_id":"142400e9-5965-5a41-813a-427106fbf770","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/13dc7a1e-eef1-5153-b1ce-e7632febd346/versions/142400e9-5965-5a41-813a-427106fbf770","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/13dc7a1e-eef1-5153-b1ce-e7632febd346"},"revision":2,"revision_timestamp":"2019-12-06T21:46:46.530Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Cwd","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2018-08-29T19:53:19.000Z","source_uri":"https://cpan.metacpan.org/authors/id/X/XS/XSAWYERX/PathTools-3.75.tar.gz","sortable_version":["3","750","0"],"version":"3.75","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/a558503aa6b1f8c727c0073339081a77888606aa701ada1ad62dd9d8c3f945a2/PathTools-3.75.tar.gz","scanner_license_expression":"unknown","source_checksum":"a558503aa6b1f8c727c0073339081a77888606aa701ada1ad62dd9d8c3f945a2","provided_features":[{"feature":"Cwd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"PathTools","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a","c287183e-48c8-5bfe-9b9d-0ead376370fe"],"artifact_id":"18f5dfd6-e09c-5bff-9dd8-a182a757b52b","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"9d19c878-dde6-5bc7-a0a1-aee1a15cf1a2"}],"ingredient":{"creation_timestamp":"2019-10-01T16:53:42.402Z","ingredient_id":"9c61e880-bed6-59de-807a-4ace3191d81b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9c61e880-bed6-59de-807a-4ace3191d81b"},"name":"Scalar-List-Utils","normalized_name":"Scalar-List-Utils","primary_namespace":"language/perl","description":"Common Scalar and List utility subroutines"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:56.566Z","ingredient_id":"9c61e880-bed6-59de-807a-4ace3191d81b","ingredient_version_id":"bebc32d9-b8e0-59dd-97b2-098496e9fd61","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9c61e880-bed6-59de-807a-4ace3191d81b/versions/bebc32d9-b8e0-59dd-97b2-098496e9fd61","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9c61e880-bed6-59de-807a-4ace3191d81b"},"revision":2,"revision_timestamp":"2019-12-06T22:22:08.218Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Sub::Util","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-10-24T09:43:15.000Z","source_uri":"https://cpan.metacpan.org/authors/id/P/PE/PEVANS/Scalar-List-Utils-1.53.tar.gz","sortable_version":["1","530","0"],"version":"1.53","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/bd4086b066fb3b18a0be2e7d9bc100a99aa0f233ad659492340415c7b2bdae99/Scalar-List-Utils-1.53.tar.gz","scanner_license_expression":"unknown","source_checksum":"bd4086b066fb3b18a0be2e7d9bc100a99aa0f233ad659492340415c7b2bdae99","provided_features":[{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"},{"feature":"Scalar-List-Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a","bbfeffca-adbf-53df-9e84-dcbc83f804bd","19f1be8e-2dc4-58be-a370-00627a6ce003"],"artifact_id":"86d6c830-22f3-5c53-b9cb-74dcfc8a0d03","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:16.878Z","ingredient_id":"2df1c8f2-0db1-506c-b339-d36a23aa303a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2df1c8f2-0db1-506c-b339-d36a23aa303a"},"name":"Test-Simple","normalized_name":"Test-Simple","primary_namespace":"language/perl","description":"Basic utilities for writing tests."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:33.143Z","ingredient_id":"2df1c8f2-0db1-506c-b339-d36a23aa303a","ingredient_version_id":"3b05243a-b6da-57ec-8c57-8de5221b8937","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2df1c8f2-0db1-506c-b339-d36a23aa303a/versions/3b05243a-b6da-57ec-8c57-8de5221b8937","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2df1c8f2-0db1-506c-b339-d36a23aa303a"},"revision":2,"revision_timestamp":"2019-12-06T21:38:18.262Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Test::Simple","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-12-02T21:27:53.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test-Simple-1.302170.tar.gz","sortable_version":["1","302","170"],"version":"1.302170","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/50dc374f93316ed1c251433e1f91050e82a56711ff47a7b333602e017e3bfe3a/Test-Simple-1.302170.tar.gz","scanner_license_expression":"unknown","source_checksum":"50dc374f93316ed1c251433e1f91050e82a56711ff47a7b333602e017e3bfe3a","provided_features":[{"feature":"Test-Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Info::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Tester::Tie","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"b3dd6720-f5bc-5c4d-8690-ee764aaf89ca","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:49.138Z","ingredient_id":"e10d6669-f1c9-57ef-a77e-3bb8fa3df884","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/e10d6669-f1c9-57ef-a77e-3bb8fa3df884"},"name":"URI","normalized_name":"URI","primary_namespace":"language/perl","description":"Uniform Resource Identifiers (absolute and relative)"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:54:49.138Z","ingredient_id":"e10d6669-f1c9-57ef-a77e-3bb8fa3df884","ingredient_version_id":"1a882ae6-d86f-5431-a5cb-8caa0abeedf5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/e10d6669-f1c9-57ef-a77e-3bb8fa3df884/versions/1a882ae6-d86f-5431-a5cb-8caa0abeedf5","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/e10d6669-f1c9-57ef-a77e-3bb8fa3df884"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2018-01-09T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/E/ET/ETHER/URI-1.73.tar.gz","sortable_version":["1","73","0"],"version":"1.73","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"URI"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/cca7ab4a6f63f3ccaacae0f2e1337e8edf84137e73f18548ec7d659f23efe413/URI-1.73.tar.gz","scanner_license_expression":"unknown","source_checksum":"cca7ab4a6f63f3ccaacae0f2e1337e8edf84137e73f18548ec7d659f23efe413","provided_features":[{"feature":"URI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::Escape","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","31","0"],"version":"3.31"},{"feature":"URI::Heuristic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","20","0"],"version":"4.20"},{"feature":"URI::IRI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::QueryParam","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::Split","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","4","0"],"version":"5.4"},{"feature":"URI::WithBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.20"},{"feature":"URI::_foreign","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_idna","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_ldap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_login","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_punycode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_query","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_segment","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_server","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_userpass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::data","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","21","0"],"version":"4.21"},{"feature":"URI::file::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::FAT","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ftp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::gopher","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::http","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::https","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ldap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ldapi","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ldaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::mailto","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::mms","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::news","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::nntp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::pop","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::rlogin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::rsync","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::rtsp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::rtspu","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::sftp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::sip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::sips","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::snews","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ssh","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::telnet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::tn3270","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::urn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::urn::isbn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::urn::oid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"f54623d0-376f-5024-b237-c1e78a926ff8","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:55:07.132Z","ingredient_id":"6184d401-d399-5634-9a36-49b77e680ee4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6184d401-d399-5634-9a36-49b77e680ee4"},"name":"Win32-ShellQuote","normalized_name":"Win32-ShellQuote","primary_namespace":"language/perl","description":"Quote argument lists for Win32"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:55:07.132Z","ingredient_id":"6184d401-d399-5634-9a36-49b77e680ee4","ingredient_version_id":"3d2abb3d-07d3-5fac-ba8b-897484c7d98c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6184d401-d399-5634-9a36-49b77e680ee4/versions/3d2abb3d-07d3-5fac-ba8b-897484c7d98c","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6184d401-d399-5634-9a36-49b77e680ee4"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2016-09-27T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/H/HA/HAARG/Win32-ShellQuote-0.003001.tar.gz","sortable_version":["0","3","1","0"],"version":"0.3.1","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Win32/ShellQuote","require_os":["MSWin32","MSWin32"]},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/aa74b0e3dc2d41cd63f62f853e521ffd76b8d823479a2619e22edb4049b4c0dc/Win32-ShellQuote-0.003001.tar.gz","scanner_license_expression":"unknown","source_checksum":"aa74b0e3dc2d41cd63f62f853e521ffd76b8d823479a2619e22edb4049b4c0dc","provided_features":[{"feature":"Win32-ShellQuote","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","1","0"],"version":"0.3.1"},{"feature":"Win32::ShellQuote","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","1","0"],"version":"0.30.1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"Win32-ShellQuote","namespace":"language/perl","version_requirements":[{"comparator":"eq","version":"0.3.1"}]}]},{"alternatives":[],"artifact_id":"0df374fb-9686-5e09-80ee-93e1943dd1eb","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:55:57.867Z","ingredient_id":"438c3d67-b979-579d-942a-cd6a47976113","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/438c3d67-b979-579d-942a-cd6a47976113"},"name":"libwww-perl","normalized_name":"libwww-perl","primary_namespace":"language/perl","description":"The World-Wide Web library for Perl"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:55:57.867Z","ingredient_id":"438c3d67-b979-579d-942a-cd6a47976113","ingredient_version_id":"84a01b55-1d92-53ae-a7cb-d591b7b54724","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/438c3d67-b979-579d-942a-cd6a47976113/versions/84a01b55-1d92-53ae-a7cb-d591b7b54724","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/438c3d67-b979-579d-942a-cd6a47976113"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-12-11T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/E/ET/ETHER/libwww-perl-6.31.tar.gz","sortable_version":["6","31","0"],"version":"6.31","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"libwww/perl"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/525d5386d39d1c1d7da8a0e9dd0cbab95cba2a4bfcfd9b83b257f49be4eecae3/libwww-perl-6.31.tar.gz","scanner_license_expression":"unknown","source_checksum":"525d5386d39d1c1d7da8a0e9dd0cbab95cba2a4bfcfd9b83b257f49be4eecae3","provided_features":[{"feature":"LWP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Authen::Basic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Authen::Digest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Authen::Ntlm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::ConnCache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Debug::TraceHTTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::DebugFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::MemberMixin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::data","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::ftp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::gopher","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::http","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::loopback","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::mailto","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::nntp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::nogo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::RobotUA","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"libwww-perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"libwww-perl","namespace":"language/perl","version_requirements":[{"comparator":"gte","version":"0"}]}]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a","a156d3e3-3f38-55ee-a5c0-af32af5e8e7c"],"artifact_id":"84393ca8-9ac8-5e3c-a820-fa55b91bda42","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:58:19.876Z","ingredient_id":"ce716f45-743d-56e6-9d06-102a58dc9c24","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ce716f45-743d-56e6-9d06-102a58dc9c24"},"name":"podlators","normalized_name":"podlators","primary_namespace":"language/perl","description":"Convert POD data to various other formats"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:48.703Z","ingredient_id":"ce716f45-743d-56e6-9d06-102a58dc9c24","ingredient_version_id":"b131cae2-42e2-564e-a217-1266ea60ff62","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ce716f45-743d-56e6-9d06-102a58dc9c24/versions/b131cae2-42e2-564e-a217-1266ea60ff62","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ce716f45-743d-56e6-9d06-102a58dc9c24"},"revision":2,"revision_timestamp":"2019-12-06T22:02:12.393Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Pod::Man","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-06-01T04:04:13.000Z","source_uri":"https://cpan.metacpan.org/authors/id/R/RR/RRA/podlators-4.12.tar.gz","sortable_version":["4","120","0"],"version":"4.12","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/948717da19630a5f003da4406da90fe1cbdec9ae493671c90dfb6d8b3d63b7eb/podlators-4.12.tar.gz","scanner_license_expression":"unknown","source_checksum":"948717da19630a5f003da4406da90fe1cbdec9ae493671c90dfb6d8b3d63b7eb","provided_features":[{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"podlators","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["51d0cb50-cb63-5d61-9312-03343731a5c7","189665e3-7ac1-52ab-8211-8ba1ca7815f7","801206d7-a69c-53fd-9f44-a39851413669","77fc8d23-fc48-5db5-b606-f5276c1bceff","8329dae3-9920-56ae-a768-6a4c64e52436","ac073035-67b4-5786-9aa3-0cb043936036"],"artifact_id":"50d60c15-ab99-5f25-bca9-e8db079f49d3","build_scripts":[{"build_script_id":"606265a1-ac03-48e0-a708-115cc5004e9a","creation_timestamp":"2019-10-01T16:56:10.414Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/606265a1-ac03-48e0-a708-115cc5004e9a"},"conditions":null,"language":"perl","script":"openssl-1.1.0-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:17.721Z","ingredient_id":"c1256669-2a2d-5cf2-8860-804bf43ceb5f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f"},"name":"openssl","normalized_name":"openssl","primary_namespace":"shared","description":"Open Secure Sockets Layer general cryptography library."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:56:17.721Z","ingredient_id":"c1256669-2a2d-5cf2-8860-804bf43ceb5f","ingredient_version_id":"865b7af2-2892-5cb4-8a61-100a21332b5c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f/versions/865b7af2-2892-5cb4-8a61-100a21332b5c","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2019-05-28T00:00:00.000Z","source_uri":"https://www.openssl.org/source/openssl-1.1.0k.tar.gz","sortable_version":["1","10","0","11","0"],"version":"1.10.0.11","activestate_license_expression":"unknown","camel_extras":{"ppm_pkg":"no"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/efa4965f4f773574d6cbda1cf874dbbe455ab1c0d4f906115f867d30444470b1/openssl-1.1.0k.tar.gz","scanner_license_expression":"unknown","source_checksum":"efa4965f4f773574d6cbda1cf874dbbe455ab1c0d4f906115f867d30444470b1","provided_features":[{"feature":"openssl","is_activestate_version":false,"is_default_provider":true,"namespace":"shared","sortable_version":["1","10","0","11","0"],"version":"1.10.0.11"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:56:13.279Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/402b7749-a78a-4913-8cf3-65f7457f0631"},"patch_id":"402b7749-a78a-4913-8cf3-65f7457f0631","conditions":null,"content":"/src/Libraries/patches/openssl/1.10.0.11/0001-Port-1.1.0h-patch-forward-to-1.1.0k.patch","description":"[PATCH 1/3] Port 1.1.0h patch forward to 1.1.0k","sequence_number":1},{"creation_timestamp":"2019-10-01T16:56:13.634Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/f44ea593-761b-44e0-8d29-509f1dd45e6a"},"patch_id":"f44ea593-761b-44e0-8d29-509f1dd45e6a","conditions":null,"content":"/src/Libraries/patches/openssl/1.10.0.11/0002-Disable-test_err.patch","description":"[PATCH 2/3] Disable test_err","sequence_number":2},{"creation_timestamp":"2019-10-01T16:56:13.998Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/d4e5c7df-8444-4a25-a4db-ffe0b86fa0d6"},"patch_id":"d4e5c7df-8444-4a25-a4db-ffe0b86fa0d6","conditions":null,"content":"/src/Libraries/patches/openssl/1.10.0.11/0003-Add-quotes-for-windows.patch","description":"[PATCH 3/3] Add quotes for windows\n\nOn windows the command for apps/openssl\nrequires quotes to work in runtime.","sequence_number":3}],"resolved_requirements":[{"feature":"openssl","namespace":"shared","version_requirements":[{"comparator":"gte","version":"0"},{"comparator":"lt","version":"1.11.0.0"}]}]},{"alternatives":[],"artifact_id":"6938f428-a31c-5347-8f0b-e1a9650addef","build_scripts":[{"build_script_id":"677467f0-5e38-4e3b-b623-9e8464a49f91","creation_timestamp":"2019-10-01T16:58:22.954Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/677467f0-5e38-4e3b-b623-9e8464a49f91"},"conditions":null,"language":"perl","script":"postgresql-9.5.4-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"865b7af2-2892-5cb4-8a61-100a21332b5c"}],"ingredient":{"creation_timestamp":"2019-10-01T16:58:24.412Z","ingredient_id":"d89530be-8d94-5e35-b606-d7849f073e74","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d89530be-8d94-5e35-b606-d7849f073e74"},"name":"postgresql","normalized_name":"postgresql","primary_namespace":"shared","description":"An object-relational database system"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:58:24.412Z","ingredient_id":"d89530be-8d94-5e35-b606-d7849f073e74","ingredient_version_id":"a873d528-56e8-5c19-b5cb-383be3bb9074","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d89530be-8d94-5e35-b606-d7849f073e74/versions/a873d528-56e8-5c19-b5cb-383be3bb9074","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d89530be-8d94-5e35-b606-d7849f073e74"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2017-05-08T00:00:00.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/Libraries/vendor/postgresql-9.6.3.tar.gz","sortable_version":["9","6","3","0"],"version":"9.6.3","activestate_license_expression":"unknown","camel_extras":{"dont_build":["hpux","solaris"],"ppm_pkg":"no","skip_test":"yes"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/df088372230b1dd21d87bb81686471508f4c42094d4f4f32b5d8e686fea69fa6/postgresql-9.6.3.tar.gz","scanner_license_expression":"unknown","source_checksum":"df088372230b1dd21d87bb81686471508f4c42094d4f4f32b5d8e686fea69fa6","provided_features":[{"feature":"postgresql","is_activestate_version":false,"is_default_provider":true,"namespace":"shared","sortable_version":["9","6","3","0"],"version":"9.6.3"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:58:23.305Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/4aafe925-353a-45d3-813a-2f32265e2eb4"},"patch_id":"4aafe925-353a-45d3-813a-2f32265e2eb4","conditions":null,"content":"/src/Libraries/patches/postgresql-9.5.4-win32.patch","description":"[PATCH 2/2] ActiveState patches for building under MinGW and MSVC","sequence_number":1},{"creation_timestamp":"2019-10-01T16:58:23.666Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/172db555-6bc9-4aeb-afec-ca22308daa4d"},"patch_id":"172db555-6bc9-4aeb-afec-ca22308daa4d","conditions":null,"content":"/src/Libraries/patches/postgresql-9.5.4-fix-old-sun-compiler.patch","description":"Don't use __attribute__ for versions of Sun C that don't\n support it","sequence_number":2},{"creation_timestamp":"2019-10-01T16:58:24.018Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/0de4632f-8673-49d4-a504-a94ccb9ea441"},"patch_id":"0de4632f-8673-49d4-a504-a94ccb9ea441","conditions":null,"content":"/src/Libraries/patches/postgresql-9.5.4-disable-shared.patch","description":"[PATCH 3/3] Patch back in support for --disable-shared, which was\n removed from Postgres starting in 9.3. This is basically just the reverse of\n 381a9ed.","sequence_number":3}],"resolved_requirements":[]}],"solver_version":0} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/recipes/perl.json b/pkg/platform/runtime/testhelper/data/recipes/perl.json deleted file mode 100644 index fa3b32b605..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/perl.json +++ /dev/null @@ -1 +0,0 @@ -{"camel_flags":[],"from_recipe_store":true,"image":{"image_id":"0fceabb4-ca86-4846-9b0a-c23947770cdb","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/0fceabb4-ca86-4846-9b0a-c23947770cdb"},"name":"activestate/centos-7.6-build","platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a","type":"Docker","sortable_version":["1","0","4","0"],"version":"1.0.4","provided_features":[{"feature":"perl-build-tools","is_activestate_version":true,"is_default_provider":false,"namespace":"image","sortable_version":["0"],"version":"0"},{"feature":"python-build-tools","is_activestate_version":true,"is_default_provider":false,"namespace":"image","sortable_version":["0"],"version":"0"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"conditions":null,"revision":5,"revision_timestamp":"2020-01-30T20:00:03.523Z"},"is_indemnified":false,"platform":{"cpu_architecture":{"cpu_architecture_id":"4cdba18d-0851-4925-9ae5-9c8a2987828a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a"},"bit_width":"64","name":"x86","provided_features":[{"feature":"x86 64-bit","is_activestate_version":false,"is_default_provider":true,"namespace":"cpu-architecture","sortable_version":["1"],"version":"1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"cpu_extensions":[],"creation_timestamp":"2019-08-06T21:46:35.288Z","display_name":"CentOS 7.6.1810, Linux 4.15.0, glibc 2.17 x86 64-bit","images":[{"image_id":"0fceabb4-ca86-4846-9b0a-c23947770cdb","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/0fceabb4-ca86-4846-9b0a-c23947770cdb"},"name":"activestate/centos-7.6-build","platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a","type":"Docker","sortable_version":["1","0","4","0"],"version":"1.0.4","provided_features":[{"feature":"perl-build-tools","is_activestate_version":true,"is_default_provider":false,"namespace":"image","sortable_version":["0"],"version":"0"},{"feature":"python-build-tools","is_activestate_version":true,"is_default_provider":false,"namespace":"image","sortable_version":["0"],"version":"0"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"conditions":null,"revision":5,"revision_timestamp":"2020-01-30T20:00:03.523Z"}],"is_user_visible":true,"kernel":{"kernel_id":"ef737274-fff9-4164-b72b-88067613f822","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822"},"name":"Linux"},"kernel_version":{"kernel_version_id":"2450c462-66e0-4aca-97d4-9910a19996f6","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/2450c462-66e0-4aca-97d4-9910a19996f6"},"sortable_version":["4","15","0"],"version":"4.15.0","provided_features":[{"feature":"Linux","is_activestate_version":false,"is_default_provider":true,"namespace":"kernel","sortable_version":["4","15","0"],"version":"4.15.0"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"libc":{"libc_id":"09a2eb42-ad34-4734-a93e-4b97395577df","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df"},"name":"glibc"},"libc_version":{"libc_version_id":"277c8630-948f-449c-9d69-5cf2ce3eb7eb","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/277c8630-948f-449c-9d69-5cf2ce3eb7eb"},"sortable_version":["2","17"],"version":"2.17","provided_features":[{"feature":"glibc","is_activestate_version":false,"is_default_provider":true,"namespace":"libc","sortable_version":["2","17"],"version":"2.17"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a"},"operating_system":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99"},"operating_system_id":"7b3a2dbb-d543-48d6-8390-7e7b63751e99","has_libc":true,"name":"CentOS"},"operating_system_version":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/2cab2f48-fb0b-415f-85f8-ddd045969662"},"operating_system_version_id":"2cab2f48-fb0b-415f-85f8-ddd045969662","sortable_version":["7","6","1810"],"version":"7.6.1810","provided_features":[{"feature":"CentOS","is_activestate_version":false,"is_default_provider":true,"namespace":"operating-system","sortable_version":["7","6","1810"],"version":"7.6.1810"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"platform_id":"0fa42e8c-ac7b-5dd7-9407-8aa15f9b993a"},"recipe_id":"585b3357-14fa-58a8-96db-4f5aa602113e","recipe_store_timestamp":"2020-04-24T17:24:26.585Z","resolved_ingredients":[{"alternatives":["dd369889-16b0-54cd-afba-d728a046a06d","3e6b87ed-9e26-533b-a52c-a4b8fdf63d9d","4b58addf-2b8d-5aaf-82a8-26e1d3254fbf","5ae75a1f-f8fa-53f1-8ae2-dd8178ed0bfa","daaebcd8-5257-5a09-b465-811933dcbf7f","ab417a2b-817a-5e63-a2e8-37a523583f2d","04036655-15dd-51d1-9960-136c9a6362fb","027dc8d1-a3f3-5a84-9fc4-8427e2f8eb26","4b1d3022-e0e4-5712-8465-f079293a106b","27959e22-7e40-5773-94cb-9cb153634ed5","15d1bc46-a098-5605-9567-9c9c4d90c139","3c7b2306-4e8e-50e1-af45-e6a792c18de2","0a1a89f8-f1cd-539b-9d93-78a397554d55","ee9c369c-7cf8-596a-96e7-34657eecb88c","a83ef247-44b4-5b5e-9aa2-387ce6883473","ffad8bea-1902-5a72-88b4-6f65a534e983","dd9f1135-5d66-535e-9879-c5e6de540ab5","5cdb089d-9a96-5f59-8090-dcf27fc087a3","471f73ed-e484-580f-b193-5a0ab37868f6","f14f6343-d75b-575d-be41-b46c2816bc04","442603f4-4df6-5d00-b48b-64c686b12431","46e20268-dd9e-5846-92c1-0249e4027609","6695f243-5c22-5b89-8998-17f5ad116d43","77031f4b-5c5e-57da-a112-fd3fcdbeaada","762f875a-880c-5de4-9dbe-923c3c7d48b7","ed851561-e424-5568-bf97-1010bf2f6ee8","252eb7bc-e95b-591c-b946-b1de81ca9ad8","b5858882-da48-5a39-b763-cef92950137d","fc2cbe4c-e940-5159-a3aa-be38eca43c7b","1c12af61-fde7-596a-8dc5-ca77866dd9a4","cd6bbe3b-41d9-56c6-85a5-4dd835f0e184","67e717fa-97b9-543c-9edf-b9a92abae7d6"],"artifact_id":"29ee664e-709c-5785-a183-c3cdd0abf65b","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2019-10-21T19:16:38.749Z","ingredient_id":"20816534-c073-5d68-9eb7-11c1d6be09f5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/20816534-c073-5d68-9eb7-11c1d6be09f5"},"name":"camel","normalized_name":"camel","primary_namespace":"builder","description":"The camel unified build system","website":"https://platform.activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-04-15T17:51:24.223Z","ingredient_id":"20816534-c073-5d68-9eb7-11c1d6be09f5","ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/20816534-c073-5d68-9eb7-11c1d6be09f5/versions/49530255-f4fa-5363-a4cc-2eb63cf5d6be","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/20816534-c073-5d68-9eb7-11c1d6be09f5"},"revision":1,"revision_timestamp":"2020-04-15T17:51:24.223Z","copyright_text":"Copyright © ActiveState Inc, 2004-2020","documentation_uri":"https://github.com/ActiveState/camel/tree/2a0758c3955df8e765c03c0f123a98435d611473/docs","is_binary_only":false,"license_expression":"UNLICENSED","release_timestamp":"2020-04-15T17:50:31.254Z","source_uri":"https://github.com/ActiveState/camel/tree/2a0758c3955df8e765c03c0f123a98435d611473","sortable_version":["20200415","135030","779230"],"version":"20200415.135030.2a0758c3","activestate_license_expression":"UNLICENSED","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://INVALID","scanner_license_expression":"UNLICENSED","source_checksum":"2a0758c3955df8e765c03c0f123a98435d611473","provided_features":[{"feature":"camel","is_activestate_version":false,"is_default_provider":true,"namespace":"builder","sortable_version":["20200415","135030","779230"],"version":"20200415.135030.2a0758c3"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"a5f0e5a0-133d-53b7-9047-683182945840","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:49:18.182Z","ingredient_id":"327b0673-5f5e-5b26-960d-a6fb18acd1c8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/327b0673-5f5e-5b26-960d-a6fb18acd1c8"},"name":"ActiveState-EULAs","normalized_name":"ActiveState-EULAs","primary_namespace":"internal","description":"ActiveState End-User License Agreements"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:49:18.182Z","ingredient_id":"327b0673-5f5e-5b26-960d-a6fb18acd1c8","ingredient_version_id":"e4d5b18c-89a9-561d-b99d-95bdd924735b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/327b0673-5f5e-5b26-960d-a6fb18acd1c8/versions/e4d5b18c-89a9-561d-b99d-95bdd924735b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/327b0673-5f5e-5b26-960d-a6fb18acd1c8"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2019-06-05T00:00:00.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/EULAs/main.tar.gz","sortable_version":["20170627","0"],"version":"20170627","activestate_license_expression":"unknown","camel_extras":{"does_not_install":"yes","dont_build":["yes"],"ppm_pkg":"no"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/internal/9d5b13269bf9b47c8778435d9c79f3cc8686ff667761c6e334e051a01a33053b/main.tar.gz","scanner_license_expression":"unknown","source_checksum":"9d5b13269bf9b47c8778435d9c79f3cc8686ff667761c6e334e051a01a33053b","provided_features":[{"feature":"ActiveState-EULAs","is_activestate_version":false,"is_default_provider":true,"namespace":"internal","sortable_version":["20170627","0"],"version":"20170627"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"ActiveState-EULAs","namespace":"internal","version_requirements":[{"comparator":"gte","version":"0"}]}]},{"alternatives":[],"artifact_id":"3b2088aa-3a85-5a54-8236-a8e285ec2fca","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:32.665Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"name":"perl","normalized_name":"perl","primary_namespace":"language","description":"Practical Extraction and Report Language"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:57:41.140Z","ingredient_id":"ed4b2154-eaee-5fba-88bb-d1eca86b1206","ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206/versions/d94f704f-ab76-5db3-a571-b9a019a1cc2a","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ed4b2154-eaee-5fba-88bb-d1eca86b1206"},"revision":12,"revision_timestamp":"2019-12-18T22:06:31.939Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/S/SH/SHAY/perl-5.28.1.tar.gz","sortable_version":["5","28","1","0"],"version":"5.28.1","activestate_license_expression":"unknown","camel_extras":{"base64_binaries":["win32/perl.ico"],"cold_storage_dirs":{"src":"__SRC__"},"git_base":"63afdf6c0f65af480aa5bb9ccba9f46dae52f6fc v5.28.1","ppm_pkg":"no"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/languages/3ebf85fe65df2ee165b22596540b7d5d42f84d4b72d84834f74e2e0b8956c347/perl-5.28.1.tar.gz","scanner_license_expression":"unknown","source_checksum":"3ebf85fe65df2ee165b22596540b7d5d42f84d4b72d84834f74e2e0b8956c347","provided_features":[{"feature":"perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language","sortable_version":["5","28","1","0"],"version":"5.28.1"},{"feature":"Amiga::ARexx","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","4","0"],"version":"0.4"},{"feature":"Amiga::Exec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.2"},{"feature":"AnyDBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"App::Cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","67","0"],"version":"1.67"},{"feature":"App::Prove","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"App::Prove::State","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"App::Prove::State::Result","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"App::Prove::State::Result::Test","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"Archive::Tar","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.30"},{"feature":"Archive::Tar::Constant","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.30"},{"feature":"Archive::Tar::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","30","0"],"version":"2.30"},{"feature":"Attribute::Handlers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"AutoLoader::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","74","0"],"version":"5.74"},{"feature":"AutoSplit::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","6","0"],"version":"1.6"},{"feature":"B::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","74","0"],"version":"1.74"},{"feature":"B::Concise","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"B::Debug","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","26","0"],"version":"1.26"},{"feature":"B::Deparse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","48","0"],"version":"1.48"},{"feature":"B::Op_private","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","28001","0"],"version":"5.28001"},{"feature":"B::Showlex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","5","0"],"version":"1.5"},{"feature":"B::Terse","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"B::Xref","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"Benchmark::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","22","0"],"version":"1.22"},{"feature":"CPAN::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.20"},{"feature":"CPAN::Author","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","2","0"],"version":"5.50.2"},{"feature":"CPAN::Bundle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","3","0"],"version":"5.50.3"},{"feature":"CPAN::CacheMgr","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","2","0"],"version":"5.50.2"},{"feature":"CPAN::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","1","0"],"version":"5.50.1"},{"feature":"CPAN::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","1","0"],"version":"5.50.1"},{"feature":"CPAN::DeferredCode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","0"],"version":"5.50"},{"feature":"CPAN::Distribution","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","19","0"],"version":"2.19"},{"feature":"CPAN::Distroprefs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","1","0"],"version":"6.1"},{"feature":"CPAN::Distrostatus","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Exception::RecursiveDependency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","1","0"],"version":"5.50.1"},{"feature":"CPAN::Exception::blocked_urllist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"CPAN::Exception::yaml_not_installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Exception::yaml_process_error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::FTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","11","0"],"version":"5.50.11"},{"feature":"CPAN::FTP::netrc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"CPAN::FirstTime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","53","11","0"],"version":"5.53.11"},{"feature":"CPAN::HTTP::Client","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","96","1","0"],"version":"1.96.1"},{"feature":"CPAN::HTTP::Credentials","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","96","1","0"],"version":"1.96.1"},{"feature":"CPAN::HandleConfig","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","8","0"],"version":"5.50.8"},{"feature":"CPAN::Index","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","12","0"],"version":"2.12"},{"feature":"CPAN::InfoObj","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Kwalify","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","50","0"],"version":"5.50"},{"feature":"CPAN::LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","96","1","0"],"version":"1.96.1"},{"feature":"CPAN::Meta","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Converter","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Feature","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::History","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Merge","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Prereqs","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Requirements","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","140","0"],"version":"2.140"},{"feature":"CPAN::Meta::Spec","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::Validator","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"CPAN::Meta::YAML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","18","0"],"version":"0.18"},{"feature":"CPAN::Mirrors","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","12","0"],"version":"2.12"},{"feature":"CPAN::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","3","0"],"version":"5.50.3"},{"feature":"CPAN::Nox","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","1","0"],"version":"5.50.1"},{"feature":"CPAN::Plugin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","96","0"],"version":"0.96"},{"feature":"CPAN::Plugin::Specfile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"},{"feature":"CPAN::Prompt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Queue","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","2","0"],"version":"5.50.2"},{"feature":"CPAN::Shell","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","7","0"],"version":"5.50.7"},{"feature":"CPAN::Tarzip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","12","0"],"version":"5.50.12"},{"feature":"CPAN::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","5","0"],"version":"5.5"},{"feature":"CPAN::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","50","3","0"],"version":"5.50.3"},{"feature":"Carp::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"Class::Struct","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","65","0"],"version":"0.65"},{"feature":"Compress::Raw::Bzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"Compress::Raw::Zlib","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","76","0"],"version":"2.76"},{"feature":"Compress::Zlib","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"Config::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0"],"version":"1"},{"feature":"Config::Extensions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.2"},{"feature":"Config::Perl::V","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","29","0"],"version":"0.29"},{"feature":"Cwd::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"DB::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"DBM_Filter::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","6","0"],"version":"0.6"},{"feature":"DBM_Filter::compress","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DBM_Filter::encode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DBM_Filter::int32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DBM_Filter::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DBM_Filter::utf8","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"DB_File::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","840","0"],"version":"1.840"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","170","0"],"version":"2.170"},{"feature":"Demo::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Descriptions::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Devel::PPPort","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","40","0"],"version":"3.40"},{"feature":"Devel::Peek","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","27","0"],"version":"1.27"},{"feature":"Devel::SelfStubber","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","6","0"],"version":"1.6"},{"feature":"Digest::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","17","1","0"],"version":"1.17.1"},{"feature":"Digest::MD5","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","55","0"],"version":"2.55"},{"feature":"Digest::SHA","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["6","1","0"],"version":"6.1"},{"feature":"Digest::base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","16","0"],"version":"1.16"},{"feature":"Digest::file","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","16","0"],"version":"1.16"},{"feature":"DirHandle::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","5","0"],"version":"1.5"},{"feature":"Dumpvalue::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","18","0"],"version":"1.18"},{"feature":"DynaLoader::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","45","0"],"version":"1.45"},{"feature":"Encode::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","97","0"],"version":"2.97"},{"feature":"Encode::Alias","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","24","0"],"version":"2.24"},{"feature":"Encode::Byte","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","4","0"],"version":"2.4"},{"feature":"Encode::CJKConstants","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","2","0"],"version":"2.2"},{"feature":"Encode::CN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Encode::CN::HZ","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.10"},{"feature":"Encode::Config","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","5","0"],"version":"2.5"},{"feature":"Encode::EBCDIC","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","2","0"],"version":"2.2"},{"feature":"Encode::Encoder","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Encode::Encoding","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","8","0"],"version":"2.8"},{"feature":"Encode::GSM0338","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"Encode::Guess","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"Encode::JP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","4","0"],"version":"2.4"},{"feature":"Encode::JP::H2Z","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","2","0"],"version":"2.2"},{"feature":"Encode::JP::JIS7","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","8","0"],"version":"2.8"},{"feature":"Encode::KR","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Encode::KR::2022_KR","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","4","0"],"version":"2.4"},{"feature":"Encode::MIME::Header","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","28","0"],"version":"2.28"},{"feature":"Encode::MIME::Header::ISO_2022_JP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","9","0"],"version":"1.9"},{"feature":"Encode::MIME::Name","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Encode::Symbol","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","2","0"],"version":"2.2"},{"feature":"Encode::TW","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Encode::Unicode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","17","0"],"version":"2.17"},{"feature":"Encode::Unicode::UTF7","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","10","0"],"version":"2.10"},{"feature":"English::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"Env::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"Errno::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0"],"version":"1"},{"feature":"Exporter::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","73","0"],"version":"5.73"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Constant","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","25","0"],"version":"0.25"},{"feature":"ExtUtils::Constant::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","6","0"],"version":"0.6"},{"feature":"ExtUtils::Constant::ProxySubs","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","9","0"],"version":"0.9"},{"feature":"ExtUtils::Constant::Utils","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","4","0"],"version":"0.4"},{"feature":"ExtUtils::Constant::XS","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"ExtUtils::Embed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","35","1","0"],"version":"1.35.1"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.70"},{"feature":"ExtUtils::Miniperl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::ParseXS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::ParseXS::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::ParseXS::CountLines","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::ParseXS::Eval","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::ParseXS::Utilities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","39","0"],"version":"3.39"},{"feature":"ExtUtils::Typemaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::InputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::OutputMap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::Typemaps::Type","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","38","0"],"version":"3.38"},{"feature":"ExtUtils::XSSymSet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","34","0"],"version":"7.34"},{"feature":"Fatal::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"Fcntl::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","13","0"],"version":"1.13"},{"feature":"File::Basename","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","85","0"],"version":"2.85"},{"feature":"File::Compare","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","6","0"],"version":"1.10.6"},{"feature":"File::Copy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","33","0"],"version":"2.33"},{"feature":"File::DosGlob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","12","0"],"version":"1.12"},{"feature":"File::Fetch","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","56","0"],"version":"0.56"},{"feature":"File::Find","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","34","0"],"version":"1.34"},{"feature":"File::Glob","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","31","0"],"version":"1.31"},{"feature":"File::GlobMapper","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"File::Path","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0"],"version":"2.15"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","74","0"],"version":"3.74"},{"feature":"File::Temp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","23","4","0"],"version":"0.23.4"},{"feature":"File::stat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"FileCache::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"FileHandle::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Filter::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","95","0"],"version":"0.95"},{"feature":"Filter::Util::Call","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","58","0"],"version":"1.58"},{"feature":"FindBin::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","51","0"],"version":"1.51"},{"feature":"GDBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","17","0"],"version":"1.17"},{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.50"},{"feature":"Getopt::Std","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","12","0"],"version":"1.12"},{"feature":"HTTP::Tiny","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","70","0"],"version":"0.70"},{"feature":"Hash::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","22","0"],"version":"0.22"},{"feature":"Hash::Util::FieldHash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.20"},{"feature":"I18N::Collate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"I18N::LangTags","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","43","0"],"version":"0.43"},{"feature":"I18N::LangTags::Detect","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"I18N::LangTags::List","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","40","0"],"version":"0.40"},{"feature":"I18N::Langinfo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.17"},{"feature":"IO::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Compress::Adapter::Bzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Adapter::Deflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Adapter::Identity","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Base::Common","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Bzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Deflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Gzip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Gzip::Constants","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::RawDeflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Zip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Zip::Constants","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Zlib::Constants","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Compress::Zlib::Extra","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Dir","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Handle","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Pipe","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Poll","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Seekable","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Select","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Socket","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Socket::INET","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Socket::IP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","39","0"],"version":"0.39"},{"feature":"IO::Socket::UNIX","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"IO::Uncompress::Adapter::Bunzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Adapter::Identity","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Adapter::Inflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::AnyInflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::AnyUncompress","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Bunzip2","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Gunzip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Inflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::RawInflate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Uncompress::Unzip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","74","0"],"version":"2.74"},{"feature":"IO::Zlib","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"IPC::Cmd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"IPC::Msg","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"IPC::Open2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"IPC::Open3","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.20"},{"feature":"IPC::Semaphore","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"IPC::SharedMem","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"IPC::SysV","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","97","1","0"],"version":"2.97.1"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","97001","0"],"version":"2.97001"},{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"Locale::Codes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Constants","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Country","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Currency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::LangExt","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::LangFam","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::LangVar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Language","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Codes::Script","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Country","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Currency","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Language","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"Locale::Maketext","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","29","0"],"version":"1.29"},{"feature":"Locale::Maketext::Guts","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.20"},{"feature":"Locale::Maketext::GutsLoader","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","20","0"],"version":"1.20"},{"feature":"Locale::Maketext::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","21","1","0"],"version":"0.21.1"},{"feature":"Locale::Script","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","56","0"],"version":"3.56"},{"feature":"MIME::Base64","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","15","0"],"version":"3.15"},{"feature":"MIME::QuotedPrint","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","13","0"],"version":"3.13"},{"feature":"Math::BigFloat","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigFloat::Trace","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"Math::BigInt","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigInt::Calc","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigInt::CalcEmu","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigInt::FastCalc","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","50","6","0"],"version":"0.50.6"},{"feature":"Math::BigInt::Lib","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","99","98","11","0"],"version":"1.99.98.11"},{"feature":"Math::BigInt::Trace","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"Math::BigRat","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","26","13","0"],"version":"0.26.13"},{"feature":"Math::Complex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","59","1","0"],"version":"1.59.1"},{"feature":"Math::Trig","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","23","0"],"version":"1.23"},{"feature":"Memoize::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","1","0"],"version":"1.3.1"},{"feature":"Memoize::AnyDBM_File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::Expire","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::ExpireFile","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::ExpireTest","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::NDBM_File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::SDBM_File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Memoize::Storable","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Module::CoreList","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","20181129","28","0"],"version":"5.20181129.28"},{"feature":"Module::CoreList::Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","20181129","28","0"],"version":"5.20181129.28"},{"feature":"Module::Load","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","32","0"],"version":"0.32"},{"feature":"Module::Load::Conditional","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","68","0"],"version":"0.68"},{"feature":"Module::Loaded","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","8","0"],"version":"0.8"},{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","33","0"],"version":"1.33"},{"feature":"MyClass::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"NDBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","14","0"],"version":"1.14"},{"feature":"NEXT::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","67","1","0"],"version":"0.67.1"},{"feature":"Net::Cmd","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Config","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Domain","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::A","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::E","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::I","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::L","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::FTP::dataconn","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::NNTP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Netrc","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::POP3","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Ping","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","62","0"],"version":"2.62"},{"feature":"Net::SMTP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::Time","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","11","0"],"version":"3.11"},{"feature":"Net::hostent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"Net::netent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"Net::protoent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"Net::servent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"O::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"ODBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","15","0"],"version":"1.15"},{"feature":"Opcode::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","43","0"],"version":"1.43"},{"feature":"POSIX::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","84","0"],"version":"1.84"},{"feature":"Params::Check","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","38","0"],"version":"0.38"},{"feature":"Parse::CPAN::Meta","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","15","0","10","0"],"version":"2.15.0.10"},{"feature":"Perl::OSType","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"PerlIO::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","10","0"],"version":"1.10"},{"feature":"PerlIO::encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","26","0"],"version":"0.26"},{"feature":"PerlIO::mmap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","16","0"],"version":"0.16"},{"feature":"PerlIO::scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","29","0"],"version":"0.29"},{"feature":"PerlIO::via","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","17","0"],"version":"0.17"},{"feature":"PerlIO::via::QuotedPrint","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","8","0"],"version":"0.8"},{"feature":"Pod::Checker","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"Pod::Escapes","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"Pod::Find","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","13","0"],"version":"1.13"},{"feature":"Pod::Html","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","24","0"],"version":"1.24"},{"feature":"Pod::InputObjects","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::ParseUtils","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Parser","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Perldoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","28","1","0"],"version":"3.28.1"},{"feature":"Pod::Perldoc::BaseTo","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::GetOptsOO","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToANSI","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToChecker","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToMan","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToNroff","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToPod","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToRtf","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTerm","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToText","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToTk","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::Perldoc::ToXml","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","28","0"],"version":"3.28"},{"feature":"Pod::PlainText","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","7","0"],"version":"2.7"},{"feature":"Pod::Select","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","63","0"],"version":"1.63"},{"feature":"Pod::Simple","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::BlackBox","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Checker","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Debug","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::DumpAsText","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::DumpAsXML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::HTML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::HTMLBatch","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::HTMLLegacy","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","1","0"],"version":"5.1"},{"feature":"Pod::Simple::LinkSection","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Methody","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Progress","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParser","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParserEndToken","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParserStartToken","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParserTextToken","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::PullParserToken","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::RTF","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Search","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::SimpleTree","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Text","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::TextContent","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::TiedOutFH","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::Transcode","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::TranscodeDumb","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::TranscodeSmart","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::XHTML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Simple::XMLOutStream","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","35","0"],"version":"3.35"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","10","0"],"version":"4.10"},{"feature":"Pod::Usage","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","69","0"],"version":"1.69"},{"feature":"SDBM_File::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","14","0"],"version":"1.14"},{"feature":"Safe::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","40","0"],"version":"2.40"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"Search::Dict","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"SelectSaver::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"SelfLoader::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Socket::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","27","0"],"version":"2.27"},{"feature":"Storable::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","8","0"],"version":"3.8"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","50","0"],"version":"1.50"},{"feature":"Symbol::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"Sys::Hostname","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","22","1","0"],"version":"1.22.1"},{"feature":"Sys::Syslog","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","35","0"],"version":"0.35"},{"feature":"TAP::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Base","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Color","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Console","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Console::ParallelSession","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Console::Session","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::File::Session","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Formatter::Session","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Harness","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Harness::Env","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Object","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Aggregator","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Grammar","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Iterator","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Iterator::Array","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Iterator::Process","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Iterator::Stream","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::IteratorFactory","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Multiplexer","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Bailout","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Comment","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Plan","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Pragma","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Test","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Unknown","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::Version","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Result::YAML","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::ResultFactory","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Scheduler","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Scheduler::Job","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Scheduler::Spinner","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::Source","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::Executable","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::Handle","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::Perl","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::SourceHandler::RawTAP","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::YAMLish::Reader","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"TAP::Parser::YAMLish::Writer","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"Term::ANSIColor","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","6","0"],"version":"4.6"},{"feature":"Term::Cap","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","17","0"],"version":"1.17"},{"feature":"Term::Complete","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","403","0"],"version":"1.403"},{"feature":"Term::ReadLine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","17","0"],"version":"1.17"},{"feature":"Test2::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","31","0"],"version":"1.31"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","114","0"],"version":"2.114"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Harness","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","42","0"],"version":"3.42"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"Text::Abbrev","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"Text::Balanced","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","3","0"],"version":"2.3"},{"feature":"Text::ParseWords","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","30","0"],"version":"3.30"},{"feature":"Text::Tabs","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2013","523","0"],"version":"2013.523"},{"feature":"Text::Wrap","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2013","523","0"],"version":"2013.523"},{"feature":"Thread::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","4","0"],"version":"3.4"},{"feature":"Thread::Queue","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["3","12","0"],"version":"3.12"},{"feature":"Thread::Semaphore","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","13","0"],"version":"2.13"},{"feature":"Tie::Array","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"Tie::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"Tie::Handle","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["4","2","0"],"version":"4.2"},{"feature":"Tie::Hash","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","5","0"],"version":"1.5"},{"feature":"Tie::Hash::NamedCapture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10","0"],"version":"0.10"},{"feature":"Tie::Memoize","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"Tie::RefHash","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","39","0"],"version":"1.39"},{"feature":"Tie::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"Tie::StdHandle","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","5","0"],"version":"4.5"},{"feature":"Tie::SubstrHash","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"Time::HiRes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","97","59","0"],"version":"1.97.59"},{"feature":"Time::Local","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Time::Piece","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","32","4","0"],"version":"1.32.4"},{"feature":"Time::Seconds","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","32","4","0"],"version":"1.32.4"},{"feature":"Time::gmtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"Time::localtime","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"Time::tm","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"UNIVERSAL::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","13","0"],"version":"1.13"},{"feature":"Unicode::Collate","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Big5","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::GB2312","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::JISX0208","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Korean","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Pinyin","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Stroke","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::CJK::Zhuyin","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Collate::Locale","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","25","0"],"version":"1.25"},{"feature":"Unicode::Normalize","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","26","0"],"version":"1.26"},{"feature":"Unicode::UCD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","70","0"],"version":"0.70"},{"feature":"User::grent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"User::pwent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"VMS::DCLsym","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","9","0"],"version":"1.9"},{"feature":"VMS::Filespec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","12","0"],"version":"1.12"},{"feature":"VMS::Stdio","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","44","0"],"version":"2.44"},{"feature":"Win32::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","52","0"],"version":"0.52"},{"feature":"Win32API::File","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","12","3","0"],"version":"0.12.3"},{"feature":"Win32CORE::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","4","0"],"version":"0.4"},{"feature":"XS::APItest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","98","0"],"version":"0.98"},{"feature":"XS::Typemap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","16","0"],"version":"0.16"},{"feature":"XSLoader::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","0"],"version":"0.30"},{"feature":"_charnames::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","45","0"],"version":"1.45"},{"feature":"arybase::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15","0"],"version":"0.15"},{"feature":"attributes::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","33","0"],"version":"0.33"},{"feature":"autodie::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::Scope::Guard","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::Scope::GuardStack","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::Util","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","29002","0"],"version":"2.29002"},{"feature":"autodie::exception::system","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autodie::hints","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","29001","0"],"version":"2.29001"},{"feature":"autodie::skip","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["2","29","0"],"version":"2.29"},{"feature":"autouse::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","11","0"],"version":"1.11"},{"feature":"base::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","27","0"],"version":"2.27"},{"feature":"bigint::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"bignum::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"bigrat::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","49","0"],"version":"0.49"},{"feature":"blib::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","7","0"],"version":"1.7"},{"feature":"bytes::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","6","0"],"version":"1.6"},{"feature":"charnames::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","45","0"],"version":"1.45"},{"feature":"constant::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","33","0"],"version":"1.33"},{"feature":"deprecate::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"diagnostics::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","36","0"],"version":"1.36"},{"feature":"encoding::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","22","0"],"version":"2.22"},{"feature":"encoding::warnings","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","13","0"],"version":"0.13"},{"feature":"experimental::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","19","0"],"version":"0.19"},{"feature":"feature::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","52","0"],"version":"1.52"},{"feature":"fields::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","24","0"],"version":"2.24"},{"feature":"filetest::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"if::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","608","0"],"version":"0.608"},{"feature":"integer::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","1","0"],"version":"1.1"},{"feature":"less::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","0"],"version":"0.3"},{"feature":"lib::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","64","0"],"version":"0.64"},{"feature":"locale::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","9","0"],"version":"1.9"},{"feature":"mro::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","22","0"],"version":"1.22"},{"feature":"ok::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","21","33","0"],"version":"1.30.21.33"},{"feature":"open::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","11","0"],"version":"1.11"},{"feature":"ops::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","2","0"],"version":"1.2"},{"feature":"overload::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","30","0"],"version":"1.30"},{"feature":"overloading::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2","0"],"version":"0.2"},{"feature":"parent::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","236","0"],"version":"0.236"},{"feature":"perlfaq::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["5","21011","0"],"version":"5.21011"},{"feature":"re::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","36","0"],"version":"0.36"},{"feature":"sigtrap::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","8","0"],"version":"1.8"},{"feature":"sort::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","4","0"],"version":"2.4"},{"feature":"strict::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","11","0"],"version":"1.11"},{"feature":"subs::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","3","0"],"version":"1.3"},{"feature":"threads::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","22","0"],"version":"2.22"},{"feature":"threads::shared","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["1","58","0"],"version":"1.58"},{"feature":"utf8::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","21","0"],"version":"1.21"},{"feature":"vars::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"version::","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","99","23","0"],"version":"0.99.23"},{"feature":"version::regex","is_activestate_version":false,"is_default_provider":false,"namespace":"language/perl","sortable_version":["0","99","23","0"],"version":"0.99.23"},{"feature":"vmsish::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"},{"feature":"warnings::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","42","0"],"version":"1.42"},{"feature":"warnings::register","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-12-18T22:06:26.788Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/cb5b6720-82e5-4546-a99a-9d39332c51af"},"patch_id":"cb5b6720-82e5-4546-a99a-9d39332c51af","conditions":null,"content":"s3://platform-sources/patches/d251ddaed91891b7b619b5d89d1bac3cb55b59bb1cda04791cc0da2cfec7c212.patch","description":"ActivePerl ~ ActivePerl 5.28 patch","sequence_number":1}],"resolved_requirements":[{"feature":"perl","namespace":"language","version_requirements":[{"comparator":"eq","version":"5.28.1"}]}]},{"alternatives":[],"artifact_id":"acb500a5-af3d-553c-bf07-4fde842cc44e","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:49:19.077Z","ingredient_id":"4c46f01f-87de-5ae2-bb45-58201d461e51","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c46f01f-87de-5ae2-bb45-58201d461e51"},"name":"ActiveState-RelocateTree","normalized_name":"ActiveState-RelocateTree","primary_namespace":"language/perl","description":"Move perl distribution to new location"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:49:19.077Z","ingredient_id":"4c46f01f-87de-5ae2-bb45-58201d461e51","ingredient_version_id":"d8b90b31-e26a-5e2f-81c7-1225e8a0a8f2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c46f01f-87de-5ae2-bb45-58201d461e51/versions/d8b90b31-e26a-5e2f-81c7-1225e8a0a8f2","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4c46f01f-87de-5ae2-bb45-58201d461e51"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2009-05-06T17:15:51.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/as-mod/ActiveState-RelocateTree/main.tar.gz","sortable_version":["1","4","0"],"version":"1.4","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ActiveState/RelocateTree"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/ab994200dced4d26e41332754e863a902a8689753622229d73bf4b9b42eef1dd/main.tar.gz","scanner_license_expression":"unknown","source_checksum":"ab994200dced4d26e41332754e863a902a8689753622229d73bf4b9b42eef1dd","provided_features":[{"feature":"ActiveState-RelocateTree","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","4","0"],"version":"1.4"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"ActiveState-RelocateTree","namespace":"language/perl","version_requirements":[{"comparator":"gte","version":"0"}]}]},{"alternatives":[],"artifact_id":"ef438bc7-bf38-5537-85f3-9ff07e715128","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"06d43cc3-8f67-575b-b34d-0ec60e9ae67e"},{"dependency_types":["build"],"ingredient_version_id":"1a882ae6-d86f-5431-a5cb-8caa0abeedf5"},{"dependency_types":["build"],"ingredient_version_id":"1cb4ca5e-4e4e-59fb-b2cb-5fdb54856ff0"},{"dependency_types":["build"],"ingredient_version_id":"3e08c8d3-fe88-5c33-82df-ded1e3d15a0b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"5b9149e8-2334-5454-a523-cd9787003344"},{"dependency_types":["build","runtime"],"ingredient_version_id":"84a01b55-1d92-53ae-a7cb-d591b7b54724"},{"dependency_types":["build"],"ingredient_version_id":"91cd893b-5b8c-5391-9c77-643fb85af0af"},{"dependency_types":["build"],"ingredient_version_id":"e4b6a074-ad51-5b69-95ce-7747c95471f8"},{"dependency_types":["runtime"],"ingredient_version_id":"f53173d3-f084-5b6f-927e-6db8c13aac9c"}],"ingredient":{"creation_timestamp":"2019-10-01T16:49:20.357Z","ingredient_id":"70829de1-9690-5b85-8d6f-1c5746a362e7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/70829de1-9690-5b85-8d6f-1c5746a362e7"},"name":"ActiveState-Test","normalized_name":"ActiveState-Test","primary_namespace":"language/perl","description":"ActiveState's Test modules"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:49:20.357Z","ingredient_id":"70829de1-9690-5b85-8d6f-1c5746a362e7","ingredient_version_id":"cf00c298-f30f-5900-8c36-6e9041654afc","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/70829de1-9690-5b85-8d6f-1c5746a362e7/versions/cf00c298-f30f-5900-8c36-6e9041654afc","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/70829de1-9690-5b85-8d6f-1c5746a362e7"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2013-04-28T14:16:37.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/as-mod/ActiveState-Test/main.tar.gz","sortable_version":["1","0","0"],"version":"1.0","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ActiveState/Test"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/565a38e09a10f3ae09afafaf29c01d60620c31c31b936d219e61c78c7aecbc57/main.tar.gz","scanner_license_expression":"unknown","source_checksum":"565a38e09a10f3ae09afafaf29c01d60620c31c31b936d219e61c78c7aecbc57","provided_features":[{"feature":"ActiveState-Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"ActiveState::Test","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","0","0"],"version":"1.0"},{"feature":"ActiveState::Test::DBI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"},{"feature":"ActiveState::Test::X11Server","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"},{"feature":"ActiveState::Test::X11Server::Impl::Managed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"ActiveState-Test","namespace":"language/perl","version_requirements":[{"comparator":"gte","version":"0"}]}]},{"alternatives":[],"artifact_id":"84a58839-2df8-5e4d-ab88-f44c991e2539","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"a873d528-56e8-5c19-b5cb-383be3bb9074"},{"dependency_types":["build"],"ingredient_version_id":"cf00c298-f30f-5900-8c36-6e9041654afc"},{"dependency_types":["runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"},{"dependency_types":["build","runtime"],"ingredient_version_id":"f53173d3-f084-5b6f-927e-6db8c13aac9c"}],"ingredient":{"creation_timestamp":"2019-10-01T16:50:32.819Z","ingredient_id":"a65130b8-7a66-5e74-aaad-ed3b2ce8f039","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a65130b8-7a66-5e74-aaad-ed3b2ce8f039"},"name":"DBD-Pg","normalized_name":"DBD-Pg","primary_namespace":"language/perl","description":"DBI PostgreSQL interface"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:50:32.819Z","ingredient_id":"a65130b8-7a66-5e74-aaad-ed3b2ce8f039","ingredient_version_id":"6e9c11f1-db6a-536e-b607-0e1aa95dceb0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a65130b8-7a66-5e74-aaad-ed3b2ce8f039/versions/6e9c11f1-db6a-536e-b607-0e1aa95dceb0","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a65130b8-7a66-5e74-aaad-ed3b2ce8f039"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-Perl OR GPL-1.0-or-later","release_timestamp":"2017-09-24T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/T/TU/TURNSTEP/DBD-Pg-3.7.0.tar.gz","sortable_version":["3","7","0","0"],"version":"3.7.0","activestate_license_expression":"unknown","camel_extras":{"dont_build":["hpux","solaris"],"mm_fullext":"DBD/Pg"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/e36e0459c9cf0f12edafb74f4cef685876d0460dbe6b411e7109070c67e56459/DBD-Pg-3.7.0.tar.gz","scanner_license_expression":"unknown","source_checksum":"e36e0459c9cf0f12edafb74f4cef685876d0460dbe6b411e7109070c67e56459","provided_features":[{"feature":"Bundle::DBD::Pg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","7","0","0"],"version":"3.7.0"},{"feature":"DBD-Pg","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","7","0","0"],"version":"3.7.0"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:50:30.233Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/5973ce13-45fb-4d96-a936-99de317bac86"},"patch_id":"5973ce13-45fb-4d96-a936-99de317bac86","conditions":null,"content":"DBD-Pg/3.7.0/0001-Add-a-very-simple-test-of-SSL-connections.patch","description":"[PATCH 1/7] Add a very simple test of SSL connections","sequence_number":1},{"creation_timestamp":"2019-10-01T16:50:30.584Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/37b9955e-9cce-444d-a218-84ea8a474254"},"patch_id":"37b9955e-9cce-444d-a218-84ea8a474254","conditions":null,"content":"DBD-Pg/3.7.0/0002-Add-an-AS-MAKEFILE.PL.patch","description":"[PATCH 2/7] Add an AS-MAKEFILE.PL\n\nThis file figures out what Pg server to connect to. It also sets the\nPOSTGRES_LIB env var to something that works for our build systems.","sequence_number":2},{"creation_timestamp":"2019-10-01T16:50:30.944Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/25720922-dcda-469d-a201-f9febb40e036"},"patch_id":"25720922-dcda-469d-a201-f9febb40e036","conditions":null,"content":"DBD-Pg/3.7.0/0003-Speed-up-test-which-runs-16k-SQL-statements.patch","description":"[PATCH 3/7] Speed up test which runs 16k SQL statements","sequence_number":3},{"creation_timestamp":"2019-10-01T16:50:31.306Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/ae975b82-2282-41b2-9551-5e87f9377604"},"patch_id":"ae975b82-2282-41b2-9551-5e87f9377604","conditions":null,"content":"DBD-Pg/3.7.0/0004-Don-t-quote-POSTGRES_LIB-on-Win32-and-skip-EXTRALIBS.patch","description":"[PATCH 4/7] Don't quote POSTGRES_LIB on Win32 and skip EXTRALIBS\n check","sequence_number":4},{"creation_timestamp":"2019-10-01T16:50:31.667Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/e5b252f2-0818-4397-bddb-20ea3707fb7b"},"patch_id":"e5b252f2-0818-4397-bddb-20ea3707fb7b","conditions":null,"content":"DBD-Pg/3.7.0/0005-Skip-alarm-using-test-on-Windows.patch","description":"[PATCH 5/7] Skip alarm-using test on Windows","sequence_number":5},{"creation_timestamp":"2019-10-01T16:50:32.023Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/0072ac8b-0163-47dd-9df7-ef9dee883b6f"},"patch_id":"0072ac8b-0163-47dd-9df7-ef9dee883b6f","conditions":null,"content":"DBD-Pg/3.7.0/0006-Skip-tests-for-lost-network-connections-that-fail-on.patch","description":"[PATCH 6/7] Skip tests for lost network connections that fail on\n Win32","sequence_number":6},{"creation_timestamp":"2019-10-01T16:50:32.384Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/cf9ab8f0-66cf-4d91-b1eb-7e993961bf92"},"patch_id":"cf9ab8f0-66cf-4d91-b1eb-7e993961bf92","conditions":null,"content":"DBD-Pg/3.7.0/0007-Rollup-patches-only-set-up-test-env-if-we-are-runnin.patch","description":"[PATCH 7/7] Rollup patches, only set up test env if we are running\n tests","sequence_number":7}],"resolved_requirements":[{"feature":"DBD-Pg","namespace":"language/perl","version_requirements":[{"comparator":"eq","version":"3.7.0"}]}]},{"alternatives":["23d7bf13-cc36-57ae-8c6a-779f7db8f7db"],"artifact_id":"4ed1a6b5-2310-5da2-9342-2b99c8ad2651","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:50:47.461Z","ingredient_id":"15f71af1-b236-5bdf-aa8a-057151757c0e","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15f71af1-b236-5bdf-aa8a-057151757c0e"},"name":"DBI","normalized_name":"DBI","primary_namespace":"language/perl","description":"Database independent interface for Perl"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:50:48.296Z","ingredient_id":"15f71af1-b236-5bdf-aa8a-057151757c0e","ingredient_version_id":"f53173d3-f084-5b6f-927e-6db8c13aac9c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15f71af1-b236-5bdf-aa8a-057151757c0e/versions/f53173d3-f084-5b6f-927e-6db8c13aac9c","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/15f71af1-b236-5bdf-aa8a-057151757c0e"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2018-10-29T00:00:00.000Z","source_uri":"https://cpan.metacpan.org/authors/id/T/TI/TIMB/DBI-1.642.tar.gz","sortable_version":["1","642","0"],"version":"1.642","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"DBI"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/3f2025023a56286cebd15cb495e36ccd9b456c3cc229bf2ce1f69e9ebfc27f5d/DBI-1.642.tar.gz","scanner_license_expression":"unknown","source_checksum":"3f2025023a56286cebd15cb495e36ccd9b456c3cc229bf2ce1f69e9ebfc27f5d","provided_features":[{"feature":"Bundle::DBI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["12","8696","0"],"version":"12.8696"},{"feature":"DBD::DBM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","8","0"],"version":"0.8"},{"feature":"DBD::File","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","44","0"],"version":"0.44"},{"feature":"DBD::Gofer::Policy::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Policy::classic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Policy::pedantic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Policy::rush","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Transport::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","14121","0"],"version":"0.14121"},{"feature":"DBD::Gofer::Transport::null","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Transport::pipeone","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10088","0"],"version":"0.10088"},{"feature":"DBD::Gofer::Transport::stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","14599","0"],"version":"0.14599"},{"feature":"DBD::Mem","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","1","0"],"version":"0.1"},{"feature":"DBD::Proxy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","2004","0"],"version":"0.2004"},{"feature":"DBI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","642","0"],"version":"1.642"},{"feature":"DBI::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","642","0"],"version":"1.642"},{"feature":"DBI::Const::GetInfo::ANSI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","8697","0"],"version":"2.8697"},{"feature":"DBI::Const::GetInfo::ODBC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","11374","0"],"version":"2.11374"},{"feature":"DBI::Const::GetInfoReturn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","8697","0"],"version":"2.8697"},{"feature":"DBI::Const::GetInfoType","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","8697","0"],"version":"2.8697"},{"feature":"DBI::DBD","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["12","15129","0"],"version":"12.15129"},{"feature":"DBI::DBD::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14214","0"],"version":"2.14214"},{"feature":"DBI::DBD::SqlEngine","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","6","0"],"version":"0.6"},{"feature":"DBI::Gofer::Execute","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","14283","0"],"version":"0.14283"},{"feature":"DBI::Gofer::Request","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","12537","0"],"version":"0.12537"},{"feature":"DBI::Gofer::Response","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","11566","0"],"version":"0.11566"},{"feature":"DBI::Gofer::Serializer::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","9950","0"],"version":"0.9950"},{"feature":"DBI::Gofer::Serializer::DataDumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","9950","0"],"version":"0.9950"},{"feature":"DBI::Gofer::Serializer::Storable","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","15586","0"],"version":"0.15586"},{"feature":"DBI::Gofer::Transport::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","12537","0"],"version":"0.12537"},{"feature":"DBI::Gofer::Transport::pipeone","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","12537","0"],"version":"0.12537"},{"feature":"DBI::Gofer::Transport::stream","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","12537","0"],"version":"0.12537"},{"feature":"DBI::Profile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","15065","0"],"version":"2.15065"},{"feature":"DBI::ProfileData","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","10008","0"],"version":"2.10008"},{"feature":"DBI::ProfileDumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","15325","0"],"version":"2.15325"},{"feature":"DBI::ProfileDumper::Apache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14121","0"],"version":"2.14121"},{"feature":"DBI::ProfileSubs","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","9396","0"],"version":"0.9396"},{"feature":"DBI::ProxyServer","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3005","0"],"version":"0.3005"},{"feature":"DBI::PurePerl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14286","0"],"version":"2.14286"},{"feature":"DBI::SQL::Nano","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","15544","0"],"version":"1.15544"},{"feature":"DBI::Util::CacheMemory","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","10315","0"],"version":"0.10315"},{"feature":"DBI::Util::_accessor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","9479","0"],"version":"0.9479"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["27d48b7f-6d4c-50df-892f-7f500745dad0","cb035aad-a1f6-59e5-baf4-fbd8666c1f75","d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"68414965-5544-5af9-8d6c-32b9cce4df2b","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:50:51.494Z","ingredient_id":"6d0d1e25-b677-544c-9aab-fc8bf0eab142","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6d0d1e25-b677-544c-9aab-fc8bf0eab142"},"name":"Data-Dumper","normalized_name":"Data-Dumper","primary_namespace":"language/perl","description":"unknown"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:49.330Z","ingredient_id":"6d0d1e25-b677-544c-9aab-fc8bf0eab142","ingredient_version_id":"34a46b65-4429-5882-ba28-f7d09bb8a1d6","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6d0d1e25-b677-544c-9aab-fc8bf0eab142/versions/34a46b65-4429-5882-ba28-f7d09bb8a1d6","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6d0d1e25-b677-544c-9aab-fc8bf0eab142"},"revision":2,"revision_timestamp":"2019-12-06T22:01:07.334Z","copyright_text":"unknown","documentation_uri":"https://metacpan.org/pod/Data::Dumper","is_binary_only":false,"license_expression":"UNKNOWN","release_timestamp":"2018-11-10T10:10:30.000Z","source_uri":"https://cpan.metacpan.org/authors/id/X/XS/XSAWYERX/Data-Dumper-2.173.tar.gz","sortable_version":["2","173","0"],"version":"2.173","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/697608b39330988e519131be667ff47168aaaaf99f06bd2095d5b46ad05d76fa/Data-Dumper-2.173.tar.gz","scanner_license_expression":"unknown","source_checksum":"697608b39330988e519131be667ff47168aaaaf99f06bd2095d5b46ad05d76fa","provided_features":[{"feature":"Data-Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","173","0"],"version":"2.173"},{"feature":"Data::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","173","0"],"version":"2.173"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"44bca841-a181-5b72-bdd4-ab5d37ccb309","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:28.430Z","ingredient_id":"4a73e3d3-370c-55c1-9fec-f5d48fc4be9b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4a73e3d3-370c-55c1-9fec-f5d48fc4be9b"},"name":"ExtUtils-CBuilder","normalized_name":"ExtUtils-CBuilder","primary_namespace":"language/perl","description":"Compile and link C code for Perl modules"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:28.430Z","ingredient_id":"4a73e3d3-370c-55c1-9fec-f5d48fc4be9b","ingredient_version_id":"28f42dcf-0e80-5058-92a5-729ca91955a8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4a73e3d3-370c-55c1-9fec-f5d48fc4be9b/versions/28f42dcf-0e80-5058-92a5-729ca91955a8","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/4a73e3d3-370c-55c1-9fec-f5d48fc4be9b"},"revision":4,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-11-22T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/A/AM/AMBS/ExtUtils-CBuilder-0.280230.tar.gz","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ExtUtils/CBuilder"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/1daae1d7709709a26139984b3c4c36e9ff22912cde6a393ea30ef40058dc9cd5/ExtUtils-CBuilder-0.280230.tar.gz","scanner_license_expression":"unknown","source_checksum":"1daae1d7709709a26139984b3c4c36e9ff22912cde6a393ea30ef40058dc9cd5","provided_features":[{"feature":"ExtUtils::CBuilder::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::dec_osf","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::GCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::MSVC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::android","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder::Platform::Windows::BCC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils::CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"},{"feature":"ExtUtils-CBuilder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","28","2","30","0"],"version":"0.28.2.30"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:51:27.984Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/059a0a2b-9ff8-4354-a993-e04088ffd3de"},"patch_id":"059a0a2b-9ff8-4354-a993-e04088ffd3de","conditions":null,"content":"ExtUtils-CBuilder-base-file.patch","description":"No description","sequence_number":1}],"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"20af464f-bda3-5072-b330-f4392b5e9850","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:32.487Z","ingredient_id":"59937b56-db73-5e9e-8d96-5966ed4593a8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/59937b56-db73-5e9e-8d96-5966ed4593a8"},"name":"ExtUtils-Install","normalized_name":"ExtUtils-Install","primary_namespace":"language/perl","description":"install files from here to there"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:32.487Z","ingredient_id":"59937b56-db73-5e9e-8d96-5966ed4593a8","ingredient_version_id":"9d19c878-dde6-5bc7-a0a1-aee1a15cf1a2","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/59937b56-db73-5e9e-8d96-5966ed4593a8/versions/9d19c878-dde6-5bc7-a0a1-aee1a15cf1a2","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/59937b56-db73-5e9e-8d96-5966ed4593a8"},"revision":4,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-05-28T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/B/BI/BINGOS/ExtUtils-Install-2.14.tar.gz","sortable_version":["2","14","0"],"version":"2.14","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ExtUtils/Install"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/35412305cbae979aac3b6e2c70cb301ae461979a1d848a8a043f74518eb96aea/ExtUtils-Install-2.14.tar.gz","scanner_license_expression":"unknown","source_checksum":"35412305cbae979aac3b6e2c70cb301ae461979a1d848a8a043f74518eb96aea","provided_features":[{"feature":"ExtUtils::Packlist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::Installed","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils::Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"},{"feature":"ExtUtils-Install","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","14","0"],"version":"2.14"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:51:32.126Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/df7d561f-feaa-4bc7-bde6-2efafc070da8"},"patch_id":"df7d561f-feaa-4bc7-bde6-2efafc070da8","conditions":null,"content":"ExtUtils-Install-2.14-hpux-inuse-rename.patch","description":"Bug 85799, on HP-UX, first try to rename an in-use file\n instead of immediately giving up.","sequence_number":1}],"resolved_requirements":[]},{"alternatives":["5ae0af7e-aef3-5815-977e-ea78d2dfdd95","fd3ebb99-efb0-5fc4-8329-f36866b44290","b3f16eff-d588-5bbe-a33e-b34e1dbdf72e","d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"d2df2faa-b698-5599-b752-825d3e59cb63","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:37.136Z","ingredient_id":"8291f28e-f684-560c-8875-5c834a4740fd","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8291f28e-f684-560c-8875-5c834a4740fd"},"name":"ExtUtils-MakeMaker","normalized_name":"ExtUtils-MakeMaker","primary_namespace":"language/perl","description":"Create a module Makefile"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-10T18:45:23.625Z","ingredient_id":"8291f28e-f684-560c-8875-5c834a4740fd","ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8291f28e-f684-560c-8875-5c834a4740fd/versions/0067cb0b-fe9b-5c73-b853-bdd90d6e240b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8291f28e-f684-560c-8875-5c834a4740fd"},"revision":1,"revision_timestamp":"2019-12-10T18:45:23.625Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/ExtUtils::MakeMaker","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-09-11T09:16:48.000Z","source_uri":"https://cpan.metacpan.org/authors/id/B/BI/BINGOS/ExtUtils-MakeMaker-7.38.tar.gz","sortable_version":["7","380","0"],"version":"7.38","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/897d64af242331ebb69090f68a2b610091e1996952d02096ce7942072a35e02c/ExtUtils-MakeMaker-7.38.tar.gz","scanner_license_expression":"unknown","source_checksum":"897d64af242331ebb69090f68a2b610091e1996952d02096ce7942072a35e02c","provided_features":[{"feature":"ExtUtils-MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Command","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Command::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Liblist","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Liblist::Kid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_AIX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Any","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_BeOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_DOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_NW5","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_UWIN","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MM_Win95","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::Locale","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::_version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::charstar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::version::regex","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::MakeMaker::version::vpp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Mkbootstrap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::Mksymlists","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"ExtUtils::testlib","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"MM","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"},{"feature":"MY","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["7","380","0"],"version":"7.38"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-12-10T15:57:44.636Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/aae9cf84-3381-45be-b044-a557232eca66"},"patch_id":"aae9cf84-3381-45be-b044-a557232eca66","conditions":null,"content":"s3://platform-sources/patches/c533f762465d39aee2a092a89e61a8d69ef51cc7d365f2d0d7a3231e09cd08f0.patch","description":"ExtUtils-MakeMaker ~ ExtUtils-MakeMaker-7.38-01-ldopts\nCarried forward from 7.30\nMake 'perl -MExtUtils::Embed -e ldopts' output a direct reference to libperl.a if using -lperl would pick up libperl.so.\nhttp://bugs.activestate.com/show_bug.cgi?id=39069\np4-change: 152627","sequence_number":1},{"creation_timestamp":"2019-12-10T15:58:48.730Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/7770ef1d-96a1-4f9b-a89c-7e1e51755a36"},"patch_id":"7770ef1d-96a1-4f9b-a89c-7e1e51755a36","conditions":null,"content":"s3://platform-sources/patches/d8467840f146ddd3e53228e2af5f83ac44af7a6f40912b5c096c6999d422e20c.patch","description":"ExtUtils-MakeMaker ~ ExtUtils-MakeMaker-7.38-02-html-pods\nCarried forward from 7.30\nSupport for HTML PODs","sequence_number":2},{"creation_timestamp":"2019-12-10T16:00:02.140Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/e1a5d58f-4c19-4177-a436-501a92b64b35"},"patch_id":"e1a5d58f-4c19-4177-a436-501a92b64b35","conditions":null,"content":"s3://platform-sources/patches/4e327d9c66c8ca64f42e754b46c96f9fbc01539f231d2afab5049711dda62051.patch","description":"ExtUtils-MakeMaker ~ ExtUtils-MakeMaker-7.38-03-htmldir\nCarried forward from 7.30\nMake sure MakeMaker sets up INSTALL.*HTMLDIR when using INSTALL_BASE\nWithout this change the html docs will be written to root level directories /bin, /lib, and /site (if they are writable; otherwise install will fail).\nThe INSTALL_BASE feature is used by local::lib (and cpanminus).","sequence_number":3},{"creation_timestamp":"2019-12-10T16:01:16.305Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/a4ae5e21-ee99-4e23-96eb-90ca47dfcdea"},"patch_id":"a4ae5e21-ee99-4e23-96eb-90ca47dfcdea","conditions":null,"content":"s3://platform-sources/patches/cde1c1d24b5308c81c1febb868c5b26565b032501b9536db83e8fb315d106195.patch","description":"ExtUtils-MakeMaker ~ ExtUtils-MakeMaker-7.38-skip-xs-on-AIX\nCarried forward from 7.30\nSkip EUMM XS tests on AIX.\nhttps://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker/pull/278","sequence_number":4}],"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"6be9481f-1484-5b4e-9407-05ef48c83c40","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:38.304Z","ingredient_id":"de5c5b9c-b323-501e-96bc-c4bdf75fe8b5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/de5c5b9c-b323-501e-96bc-c4bdf75fe8b5"},"name":"ExtUtils-Manifest","normalized_name":"ExtUtils-Manifest","primary_namespace":"language/perl","description":"utilities to write and check a MANIFEST file"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:38.304Z","ingredient_id":"de5c5b9c-b323-501e-96bc-c4bdf75fe8b5","ingredient_version_id":"c509e237-a516-5cf0-aaec-216a4daaeed4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/de5c5b9c-b323-501e-96bc-c4bdf75fe8b5/versions/c509e237-a516-5cf0-aaec-216a4daaeed4","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/de5c5b9c-b323-501e-96bc-c4bdf75fe8b5"},"revision":6,"revision_timestamp":"2019-11-05T00:50:49.251Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2014-12-31T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/E/ET/ETHER/ExtUtils-Manifest-1.70.tar.gz","sortable_version":["1","70","0"],"version":"1.70","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"ExtUtils/Manifest","required":"1"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/eeff062050b223964cd8f624a90ae75df443612239df34a20ff87644f9f52b95/ExtUtils-Manifest-1.70.tar.gz","scanner_license_expression":"unknown","source_checksum":"eeff062050b223964cd8f624a90ae75df443612239df34a20ff87644f9f52b95","provided_features":[{"feature":"ExtUtils-Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.70"},{"feature":"ExtUtils::Manifest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","70","0"],"version":"1.70"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"d78ed36e-672c-59e3-81c9-5761074f6c97","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:55.496Z","ingredient_id":"b58e146b-377e-54f5-9424-705f681840f3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/b58e146b-377e-54f5-9424-705f681840f3"},"name":"Getopt-Long","normalized_name":"Getopt-Long","primary_namespace":"language/perl","description":"Module to handle parsing command line options"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:55.496Z","ingredient_id":"b58e146b-377e-54f5-9424-705f681840f3","ingredient_version_id":"f21bbf0a-4665-5fb9-88b8-3eb9a22a7da7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/b58e146b-377e-54f5-9424-705f681840f3/versions/f21bbf0a-4665-5fb9-88b8-3eb9a22a7da7","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/b58e146b-377e-54f5-9424-705f681840f3"},"revision":4,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0 OR GPL-2.0-or-later","release_timestamp":"2017-05-27T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/J/JV/JV/Getopt-Long-2.50.tar.gz","sortable_version":["2","50","0"],"version":"2.50","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Getopt/Long"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/20881adb2b73e83825f9a0a3b141db11b3a555e1d3775b13d81d0481623e4b67/Getopt-Long-2.50.tar.gz","scanner_license_expression":"unknown","source_checksum":"20881adb2b73e83825f9a0a3b141db11b3a555e1d3775b13d81d0481623e4b67","provided_features":[{"feature":"Getopt::Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.50"},{"feature":"Getopt-Long","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","50","0"],"version":"2.50"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"e8b01fb8-3e62-5ac4-8e4b-422945b8cc9d","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"3b05243a-b6da-57ec-8c57-8de5221b8937"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"4b150af7-4abd-5bad-849c-94cde6b59fed"},{"dependency_types":["runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:57.424Z","ingredient_id":"7075b232-08c5-5ad7-bf90-943d1b32dcf0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7075b232-08c5-5ad7-bf90-943d1b32dcf0"},"name":"HTML-Parser","normalized_name":"HTML-Parser","primary_namespace":"language/perl","description":"HTML parser class"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:57.424Z","ingredient_id":"7075b232-08c5-5ad7-bf90-943d1b32dcf0","ingredient_version_id":"1cb4ca5e-4e4e-59fb-b2cb-5fdb54856ff0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7075b232-08c5-5ad7-bf90-943d1b32dcf0/versions/1cb4ca5e-4e4e-59fb-b2cb-5fdb54856ff0","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7075b232-08c5-5ad7-bf90-943d1b32dcf0"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2016-01-19T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/G/GA/GAAS/HTML-Parser-3.72.tar.gz","sortable_version":["3","72","0"],"version":"3.72","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTML/Parser"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/ec28c7e1d9e67c45eca197077f7cdc41ead1bb4c538c7f02a3296a4bb92f608b/HTML-Parser-3.72.tar.gz","scanner_license_expression":"unknown","source_checksum":"ec28c7e1d9e67c45eca197077f7cdc41ead1bb4c538c7f02a3296a4bb92f608b","provided_features":[{"feature":"HTML-Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","72","0"],"version":"3.72"},{"feature":"HTML::Entities","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","69","0"],"version":"3.69"},{"feature":"HTML::Filter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","72","0"],"version":"3.72"},{"feature":"HTML::HeadParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","71","0"],"version":"3.71"},{"feature":"HTML::LinkExtor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","69","0"],"version":"3.69"},{"feature":"HTML::Parser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","72","0"],"version":"3.72"},{"feature":"HTML::PullParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","57","0"],"version":"3.57"},{"feature":"HTML::TokeParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","69","0"],"version":"3.69"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"9a4b00f2-45fd-5480-b790-302bec5db07d","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:51:58.616Z","ingredient_id":"642ba5a2-5d51-5c4e-87fa-3685665bd030","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/642ba5a2-5d51-5c4e-87fa-3685665bd030"},"name":"HTML-Tagset","normalized_name":"HTML-Tagset","primary_namespace":"language/perl","description":"data tables useful in parsing HTML"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:51:58.616Z","ingredient_id":"642ba5a2-5d51-5c4e-87fa-3685665bd030","ingredient_version_id":"4b150af7-4abd-5bad-849c-94cde6b59fed","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/642ba5a2-5d51-5c4e-87fa-3685665bd030/versions/4b150af7-4abd-5bad-849c-94cde6b59fed","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/642ba5a2-5d51-5c4e-87fa-3685665bd030"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2008-03-01T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/P/PE/PETDANCE/HTML-Tagset-3.20.tar.gz","sortable_version":["3","20","0"],"version":"3.20","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTML/Tagset"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/adb17dac9e36cd011f5243881c9739417fd102fce760f8de4e9be4c7131108e2/HTML-Tagset-3.20.tar.gz","scanner_license_expression":"unknown","source_checksum":"adb17dac9e36cd011f5243881c9739417fd102fce760f8de4e9be4c7131108e2","provided_features":[{"feature":"HTML-Tagset","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","20","0"],"version":"3.20"},{"feature":"HTML::Tagset","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","20","0"],"version":"3.20"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"701c6b1f-2b6c-56c9-ae5d-f3ae17cd3d1e","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:02.127Z","ingredient_id":"9ed3546f-abf3-546f-a532-d4badd1937f7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9ed3546f-abf3-546f-a532-d4badd1937f7"},"name":"HTTP-Date","normalized_name":"HTTP-Date","primary_namespace":"language/perl","description":"date conversion routines"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:02.127Z","ingredient_id":"9ed3546f-abf3-546f-a532-d4badd1937f7","ingredient_version_id":"91cd893b-5b8c-5391-9c77-643fb85af0af","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9ed3546f-abf3-546f-a532-d4badd1937f7/versions/91cd893b-5b8c-5391-9c77-643fb85af0af","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9ed3546f-abf3-546f-a532-d4badd1937f7"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-Perl OR GPL-1.0-or-later","release_timestamp":"2012-03-30T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/G/GA/GAAS/HTTP-Date-6.02.tar.gz","sortable_version":["6","2","0"],"version":"6.2","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTTP/Date"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/e8b9941da0f9f0c9c01068401a5e81341f0e3707d1c754f8e11f42a7e629e333/HTTP-Date-6.02.tar.gz","scanner_license_expression":"unknown","source_checksum":"e8b9941da0f9f0c9c01068401a5e81341f0e3707d1c754f8e11f42a7e629e333","provided_features":[{"feature":"HTTP-Date","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","2","0"],"version":"6.2"},{"feature":"HTTP::Date","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","2","0"],"version":"6.2"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c24ffb45-a21d-561f-ad66-d56556b2bdb4","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"50f0603e-048d-5f9a-ac44-9d32df97809d"},{"dependency_types":["build"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:02.612Z","ingredient_id":"80076996-fc73-50c2-850e-a606a139b302","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/80076996-fc73-50c2-850e-a606a139b302"},"name":"HTTP-Message","normalized_name":"HTTP-Message","primary_namespace":"language/perl","description":"HTTP style message (base class)"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:02.612Z","ingredient_id":"80076996-fc73-50c2-850e-a606a139b302","ingredient_version_id":"3e08c8d3-fe88-5c33-82df-ded1e3d15a0b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/80076996-fc73-50c2-850e-a606a139b302/versions/3e08c8d3-fe88-5c33-82df-ded1e3d15a0b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/80076996-fc73-50c2-850e-a606a139b302"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-12-20T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/O/OA/OALDERS/HTTP-Message-6.14.tar.gz","sortable_version":["6","14","0"],"version":"6.14","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTTP/Message"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/71aab9f10eb4b8ec6e8e3a85fc5acb46ba04db1c93eb99613b184078c5cf2ac9/HTTP-Message-6.14.tar.gz","scanner_license_expression":"unknown","source_checksum":"71aab9f10eb4b8ec6e8e3a85fc5acb46ba04db1c93eb99613b184078c5cf2ac9","provided_features":[{"feature":"HTTP-Message","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Headers","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Headers::Auth","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Headers::ETag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Headers::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Message","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Request","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Request::Common","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Response","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"},{"feature":"HTTP::Status","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","14","0"],"version":"6.14"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"7d72ca66-ae36-5e6f-a491-d649bbdb8b8f","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["runtime"],"ingredient_version_id":"3e08c8d3-fe88-5c33-82df-ded1e3d15a0b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:03.039Z","ingredient_id":"2950e101-1150-5ab1-affe-ab6ac3d4b6e7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2950e101-1150-5ab1-affe-ab6ac3d4b6e7"},"name":"HTTP-Negotiate","normalized_name":"HTTP-Negotiate","primary_namespace":"language/perl","description":"choose a variant to serve"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:03.039Z","ingredient_id":"2950e101-1150-5ab1-affe-ab6ac3d4b6e7","ingredient_version_id":"e4b6a074-ad51-5b69-95ce-7747c95471f8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2950e101-1150-5ab1-affe-ab6ac3d4b6e7/versions/e4b6a074-ad51-5b69-95ce-7747c95471f8","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2950e101-1150-5ab1-affe-ab6ac3d4b6e7"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-Perl OR GPL-1.0-or-later","release_timestamp":"2012-02-18T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/G/GA/GAAS/HTTP-Negotiate-6.01.tar.gz","sortable_version":["6","1","0"],"version":"6.1","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"HTTP/Negotiate"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/1c729c1ea63100e878405cda7d66f9adfd3ed4f1d6cacaca0ee9152df728e016/HTTP-Negotiate-6.01.tar.gz","scanner_license_expression":"unknown","source_checksum":"1c729c1ea63100e878405cda7d66f9adfd3ed4f1d6cacaca0ee9152df728e016","provided_features":[{"feature":"HTTP-Negotiate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","1","0"],"version":"6.1"},{"feature":"HTTP::Negotiate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","1","0"],"version":"6.1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["96636fc0-a33a-5825-8f5d-5122b3812a0f"],"artifact_id":"8d011eb1-3d8e-5074-a8b2-d41586e53059","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["runtime"],"ingredient_version_id":"3b05243a-b6da-57ec-8c57-8de5221b8937"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"bebc32d9-b8e0-59dd-97b2-098496e9fd61"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:22.652Z","ingredient_id":"21072e99-9e15-5b56-a8fc-e83864695be8","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/21072e99-9e15-5b56-a8fc-e83864695be8"},"name":"JSON-PP","normalized_name":"JSON-PP","primary_namespace":"language/perl","description":"JSON::XS compatible pure-Perl module."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-11-13T15:08:42.291Z","ingredient_id":"21072e99-9e15-5b56-a8fc-e83864695be8","ingredient_version_id":"50f0603e-048d-5f9a-ac44-9d32df97809d","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/21072e99-9e15-5b56-a8fc-e83864695be8/versions/50f0603e-048d-5f9a-ac44-9d32df97809d","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/21072e99-9e15-5b56-a8fc-e83864695be8"},"revision":1,"revision_timestamp":"2019-11-13T15:08:42.291Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/JSON::PP","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-06-29T09:52:40.000Z","source_uri":"https://cpan.metacpan.org/authors/id/I/IS/ISHIGAKI/JSON-PP-4.04.tar.gz","sortable_version":["4","40","0"],"version":"4.04","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/81311c56d7b94bbf8003cf421e87961efba576189198e516fd5426889650b66a/JSON-PP-4.04.tar.gz","scanner_license_expression":"unknown","source_checksum":"81311c56d7b94bbf8003cf421e87961efba576189198e516fd5426889650b66a","provided_features":[{"feature":"JSON-PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","40","0"],"version":"4.04"},{"feature":"JSON::PP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","40","0"],"version":"4.04"},{"feature":"JSON::PP::Boolean","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","40","0"],"version":"4.04"},{"feature":"JSON::PP::IncrParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","40","0"],"version":"4.04"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["a921e82c-9204-5b32-b7fb-3491c52b4e6b"],"artifact_id":"79b640e2-85c5-5e36-b466-cec860002061","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build","runtime"],"ingredient_version_id":"142400e9-5965-5a41-813a-427106fbf770"},{"dependency_types":["runtime"],"ingredient_version_id":"28f42dcf-0e80-5058-92a5-729ca91955a8"},{"dependency_types":["runtime"],"ingredient_version_id":"34a46b65-4429-5882-ba28-f7d09bb8a1d6"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["runtime"],"ingredient_version_id":"9d19c878-dde6-5bc7-a0a1-aee1a15cf1a2"},{"dependency_types":["build","runtime"],"ingredient_version_id":"ad8f2146-84db-5542-b4b7-c188f18784d7"},{"dependency_types":["runtime"],"ingredient_version_id":"b131cae2-42e2-564e-a217-1266ea60ff62"},{"dependency_types":["runtime"],"ingredient_version_id":"c509e237-a516-5cf0-aaec-216a4daaeed4"},{"dependency_types":["build","runtime"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"},{"dependency_types":["runtime"],"ingredient_version_id":"f21bbf0a-4665-5fb9-88b8-3eb9a22a7da7"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:48.137Z","ingredient_id":"c709227b-f464-5cb3-b53f-de99f4244cb1","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c709227b-f464-5cb3-b53f-de99f4244cb1"},"name":"Module-Build","normalized_name":"Module-Build","primary_namespace":"language/perl","description":"Build and install Perl modules"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-12T22:59:25.654Z","ingredient_id":"c709227b-f464-5cb3-b53f-de99f4244cb1","ingredient_version_id":"5b9149e8-2334-5454-a523-cd9787003344","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c709227b-f464-5cb3-b53f-de99f4244cb1/versions/5b9149e8-2334-5454-a523-cd9787003344","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c709227b-f464-5cb3-b53f-de99f4244cb1"},"revision":3,"revision_timestamp":"2020-04-22T15:09:12.488Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Module::Build","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-04-15T22:52:38.000Z","source_uri":"https://cpan.metacpan.org/authors/id/L/LE/LEONT/Module-Build-0.4229.tar.gz","sortable_version":["0","422","900"],"version":"0.4229","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/1fe491a6cda914b01bc8e592faa2b5404e9f35915ca15322f8f2a8d8f9008c18/Module-Build-0.4229.tar.gz","scanner_license_expression":"unknown","source_checksum":"1fe491a6cda914b01bc8e592faa2b5404e9f35915ca15322f8f2a8d8f9008c18","provided_features":[{"feature":"Module::Build::PodParser","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::os2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::darwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::aix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::Windows","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::VOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::MacOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Platform::Default","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::PPMMaker","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Notes","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Dumper","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Cookbook","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Config","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Compat","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module::Build","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"},{"feature":"Module-Build","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","422","900"],"version":"0.4229"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"56135216-8f1d-5289-a8db-fae6e287dcbd","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"d94f704f-ab76-5db3-a571-b9a019a1cc2a"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:51.673Z","ingredient_id":"441965ba-8592-5986-b10d-7e1d959ddfd9","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/441965ba-8592-5986-b10d-7e1d959ddfd9"},"name":"Module-Metadata","normalized_name":"Module-Metadata","primary_namespace":"language/perl","description":"Gather package and POD information from perl module files"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:51.673Z","ingredient_id":"441965ba-8592-5986-b10d-7e1d959ddfd9","ingredient_version_id":"ad8f2146-84db-5542-b4b7-c188f18784d7","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/441965ba-8592-5986-b10d-7e1d959ddfd9/versions/ad8f2146-84db-5542-b4b7-c188f18784d7","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/441965ba-8592-5986-b10d-7e1d959ddfd9"},"revision":4,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2016-07-24T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/E/ET/ETHER/Module-Metadata-1.000033.tar.gz","sortable_version":["1","33","0"],"version":"1.33","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Module/Metadata"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/bc96cc7949b52e2dac1595e806102640760917cfcd7497c7a023192156f3ff8e/Module-Metadata-1.000033.tar.gz","scanner_license_expression":"unknown","source_checksum":"bc96cc7949b52e2dac1595e806102640760917cfcd7497c7a023192156f3ff8e","provided_features":[{"feature":"Module::Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","33","0"],"version":"1.33"},{"feature":"Module-Metadata","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","33","0"],"version":"1.33"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"c561e3f0-2aba-5277-8315-279a9f06a8ca","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:52:59.671Z","ingredient_id":"d6b106ec-77df-51da-9864-5a040bf0711a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d6b106ec-77df-51da-9864-5a040bf0711a"},"name":"Net-HTTP","normalized_name":"Net-HTTP","primary_namespace":"language/perl","description":"Low-level HTTP connection (client)"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:52:59.671Z","ingredient_id":"d6b106ec-77df-51da-9864-5a040bf0711a","ingredient_version_id":"06d43cc3-8f67-575b-b34d-0ec60e9ae67e","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d6b106ec-77df-51da-9864-5a040bf0711a/versions/06d43cc3-8f67-575b-b34d-0ec60e9ae67e","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d6b106ec-77df-51da-9864-5a040bf0711a"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-09-01T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/O/OA/OALDERS/Net-HTTP-6.17.tar.gz","sortable_version":["6","17","0"],"version":"6.17","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Net/HTTP"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/1e8624b1618dc6f7f605f5545643ebb9b833930f4d7485d4124aa2f2f26d1611/Net-HTTP-6.17.tar.gz","scanner_license_expression":"unknown","source_checksum":"1e8624b1618dc6f7f605f5545643ebb9b833930f4d7485d4124aa2f2f26d1611","provided_features":[{"feature":"Net-HTTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"},{"feature":"Net::HTTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"},{"feature":"Net::HTTP::Methods","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"},{"feature":"Net::HTTP::NB","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"},{"feature":"Net::HTTPS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","17","0"],"version":"6.17"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["21a740ba-c54d-5a78-bc42-0fdb7dced2ba","d94f704f-ab76-5db3-a571-b9a019a1cc2a"],"artifact_id":"aea53a58-9da4-5c4a-9259-fc533a28cbc6","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:53:18.167Z","ingredient_id":"13dc7a1e-eef1-5153-b1ce-e7632febd346","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/13dc7a1e-eef1-5153-b1ce-e7632febd346"},"name":"PathTools","normalized_name":"PathTools","primary_namespace":"language/perl","description":"unknown"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:43.162Z","ingredient_id":"13dc7a1e-eef1-5153-b1ce-e7632febd346","ingredient_version_id":"142400e9-5965-5a41-813a-427106fbf770","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/13dc7a1e-eef1-5153-b1ce-e7632febd346/versions/142400e9-5965-5a41-813a-427106fbf770","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/13dc7a1e-eef1-5153-b1ce-e7632febd346"},"revision":2,"revision_timestamp":"2019-12-06T21:46:46.530Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Cwd","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2018-08-29T19:53:19.000Z","source_uri":"https://cpan.metacpan.org/authors/id/X/XS/XSAWYERX/PathTools-3.75.tar.gz","sortable_version":["3","750","0"],"version":"3.75","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/a558503aa6b1f8c727c0073339081a77888606aa701ada1ad62dd9d8c3f945a2/PathTools-3.75.tar.gz","scanner_license_expression":"unknown","source_checksum":"a558503aa6b1f8c727c0073339081a77888606aa701ada1ad62dd9d8c3f945a2","provided_features":[{"feature":"Cwd","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::AmigaOS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Cygwin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Epoc","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Functions","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::VMS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"File::Spec::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"},{"feature":"PathTools","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","750","0"],"version":"3.75"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a","c287183e-48c8-5bfe-9b9d-0ead376370fe"],"artifact_id":"18f5dfd6-e09c-5bff-9dd8-a182a757b52b","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"9d19c878-dde6-5bc7-a0a1-aee1a15cf1a2"}],"ingredient":{"creation_timestamp":"2019-10-01T16:53:42.402Z","ingredient_id":"9c61e880-bed6-59de-807a-4ace3191d81b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9c61e880-bed6-59de-807a-4ace3191d81b"},"name":"Scalar-List-Utils","normalized_name":"Scalar-List-Utils","primary_namespace":"language/perl","description":"Common Scalar and List utility subroutines"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:56.566Z","ingredient_id":"9c61e880-bed6-59de-807a-4ace3191d81b","ingredient_version_id":"bebc32d9-b8e0-59dd-97b2-098496e9fd61","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9c61e880-bed6-59de-807a-4ace3191d81b/versions/bebc32d9-b8e0-59dd-97b2-098496e9fd61","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9c61e880-bed6-59de-807a-4ace3191d81b"},"revision":2,"revision_timestamp":"2019-12-06T22:22:08.218Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Sub::Util","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-10-24T09:43:15.000Z","source_uri":"https://cpan.metacpan.org/authors/id/P/PE/PEVANS/Scalar-List-Utils-1.53.tar.gz","sortable_version":["1","530","0"],"version":"1.53","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/bd4086b066fb3b18a0be2e7d9bc100a99aa0f233ad659492340415c7b2bdae99/Scalar-List-Utils-1.53.tar.gz","scanner_license_expression":"unknown","source_checksum":"bd4086b066fb3b18a0be2e7d9bc100a99aa0f233ad659492340415c7b2bdae99","provided_features":[{"feature":"List::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"},{"feature":"List::Util::XS","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"},{"feature":"Scalar-List-Utils","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"},{"feature":"Scalar::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"},{"feature":"Sub::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","530","0"],"version":"1.53"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a","bbfeffca-adbf-53df-9e84-dcbc83f804bd","19f1be8e-2dc4-58be-a370-00627a6ce003"],"artifact_id":"86d6c830-22f3-5c53-b9cb-74dcfc8a0d03","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:16.878Z","ingredient_id":"2df1c8f2-0db1-506c-b339-d36a23aa303a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2df1c8f2-0db1-506c-b339-d36a23aa303a"},"name":"Test-Simple","normalized_name":"Test-Simple","primary_namespace":"language/perl","description":"Basic utilities for writing tests."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:33.143Z","ingredient_id":"2df1c8f2-0db1-506c-b339-d36a23aa303a","ingredient_version_id":"3b05243a-b6da-57ec-8c57-8de5221b8937","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2df1c8f2-0db1-506c-b339-d36a23aa303a/versions/3b05243a-b6da-57ec-8c57-8de5221b8937","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/2df1c8f2-0db1-506c-b339-d36a23aa303a"},"revision":2,"revision_timestamp":"2019-12-06T21:38:18.262Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Test::Simple","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-12-02T21:27:53.000Z","source_uri":"https://cpan.metacpan.org/authors/id/E/EX/EXODIST/Test-Simple-1.302170.tar.gz","sortable_version":["1","302","170"],"version":"1.302170","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/50dc374f93316ed1c251433e1f91050e82a56711ff47a7b333602e017e3bfe3a/Test-Simple-1.302170.tar.gz","scanner_license_expression":"unknown","source_checksum":"50dc374f93316ed1c251433e1f91050e82a56711ff47a7b333602e017e3bfe3a","provided_features":[{"feature":"Test-Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API::Breakage","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API::Context","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API::Instance","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::API::Stack","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Bail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Diag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Encoding","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Exception","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Fail","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Note","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Pass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Skip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::TAP::Version","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::V2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Event::Waiting","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::About","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Amnesty","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Assert","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Control","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Error","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Info","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Info::Table","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Meta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Parent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Plan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Render","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::EventFacet::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Formatter::TAP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Hub","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Hub::Interceptor","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Hub::Interceptor::Terminator","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Hub::Subtest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::IPC","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::IPC::Driver","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::IPC::Driver::Files","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Tools::Tiny","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util::ExternalMeta","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util::Facets2Legacy","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util::HashBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test2::Util::Trace","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Formatter","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::IO::Scalar","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Module","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Tester::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::Tester::Tie","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Builder::TodoDiag","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::More","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Tester","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Tester::Capture","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Tester::CaptureRunner","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::Tester::Delegate","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"Test::use::ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"},{"feature":"ok","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","302","170"],"version":"1.302170"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"b3dd6720-f5bc-5c4d-8690-ee764aaf89ca","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:54:49.138Z","ingredient_id":"e10d6669-f1c9-57ef-a77e-3bb8fa3df884","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/e10d6669-f1c9-57ef-a77e-3bb8fa3df884"},"name":"URI","normalized_name":"URI","primary_namespace":"language/perl","description":"Uniform Resource Identifiers (absolute and relative)"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:54:49.138Z","ingredient_id":"e10d6669-f1c9-57ef-a77e-3bb8fa3df884","ingredient_version_id":"1a882ae6-d86f-5431-a5cb-8caa0abeedf5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/e10d6669-f1c9-57ef-a77e-3bb8fa3df884/versions/1a882ae6-d86f-5431-a5cb-8caa0abeedf5","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/e10d6669-f1c9-57ef-a77e-3bb8fa3df884"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2018-01-09T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/E/ET/ETHER/URI-1.73.tar.gz","sortable_version":["1","73","0"],"version":"1.73","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"URI"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/cca7ab4a6f63f3ccaacae0f2e1337e8edf84137e73f18548ec7d659f23efe413/URI-1.73.tar.gz","scanner_license_expression":"unknown","source_checksum":"cca7ab4a6f63f3ccaacae0f2e1337e8edf84137e73f18548ec7d659f23efe413","provided_features":[{"feature":"URI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::Escape","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["3","31","0"],"version":"3.31"},{"feature":"URI::Heuristic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","20","0"],"version":"4.20"},{"feature":"URI::IRI","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::QueryParam","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::Split","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::URL","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["5","4","0"],"version":"5.4"},{"feature":"URI::WithBase","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["2","20","0"],"version":"2.20"},{"feature":"URI::_foreign","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_generic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_idna","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_ldap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_login","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_punycode","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_query","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_segment","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_server","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::_userpass","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::data","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","21","0"],"version":"4.21"},{"feature":"URI::file::Base","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::FAT","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::Mac","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::OS2","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::QNX","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::Unix","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::file::Win32","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ftp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::gopher","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::http","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::https","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ldap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ldapi","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ldaps","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::mailto","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::mms","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::news","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::nntp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::pop","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::rlogin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::rsync","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::rtsp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::rtspu","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::sftp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::sip","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::sips","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::snews","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::ssh","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::telnet","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::tn3270","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::urn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::urn::isbn","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"},{"feature":"URI::urn::oid","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["1","73","0"],"version":"1.73"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"f54623d0-376f-5024-b237-c1e78a926ff8","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:55:07.132Z","ingredient_id":"6184d401-d399-5634-9a36-49b77e680ee4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6184d401-d399-5634-9a36-49b77e680ee4"},"name":"Win32-ShellQuote","normalized_name":"Win32-ShellQuote","primary_namespace":"language/perl","description":"Quote argument lists for Win32"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:55:07.132Z","ingredient_id":"6184d401-d399-5634-9a36-49b77e680ee4","ingredient_version_id":"3d2abb3d-07d3-5fac-ba8b-897484c7d98c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6184d401-d399-5634-9a36-49b77e680ee4/versions/3d2abb3d-07d3-5fac-ba8b-897484c7d98c","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/6184d401-d399-5634-9a36-49b77e680ee4"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2016-09-27T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/H/HA/HAARG/Win32-ShellQuote-0.003001.tar.gz","sortable_version":["0","3","1","0"],"version":"0.3.1","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"Win32/ShellQuote","require_os":["MSWin32","MSWin32"]},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/aa74b0e3dc2d41cd63f62f853e521ffd76b8d823479a2619e22edb4049b4c0dc/Win32-ShellQuote-0.003001.tar.gz","scanner_license_expression":"unknown","source_checksum":"aa74b0e3dc2d41cd63f62f853e521ffd76b8d823479a2619e22edb4049b4c0dc","provided_features":[{"feature":"Win32-ShellQuote","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","3","1","0"],"version":"0.3.1"},{"feature":"Win32::ShellQuote","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["0","30","1","0"],"version":"0.30.1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"Win32-ShellQuote","namespace":"language/perl","version_requirements":[{"comparator":"eq","version":"0.3.1"}]}]},{"alternatives":[],"artifact_id":"0df374fb-9686-5e09-80ee-93e1943dd1eb","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:55:57.867Z","ingredient_id":"438c3d67-b979-579d-942a-cd6a47976113","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/438c3d67-b979-579d-942a-cd6a47976113"},"name":"libwww-perl","normalized_name":"libwww-perl","primary_namespace":"language/perl","description":"The World-Wide Web library for Perl"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:55:57.867Z","ingredient_id":"438c3d67-b979-579d-942a-cd6a47976113","ingredient_version_id":"84a01b55-1d92-53ae-a7cb-d591b7b54724","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/438c3d67-b979-579d-942a-cd6a47976113/versions/84a01b55-1d92-53ae-a7cb-d591b7b54724","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/438c3d67-b979-579d-942a-cd6a47976113"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Artistic-1.0-perl OR GPL-1.0-or-later","release_timestamp":"2017-12-11T00:00:00.000Z","source_uri":"https://www.cpan.org/authors/id/E/ET/ETHER/libwww-perl-6.31.tar.gz","sortable_version":["6","31","0"],"version":"6.31","activestate_license_expression":"unknown","camel_extras":{"mm_fullext":"libwww/perl"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/525d5386d39d1c1d7da8a0e9dd0cbab95cba2a4bfcfd9b83b257f49be4eecae3/libwww-perl-6.31.tar.gz","scanner_license_expression":"unknown","source_checksum":"525d5386d39d1c1d7da8a0e9dd0cbab95cba2a4bfcfd9b83b257f49be4eecae3","provided_features":[{"feature":"LWP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Authen::Basic","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Authen::Digest","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Authen::Ntlm","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::ConnCache","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Debug","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Debug::TraceHTTP","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::DebugFile","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::MemberMixin","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::cpan","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::data","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::file","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::ftp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::gopher","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::http","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::loopback","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::mailto","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::nntp","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Protocol::nogo","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::RobotUA","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::Simple","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"LWP::UserAgent","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"},{"feature":"libwww-perl","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["6","31","0"],"version":"6.31"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"libwww-perl","namespace":"language/perl","version_requirements":[{"comparator":"gte","version":"0"}]}]},{"alternatives":["d94f704f-ab76-5db3-a571-b9a019a1cc2a","a156d3e3-3f38-55ee-a5c0-af32af5e8e7c"],"artifact_id":"84393ca8-9ac8-5e3c-a820-fa55b91bda42","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0067cb0b-fe9b-5c73-b853-bdd90d6e240b"},{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:58:19.876Z","ingredient_id":"ce716f45-743d-56e6-9d06-102a58dc9c24","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ce716f45-743d-56e6-9d06-102a58dc9c24"},"name":"podlators","normalized_name":"podlators","primary_namespace":"language/perl","description":"Convert POD data to various other formats"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-12-06T18:21:48.703Z","ingredient_id":"ce716f45-743d-56e6-9d06-102a58dc9c24","ingredient_version_id":"b131cae2-42e2-564e-a217-1266ea60ff62","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ce716f45-743d-56e6-9d06-102a58dc9c24/versions/b131cae2-42e2-564e-a217-1266ea60ff62","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/ce716f45-743d-56e6-9d06-102a58dc9c24"},"revision":2,"revision_timestamp":"2019-12-06T22:02:12.393Z","copyright_text":"perl_5","documentation_uri":"https://metacpan.org/pod/Pod::Man","is_binary_only":false,"license_expression":"(Artistic-1.0-Perl OR GPL-1.0-or-later)","release_timestamp":"2019-06-01T04:04:13.000Z","source_uri":"https://cpan.metacpan.org/authors/id/R/RR/RRA/podlators-4.12.tar.gz","sortable_version":["4","120","0"],"version":"4.12","activestate_license_expression":"unknown","dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/perl/948717da19630a5f003da4406da90fe1cbdec9ae493671c90dfb6d8b3d63b7eb/podlators-4.12.tar.gz","scanner_license_expression":"unknown","source_checksum":"948717da19630a5f003da4406da90fe1cbdec9ae493671c90dfb6d8b3d63b7eb","provided_features":[{"feature":"Pod::Man","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::ParseLink","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::Text","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::Text::Color","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::Text::Overstrike","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"Pod::Text::Termcap","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"},{"feature":"podlators","is_activestate_version":false,"is_default_provider":true,"namespace":"language/perl","sortable_version":["4","120","0"],"version":"4.12"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":["51d0cb50-cb63-5d61-9312-03343731a5c7","189665e3-7ac1-52ab-8211-8ba1ca7815f7","801206d7-a69c-53fd-9f44-a39851413669","77fc8d23-fc48-5db5-b606-f5276c1bceff","8329dae3-9920-56ae-a768-6a4c64e52436","ac073035-67b4-5786-9aa3-0cb043936036"],"artifact_id":"50d60c15-ab99-5f25-bca9-e8db079f49d3","build_scripts":[{"build_script_id":"606265a1-ac03-48e0-a708-115cc5004e9a","creation_timestamp":"2019-10-01T16:56:10.414Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/606265a1-ac03-48e0-a708-115cc5004e9a"},"conditions":null,"language":"perl","script":"openssl-1.1.0-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:17.721Z","ingredient_id":"c1256669-2a2d-5cf2-8860-804bf43ceb5f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f"},"name":"openssl","normalized_name":"openssl","primary_namespace":"shared","description":"Open Secure Sockets Layer general cryptography library."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:56:17.721Z","ingredient_id":"c1256669-2a2d-5cf2-8860-804bf43ceb5f","ingredient_version_id":"865b7af2-2892-5cb4-8a61-100a21332b5c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f/versions/865b7af2-2892-5cb4-8a61-100a21332b5c","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2019-05-28T00:00:00.000Z","source_uri":"https://www.openssl.org/source/openssl-1.1.0k.tar.gz","sortable_version":["1","10","0","11","0"],"version":"1.10.0.11","activestate_license_expression":"unknown","camel_extras":{"ppm_pkg":"no"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/efa4965f4f773574d6cbda1cf874dbbe455ab1c0d4f906115f867d30444470b1/openssl-1.1.0k.tar.gz","scanner_license_expression":"unknown","source_checksum":"efa4965f4f773574d6cbda1cf874dbbe455ab1c0d4f906115f867d30444470b1","provided_features":[{"feature":"openssl","is_activestate_version":false,"is_default_provider":true,"namespace":"shared","sortable_version":["1","10","0","11","0"],"version":"1.10.0.11"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:56:13.279Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/402b7749-a78a-4913-8cf3-65f7457f0631"},"patch_id":"402b7749-a78a-4913-8cf3-65f7457f0631","conditions":null,"content":"/src/Libraries/patches/openssl/1.10.0.11/0001-Port-1.1.0h-patch-forward-to-1.1.0k.patch","description":"[PATCH 1/3] Port 1.1.0h patch forward to 1.1.0k","sequence_number":1},{"creation_timestamp":"2019-10-01T16:56:13.634Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/f44ea593-761b-44e0-8d29-509f1dd45e6a"},"patch_id":"f44ea593-761b-44e0-8d29-509f1dd45e6a","conditions":null,"content":"/src/Libraries/patches/openssl/1.10.0.11/0002-Disable-test_err.patch","description":"[PATCH 2/3] Disable test_err","sequence_number":2},{"creation_timestamp":"2019-10-01T16:56:13.998Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/d4e5c7df-8444-4a25-a4db-ffe0b86fa0d6"},"patch_id":"d4e5c7df-8444-4a25-a4db-ffe0b86fa0d6","conditions":null,"content":"/src/Libraries/patches/openssl/1.10.0.11/0003-Add-quotes-for-windows.patch","description":"[PATCH 3/3] Add quotes for windows\n\nOn windows the command for apps/openssl\nrequires quotes to work in runtime.","sequence_number":3}],"resolved_requirements":[{"feature":"openssl","namespace":"shared","version_requirements":[{"comparator":"gte","version":"0"},{"comparator":"lt","version":"1.11.0.0"}]}]},{"alternatives":[],"artifact_id":"6938f428-a31c-5347-8f0b-e1a9650addef","build_scripts":[{"build_script_id":"677467f0-5e38-4e3b-b623-9e8464a49f91","creation_timestamp":"2019-10-01T16:58:22.954Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/677467f0-5e38-4e3b-b623-9e8464a49f91"},"conditions":null,"language":"perl","script":"postgresql-9.5.4-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"49530255-f4fa-5363-a4cc-2eb63cf5d6be"},{"dependency_types":["build"],"ingredient_version_id":"865b7af2-2892-5cb4-8a61-100a21332b5c"}],"ingredient":{"creation_timestamp":"2019-10-01T16:58:24.412Z","ingredient_id":"d89530be-8d94-5e35-b606-d7849f073e74","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d89530be-8d94-5e35-b606-d7849f073e74"},"name":"postgresql","normalized_name":"postgresql","primary_namespace":"shared","description":"An object-relational database system"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:58:24.412Z","ingredient_id":"d89530be-8d94-5e35-b606-d7849f073e74","ingredient_version_id":"a873d528-56e8-5c19-b5cb-383be3bb9074","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d89530be-8d94-5e35-b606-d7849f073e74/versions/a873d528-56e8-5c19-b5cb-383be3bb9074","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d89530be-8d94-5e35-b606-d7849f073e74"},"revision":2,"revision_timestamp":"2019-10-24T21:51:00.179Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2017-05-08T00:00:00.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/Libraries/vendor/postgresql-9.6.3.tar.gz","sortable_version":["9","6","3","0"],"version":"9.6.3","activestate_license_expression":"unknown","camel_extras":{"dont_build":["hpux","solaris"],"ppm_pkg":"no","skip_test":"yes"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/df088372230b1dd21d87bb81686471508f4c42094d4f4f32b5d8e686fea69fa6/postgresql-9.6.3.tar.gz","scanner_license_expression":"unknown","source_checksum":"df088372230b1dd21d87bb81686471508f4c42094d4f4f32b5d8e686fea69fa6","provided_features":[{"feature":"postgresql","is_activestate_version":false,"is_default_provider":true,"namespace":"shared","sortable_version":["9","6","3","0"],"version":"9.6.3"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2019-10-01T16:58:23.305Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/4aafe925-353a-45d3-813a-2f32265e2eb4"},"patch_id":"4aafe925-353a-45d3-813a-2f32265e2eb4","conditions":null,"content":"/src/Libraries/patches/postgresql-9.5.4-win32.patch","description":"[PATCH 2/2] ActiveState patches for building under MinGW and MSVC","sequence_number":1},{"creation_timestamp":"2019-10-01T16:58:23.666Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/172db555-6bc9-4aeb-afec-ca22308daa4d"},"patch_id":"172db555-6bc9-4aeb-afec-ca22308daa4d","conditions":null,"content":"/src/Libraries/patches/postgresql-9.5.4-fix-old-sun-compiler.patch","description":"Don't use __attribute__ for versions of Sun C that don't\n support it","sequence_number":2},{"creation_timestamp":"2019-10-01T16:58:24.018Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/0de4632f-8673-49d4-a504-a94ccb9ea441"},"patch_id":"0de4632f-8673-49d4-a504-a94ccb9ea441","conditions":null,"content":"/src/Libraries/patches/postgresql-9.5.4-disable-shared.patch","description":"[PATCH 3/3] Patch back in support for --disable-shared, which was\n removed from Postgres starting in 9.3. This is basically just the reverse of\n 381a9ed.","sequence_number":3}],"resolved_requirements":[]}],"solver_version":0} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/data/recipes/python-alternative-base.json b/pkg/platform/runtime/testhelper/data/recipes/python-alternative-base.json deleted file mode 100644 index 0cfe3ce8a1..0000000000 --- a/pkg/platform/runtime/testhelper/data/recipes/python-alternative-base.json +++ /dev/null @@ -1 +0,0 @@ -{"camel_flags":[],"from_recipe_store":true,"image":{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","31"],"version":"1.31","provided_features":[{"feature":"GCC","is_default_provider":null,"namespace":"compiler","sortable_version":["10","2","1"],"version":"10.2.1"},{"feature":"GNU C++03","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C++11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C++14","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C89","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C++98","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C99","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++03","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++14","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C89","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++98","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C99","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO Fortran 77","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO Fortran 90","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO Fortran 95","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"New image version with build wrapper changes","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0"],"version":"0"}]}],"revision":5,"revision_timestamp":"2021-07-05T17:36:43.183Z"},"is_indemnified":false,"platform":{"cpu_architecture":{"cpu_architecture_id":"4cdba18d-0851-4925-9ae5-9c8a2987828a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/cpu-architectures/4cdba18d-0851-4925-9ae5-9c8a2987828a"},"bit_width":"64","name":"x86","provided_features":[{"feature":"x86 64-bit","is_default_provider":null,"namespace":"cpu-architecture","sortable_version":["1"],"version":"1"}],"author_platform_user_id":"7f320133-2c9a-476e-9c09-8970ac525a8f","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2019-08-06T21:46:35.288Z"},"cpu_extensions":[],"creation_timestamp":"2021-01-15T18:05:36.924Z","display_name":"CentOS 8, Linux 4.18.0, glibc 2.28 x86 64-bit","end_of_support_date":"2025-12-31","images":[{"image_id":"00216735-694e-4ef8-a7d5-7724b9200be0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/00216735-694e-4ef8-a7d5-7724b9200be0"},"name":"docker-registry.activestate.build/activestate/centos-8-build","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","1"],"version":"1.1","provided_features":[{"feature":"GCC","is_default_provider":null,"namespace":"compiler","sortable_version":["8","3"],"version":"8.3"},{"feature":"GNU C++03","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C++11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C++14","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C89","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C++98","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C99","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++03","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++14","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C89","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++98","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C99","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO Fortran 77","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO Fortran 90","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO Fortran 95","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Added a new revision to add compiler features to images","is_stable_revision":true,"conditions":[{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"eq","sortable_version":[]}]}],"revision":1,"revision_timestamp":"2021-01-15T18:07:52.645Z"},{"image_id":"6b334b10-5211-4dc4-b97b-641de9eedcf3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/images/6b334b10-5211-4dc4-b97b-641de9eedcf3"},"name":"docker-registry.activestate.build/activestate/centos-8-builder","platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2","type":"Docker","sortable_version":["1","31"],"version":"1.31","provided_features":[{"feature":"GCC","is_default_provider":null,"namespace":"compiler","sortable_version":["10","2","1"],"version":"10.2.1"},{"feature":"GNU C++03","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C++11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C++14","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C89","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C++98","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"GNU C99","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++03","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++11","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++14","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C89","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C++98","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO C99","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO Fortran 77","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO Fortran 90","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"},{"feature":"ISO Fortran 95","is_default_provider":null,"namespace":"compiler","sortable_version":["0"],"version":"0"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"New image version with build wrapper changes","is_stable_revision":true,"conditions":[{"feature":"alternative-builder","namespace":"builder","requirements":[{"comparator":"gte","sortable_version":["0","0","1"],"version":"0.0.1"}]},{"feature":"alternative-built-language","namespace":"language","requirements":[{"comparator":"gte","sortable_version":["0"],"version":"0"}]}],"revision":5,"revision_timestamp":"2021-07-05T17:36:43.183Z"}],"is_user_visible":true,"kernel":{"kernel_id":"ef737274-fff9-4164-b72b-88067613f822","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822"},"name":"Linux"},"kernel_version":{"kernel_version_id":"61f9365e-03ed-448f-9a24-2b845727e4f5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/kernels/ef737274-fff9-4164-b72b-88067613f822/versions/61f9365e-03ed-448f-9a24-2b845727e4f5"},"sortable_version":["4","18"],"version":"4.18.0","provided_features":[{"feature":"Linux","is_default_provider":null,"namespace":"kernel","sortable_version":["4","18"],"version":"4.18.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:04.588Z"},"libc":{"libc_id":"09a2eb42-ad34-4734-a93e-4b97395577df","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df"},"name":"glibc"},"libc_version":{"libc_version_id":"22d234e7-145e-4688-9d05-ee164b4ffa12","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/libcs/09a2eb42-ad34-4734-a93e-4b97395577df/versions/22d234e7-145e-4688-9d05-ee164b4ffa12"},"sortable_version":["2","28"],"version":"2.28","provided_features":[{"feature":"glibc","is_default_provider":null,"namespace":"libc","sortable_version":["2","28"],"version":"2.28"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:19.136Z"},"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/platforms/7c998ec2-7491-4e75-be4d-8885800ef5f2"},"operating_system":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99"},"operating_system_id":"7b3a2dbb-d543-48d6-8390-7e7b63751e99","has_libc":true,"name":"CentOS"},"operating_system_version":{"links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/operating-systems/7b3a2dbb-d543-48d6-8390-7e7b63751e99/versions/42cab97b-9d80-407f-89a8-230836868e88"},"operating_system_version_id":"42cab97b-9d80-407f-89a8-230836868e88","sortable_version":["8"],"version":"8","provided_features":[{"feature":"CentOS","is_default_provider":null,"namespace":"operating-system","sortable_version":["8"],"version":"8"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true,"revision":1,"revision_timestamp":"2021-01-15T18:03:50.448Z"},"platform_id":"7c998ec2-7491-4e75-be4d-8885800ef5f2"},"recipe_id":"413fd54c-f030-58b6-be56-8a90b22eea6b","recipe_store_timestamp":"2021-07-13T22:05:49.376Z","resolved_ingredients":[{"alternatives":[],"artifact_id":"b86d0d5e-90a1-570e-8540-a1c735510b13","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"2f7d18ba-c4f7-5466-9898-015bc6e2220b"}],"ingredient":{"creation_timestamp":"2020-07-23T01:18:35.666Z","ingredient_id":"a5088640-af04-5fc3-b9ad-fdba12a8de66","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a5088640-af04-5fc3-b9ad-fdba12a8de66"},"name":"autotools-builder","normalized_name":"autotools-builder","primary_namespace":"builder","description":"Builds autotools based packages.","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T16:59:19.857Z","ingredient_id":"a5088640-af04-5fc3-b9ad-fdba12a8de66","ingredient_version_id":"4e341258-2369-5fa3-8a41-a4533416452e","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a5088640-af04-5fc3-b9ad-fdba12a8de66/versions/4e341258-2369-5fa3-8a41-a4533416452e","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/a5088640-af04-5fc3-b9ad-fdba12a8de66"},"revision":4,"revision_timestamp":"2021-06-22T16:53:28.178Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"MIT","release_timestamp":"2020-01-15T23:17:54.000Z","source_uri":"https://s3.amazonaws.com/platform-sources/builder/dbf3d193fbd188dadd5582960a7b333746a8c16c674879494173955b9a8f888b/autotools-builder.tar.gz","sortable_version":["2"],"version":"2.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/9c40e7f8d2917c21672745e2898eb1ae15bf8ada39d26fd8d6922d850da12f98/autotools-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"9c40e7f8d2917c21672745e2898eb1ae15bf8ada39d26fd8d6922d850da12f98","status":"stable","provided_features":[{"feature":"alternative-builder","is_default_provider":null,"namespace":"builder","sortable_version":["2"],"version":"2.0.0"},{"feature":"autotools-builder","is_default_provider":null,"namespace":"builder","sortable_version":["2"],"version":"2.0.0"}],"author_platform_user_id":"a4603881-68af-4a9f-9e4c-6de870d9cbb4","comment":"Initial upload.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"083cf0a1-b36e-5618-8fb4-3b059116c5e8","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"2f7d18ba-c4f7-5466-9898-015bc6e2220b"}],"ingredient":{"creation_timestamp":"2020-12-09T22:06:05.260Z","ingredient_id":"f578663c-7bf1-5139-a3e6-d135c7665699","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/f578663c-7bf1-5139-a3e6-d135c7665699"},"name":"bzip2-builder","normalized_name":"bzip2-builder","primary_namespace":"builder","description":"Builds Bzip2","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-12-09T22:06:05.260Z","ingredient_id":"f578663c-7bf1-5139-a3e6-d135c7665699","ingredient_version_id":"aba9c41d-40b3-5e82-b134-822ce4656d7c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/f578663c-7bf1-5139-a3e6-d135c7665699/versions/aba9c41d-40b3-5e82-b134-822ce4656d7c","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/f578663c-7bf1-5139-a3e6-d135c7665699"},"revision":5,"revision_timestamp":"2021-06-22T16:53:43.340Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"MIT","release_timestamp":"2020-08-26T17:35:32.000Z","source_uri":"https://s3.amazonaws.com/platform-sources/builder/399ef5c4444fb90ce2a3eeb7620cd1e1d3f4014b9755a930aabb4a912b57401d/bzip2-builder.tar.gz","sortable_version":["1"],"version":"1.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/d5d9d47ee1d9c429307e71aab772b4be0750f042dc3afe369fb8addb7f5273e2/bzip2-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"d5d9d47ee1d9c429307e71aab772b4be0750f042dc3afe369fb8addb7f5273e2","status":"stable","provided_features":[{"feature":"alternative-builder","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"},{"feature":"bzip2-builder","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"}],"author_platform_user_id":"a4603881-68af-4a9f-9e4c-6de870d9cbb4","comment":"First attempt at building bzip2 in alt-builders","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"9c5a020c-9aef-5919-929b-27244206a0a5","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"2f7d18ba-c4f7-5466-9898-015bc6e2220b"}],"ingredient":{"creation_timestamp":"2020-07-23T01:18:45.357Z","ingredient_id":"d7fbe3d6-53fa-5266-b5ba-5a8d4a2a4a44","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d7fbe3d6-53fa-5266-b5ba-5a8d4a2a4a44"},"name":"openssl-builder","normalized_name":"openssl-builder","primary_namespace":"builder","description":"Builds OpenSSL","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:56:29.653Z","ingredient_id":"d7fbe3d6-53fa-5266-b5ba-5a8d4a2a4a44","ingredient_version_id":"882ad631-b4c1-5778-8334-598aa2866423","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d7fbe3d6-53fa-5266-b5ba-5a8d4a2a4a44/versions/882ad631-b4c1-5778-8334-598aa2866423","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d7fbe3d6-53fa-5266-b5ba-5a8d4a2a4a44"},"revision":8,"revision_timestamp":"2021-06-22T16:54:49.775Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"MIT","release_timestamp":"2020-08-26T17:35:32.000Z","source_uri":"https://s3.amazonaws.com/platform-sources/builder/da84d62967bb9cb5769697af0e8e7ec85aa268cb638d602321c6167503e7fc8f/openssl-builder.tar.gz","sortable_version":["2"],"version":"2.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/18d0b52ffc51b3996a542cdaabccfd6a50f43cb916b0f93d506781d9409542c7/openssl-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"18d0b52ffc51b3996a542cdaabccfd6a50f43cb916b0f93d506781d9409542c7","status":"stable","provided_features":[{"feature":"alternative-builder","is_default_provider":null,"namespace":"builder","sortable_version":["2"],"version":"2.0.0"},{"feature":"openssl-builder","is_default_provider":null,"namespace":"builder","sortable_version":["2"],"version":"2.0.0"}],"author_platform_user_id":"a4603881-68af-4a9f-9e4c-6de870d9cbb4","comment":"Created new version 2.0.0 from 2.0.0.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"69531074-652e-5bdc-9864-a4e5c9a04876","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"2f7d18ba-c4f7-5466-9898-015bc6e2220b"}],"ingredient":{"creation_timestamp":"2021-03-15T16:57:05.232Z","ingredient_id":"f71bc6d7-8405-5b56-81e4-968670016e8e","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/f71bc6d7-8405-5b56-81e4-968670016e8e"},"name":"python-builder","normalized_name":"python-builder","primary_namespace":"builder","description":"Builds Python","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-03-15T16:57:05.232Z","ingredient_id":"f71bc6d7-8405-5b56-81e4-968670016e8e","ingredient_version_id":"5b5f6bb1-57b3-5449-985f-76c2e2179e81","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/f71bc6d7-8405-5b56-81e4-968670016e8e/versions/5b5f6bb1-57b3-5449-985f-76c2e2179e81","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/f71bc6d7-8405-5b56-81e4-968670016e8e"},"revision":10,"revision_timestamp":"2021-06-24T15:13:58.559Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"PSFL","release_timestamp":"2020-11-19T17:00:00.000Z","source_uri":"https://s3.amazonaws.com/platform-sources/builder/dcf13b6ff2b02e82b7d80ac60edcbaf704d6df0191f1bc2f8c49dc6e6857766a/python-builder.tar.gz","sortable_version":["1"],"version":"1.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/7c0d3f2d8daced808850274dab501d99987de5deef76c19308eb3071bdbbc885/python-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"7c0d3f2d8daced808850274dab501d99987de5deef76c19308eb3071bdbbc885","status":"stable","provided_features":[{"feature":"alternative-builder","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"},{"feature":"python-builder","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Initial upload.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"34ef9f26-d64c-52ac-9724-cd445b627c5c","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"2f7d18ba-c4f7-5466-9898-015bc6e2220b"},{"dependency_types":["runtime"],"ingredient_version_id":"d32eb2b8-5a71-5b82-b2a9-3003aaf5cdf1"}],"ingredient":{"creation_timestamp":"2021-06-03T19:50:17.230Z","ingredient_id":"928f7db1-381c-5dc7-9328-7cdda77395d4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/928f7db1-381c-5dc7-9328-7cdda77395d4"},"name":"python-wheel-builder","normalized_name":"python-wheel-builder","primary_namespace":"builder","description":"Builds Python Modules","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-06-03T19:50:17.230Z","ingredient_id":"928f7db1-381c-5dc7-9328-7cdda77395d4","ingredient_version_id":"c1629339-d635-55cd-99f8-7a2f9c5f437f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/928f7db1-381c-5dc7-9328-7cdda77395d4/versions/c1629339-d635-55cd-99f8-7a2f9c5f437f","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/928f7db1-381c-5dc7-9328-7cdda77395d4"},"revision":3,"revision_timestamp":"2021-06-10T18:53:13.138Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"unknown","release_timestamp":"2020-12-03T17:00:00.000Z","source_uri":"https://s3.amazonaws.com/platform-sources/builder/dcf13b6ff2b02e82b7d80ac60edcbaf704d6df0191f1bc2f8c49dc6e6857766a/python-builder.tar.gz","sortable_version":["1"],"version":"1.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/5884e3b953533a980048e90ecb230e09676e978cec14c8f2596528d2302098fc/python-wheel-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"5884e3b953533a980048e90ecb230e09676e978cec14c8f2596528d2302098fc","status":"stable","provided_features":[{"feature":"alternative-builder","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"},{"feature":"python-wheel-builder","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Initial upload.","is_stable_revision":true},"patches":null,"resolved_requirements":[{"feature":"python-wheel-builder","namespace":"builder","version_requirements":[{"comparator":"gte","version":"0"}]}]},{"alternatives":[],"artifact_id":"2472e9ae-0b24-5051-b7a4-88fc3ce0a230","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"2f7d18ba-c4f7-5466-9898-015bc6e2220b"}],"ingredient":{"creation_timestamp":"2021-03-15T16:57:50.919Z","ingredient_id":"d163cfe2-5288-583c-8b28-14d7dd4866ae","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d163cfe2-5288-583c-8b28-14d7dd4866ae"},"name":"tcltktix-builder","normalized_name":"tcltktix-builder","primary_namespace":"builder","description":"Builds Tcl/Tk/Tix bundle ingredient","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-03-15T16:57:50.919Z","ingredient_id":"d163cfe2-5288-583c-8b28-14d7dd4866ae","ingredient_version_id":"0c5e9b16-d3fe-57c4-a58f-ecd97f2b47a4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d163cfe2-5288-583c-8b28-14d7dd4866ae/versions/0c5e9b16-d3fe-57c4-a58f-ecd97f2b47a4","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/d163cfe2-5288-583c-8b28-14d7dd4866ae"},"revision":3,"revision_timestamp":"2021-07-06T20:29:33.559Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"MIT","release_timestamp":"2020-01-15T23:17:54.000Z","source_uri":"https://s3.amazon.aws.com/platform-sources/builder/41b3d1b9d6ccdb7b0f45e8b217d42d9cf3a3d60462141d0141d287910443ae1e/tcltktix-builder.tar.gz","sortable_version":["1"],"version":"1.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/590557e0306585eaba1edba55cd1d4acc9c5ac4d839b1a5edbf8440e6b1dda4b/tcltktix-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"590557e0306585eaba1edba55cd1d4acc9c5ac4d839b1a5edbf8440e6b1dda4b","status":"stable","provided_features":[{"feature":"alternative-builder","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"},{"feature":"tcltktix-builder","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial upload.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"4e738f6f-49ab-5034-a235-f54bc80211cb","build_scripts":null,"dependencies":[{"dependency_types":["runtime"],"ingredient_version_id":"2f7d18ba-c4f7-5466-9898-015bc6e2220b"}],"ingredient":{"creation_timestamp":"2020-07-23T01:18:51.945Z","ingredient_id":"fc4cbe65-edcd-5feb-bc3f-c03bf5186ff1","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/fc4cbe65-edcd-5feb-bc3f-c03bf5186ff1"},"name":"zlib-builder","normalized_name":"zlib-builder","primary_namespace":"builder","description":"Builds zlib","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T17:59:33.922Z","ingredient_id":"fc4cbe65-edcd-5feb-bc3f-c03bf5186ff1","ingredient_version_id":"60e2b59f-9a3f-5af9-84ac-2e2cc8d69611","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/fc4cbe65-edcd-5feb-bc3f-c03bf5186ff1/versions/60e2b59f-9a3f-5af9-84ac-2e2cc8d69611","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/fc4cbe65-edcd-5feb-bc3f-c03bf5186ff1"},"revision":5,"revision_timestamp":"2021-05-17T21:27:17.532Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"MIT","release_timestamp":"2020-01-15T23:17:54.000Z","source_uri":"https://s3.amazonaws.com/platform-sources/builder/dcf13b6ff2b02e82b7d80ac60edcbaf704d6df0191f1bc2f8c49dc6e6857766a/zlib-builder.tar.gz","sortable_version":["2"],"version":"2.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/dbae6b254f62f18432f34a4599e5456a7b048bc874f4fdcdbd8fa63d7b9bbee0/zlib-builder.tar.gz","scanner_license_expression":"unknown","source_checksum":"dbae6b254f62f18432f34a4599e5456a7b048bc874f4fdcdbd8fa63d7b9bbee0","status":"stable","provided_features":[{"feature":"alternative-builder","is_default_provider":null,"namespace":"builder","sortable_version":["2"],"version":"2.0.0"},{"feature":"zlib-builder","is_default_provider":null,"namespace":"builder","sortable_version":["2"],"version":"2.0.0"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial upload.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"e4556331-1d94-5ff9-95c8-4411fefd41ef","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2020-09-30T18:00:55.098Z","ingredient_id":"548f49f4-510d-5e53-91e2-ab16a77af395","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/548f49f4-510d-5e53-91e2-ab16a77af395"},"name":"python-builder-lib","normalized_name":"python-builder-lib","primary_namespace":"builder-lib","description":"Library support for Python-based builders","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-09-30T18:00:55.098Z","ingredient_id":"548f49f4-510d-5e53-91e2-ab16a77af395","ingredient_version_id":"2f7d18ba-c4f7-5466-9898-015bc6e2220b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/548f49f4-510d-5e53-91e2-ab16a77af395/versions/2f7d18ba-c4f7-5466-9898-015bc6e2220b","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/548f49f4-510d-5e53-91e2-ab16a77af395"},"revision":43,"revision_timestamp":"2021-06-28T20:52:36.800Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"MIT","release_timestamp":"2020-08-25T08:03:30.000Z","source_uri":"https://s3.amazonaws.com/platform-sources/builder/da84d62967bb9cb5769697af0e8e7ec85aa268cb638d602321c6167503e7fc8f/python-builder-lib.tar.gz","sortable_version":["1"],"version":"1.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/e823ef9841e14612f830294c30cc1d10cb77dec124a226f207dbfffcf50afa62/python-builder-lib.tar.gz","scanner_license_expression":"unknown","source_checksum":"e823ef9841e14612f830294c30cc1d10cb77dec124a226f207dbfffcf50afa62","status":"stable","provided_features":[{"feature":"alternative-builder-lib","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"},{"feature":"python-builder-lib","is_default_provider":null,"namespace":"builder-lib","sortable_version":["1"],"version":"1.0.0"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Initial creation.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"b227fd62-6304-5df4-8d2a-47ee8d26a53e","build_scripts":null,"dependencies":[],"ingredient":{"creation_timestamp":"2021-06-02T18:55:31.899Z","ingredient_id":"8872d3e4-af72-5fb8-9b52-ddbcfb46e31c","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8872d3e4-af72-5fb8-9b52-ddbcfb46e31c"},"name":"python-distribution-builder-lib","normalized_name":"python-distribution-builder-lib","primary_namespace":"builder-lib","description":"Library support for Python-based builders","website":"https://activestate.com"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-06-02T18:55:31.899Z","ingredient_id":"8872d3e4-af72-5fb8-9b52-ddbcfb46e31c","ingredient_version_id":"d32eb2b8-5a71-5b82-b2a9-3003aaf5cdf1","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8872d3e4-af72-5fb8-9b52-ddbcfb46e31c/versions/d32eb2b8-5a71-5b82-b2a9-3003aaf5cdf1","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/8872d3e4-af72-5fb8-9b52-ddbcfb46e31c"},"revision":9,"revision_timestamp":"2021-07-06T20:34:42.345Z","copyright_text":"To be added.","documentation_uri":"https://activestate.com","is_binary_only":false,"license_expression":"MIT","release_timestamp":"2020-08-25T08:03:30.000Z","source_uri":"https://s3.amazonaws.com/platform-sources/builder/da84d62967bb9cb5769697af0e8e7ec85aa268cb638d602321c6167503e7fc8f/python-builder-lib.tar.gz","sortable_version":["1"],"version":"1.0.0","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/builder/bedb935bf31aa94b624406b62d2583226501ebd26b1ccbbf1ca4a9c08986f9d6/python-distribution-builder-lib.tar.gz","scanner_license_expression":"unknown","source_checksum":"bedb935bf31aa94b624406b62d2583226501ebd26b1ccbbf1ca4a9c08986f9d6","status":"stable","provided_features":[{"feature":"alternative-builder-lib","is_default_provider":null,"namespace":"builder","sortable_version":["1"],"version":"1.0.0"},{"feature":"python-distribution-builder-lib","is_default_provider":null,"namespace":"builder-lib","sortable_version":["1"],"version":"1.0.0"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial creation.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"cc37913d-c215-5a8b-a2fc-3f3884b00ca9","build_scripts":null,"dependencies":[{"dependency_types":["build","runtime"],"ingredient_version_id":"04dfbfcd-33b0-585d-8444-1af40bde98fd"},{"dependency_types":["build","runtime"],"ingredient_version_id":"39d388df-21db-51e5-a550-a6cd04e15ba3"},{"dependency_types":["build","runtime"],"ingredient_version_id":"56725f0f-e7be-5f77-8a1e-27e33003d763"},{"dependency_types":["build"],"ingredient_version_id":"5b5f6bb1-57b3-5449-985f-76c2e2179e81"},{"dependency_types":["build"],"ingredient_version_id":"93bf4699-657f-5fff-9bc0-417c4ac841e4"},{"dependency_types":["build"],"ingredient_version_id":"a45dc564-3e7d-5b43-b2b3-2a941b0f5807"},{"dependency_types":["build"],"ingredient_version_id":"a59dcc34-5296-529e-a614-d1816ee25ebb"},{"dependency_types":["build","runtime"],"ingredient_version_id":"b077ac4e-7503-503f-b530-9f7f13dfd77f"},{"dependency_types":["build"],"ingredient_version_id":"b98a9a54-ca3d-509d-9295-7e499a0872a5"},{"dependency_types":["build","runtime"],"ingredient_version_id":"c3b7c513-8be8-56d9-8d30-b19e9c56e393"},{"dependency_types":["build"],"ingredient_version_id":"fc0a6031-9d27-5d2b-90cb-871ee6ad01d9"}],"ingredient":{"creation_timestamp":"2019-10-01T17:06:08.287Z","ingredient_id":"161a6a17-6b8a-54c9-a476-2c8c960b054e","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/161a6a17-6b8a-54c9-a476-2c8c960b054e"},"name":"python","normalized_name":"python","primary_namespace":"language","description":"It's just a flesh wound!"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-07-12T22:11:19.811Z","ingredient_id":"161a6a17-6b8a-54c9-a476-2c8c960b054e","ingredient_version_id":"1d648abb-c93f-578c-9710-cfd692cea165","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/161a6a17-6b8a-54c9-a476-2c8c960b054e/versions/1d648abb-c93f-578c-9710-cfd692cea165","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/161a6a17-6b8a-54c9-a476-2c8c960b054e"},"revision":1,"revision_timestamp":"2021-07-12T22:11:19.811Z","copyright_text":"To be added.","documentation_uri":"https://docs.python.org/3/index.html","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2021-04-09T00:00:00.000Z","source_uri":"https://www.python.org/ftp/python/3.9.6/Python-3.9.6.tgz","sortable_version":["0","3","9","6"],"version":"3.9.6","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/language/05a73de02dac1b8d2476b2ee5dc8b2adecdb3809a1abf49761a5b5d166eaba4e/cpython-3.9.6.tar.gz","scanner_license_expression":"unknown","source_checksum":"05a73de02dac1b8d2476b2ee5dc8b2adecdb3809a1abf49761a5b5d166eaba4e","status":"stable","provided_features":[{"feature":"alternative-built-language","is_default_provider":null,"namespace":"language","sortable_version":["10"],"version":"10.0.0"},{"feature":"python","is_default_provider":null,"namespace":"language","sortable_version":["0","3","9","6"],"version":"3.9.6"},{"feature":"pip","is_default_provider":null,"namespace":"language/python","sortable_version":["0","20","2","3"],"version":"20.2.3"},{"feature":"setuptools","is_default_provider":null,"namespace":"language/python","sortable_version":["0","49","2","1"],"version":"49.2.1"}],"author_platform_user_id":"ebb2d287-b6e8-4e33-87c9-ce420b18b777","comment":"add 3.9.6 release","is_stable_revision":true},"patches":[{"creation_timestamp":"2021-06-03T23:28:13.959Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/6a5782ca-e6e9-444b-9a6c-c92fdc5c1d97"},"patch_id":"6a5782ca-e6e9-444b-9a6c-c92fdc5c1d97","conditions":null,"content":"s3://platform-sources/patches/f2e5fe12c7bc4aeee200985f51bd210710f3f9424baec8eeebda1f30161f5799.patch","description":"python ~ Fix platlibdir handling in python 3.9.2","sequence_number":1}],"resolved_requirements":[{"feature":"python","namespace":"language","version_requirements":[{"comparator":"eq","version":"3.9.6"}]}]},{"alternatives":[],"artifact_id":"f0c54356-7350-5804-a857-230268000f0b","build_scripts":[{"build_script_id":"a6f6b7ba-af2c-4e14-8c12-deeaacde8251","creation_timestamp":"2021-03-15T16:59:08.589Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/a6f6b7ba-af2c-4e14-8c12-deeaacde8251"},"conditions":null,"language":"perl","script":"bzip2-1.0.6-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"aba9c41d-40b3-5e82-b134-822ce4656d7c"}],"ingredient":{"creation_timestamp":"2019-10-01T16:55:29.800Z","ingredient_id":"c9621f15-45d3-5da0-849a-f2979aa8e0d5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c9621f15-45d3-5da0-849a-f2979aa8e0d5"},"name":"bzip2","normalized_name":"bzip2","primary_namespace":"shared","description":"bzip2 is a data compressor."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2020-05-25T20:49:23.383Z","ingredient_id":"c9621f15-45d3-5da0-849a-f2979aa8e0d5","ingredient_version_id":"b077ac4e-7503-503f-b530-9f7f13dfd77f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c9621f15-45d3-5da0-849a-f2979aa8e0d5/versions/b077ac4e-7503-503f-b530-9f7f13dfd77f","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c9621f15-45d3-5da0-849a-f2979aa8e0d5"},"revision":4,"revision_timestamp":"2021-03-15T16:59:08.870Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2018-11-03T00:00:00.000Z","source_uri":"https://camel-sources.s3.amazonaws.com/src/vendor-sources/python-core/bzip2-1.0.8-pysvn.tar.gz","sortable_version":["1","0","8"],"version":"1.0.8","activestate_license_expression":"unknown","camel_extras":{"ppm_pkg":"no","skip_test":"yes"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269/bzip2-1.0.8-pysvn.tar.gz","scanner_license_expression":"unknown","source_checksum":"ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269","status":"stable","provided_features":[{"feature":"bzip2","is_default_provider":null,"namespace":"shared","sortable_version":["1","0","8"],"version":"1.0.8"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Convert patch content to S3 URI and add condition on camel builder","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"abd1cb5d-c520-5218-9891-b35c4c22280f","build_scripts":[{"build_script_id":"1ce37919-3ea7-416e-87ab-848fb1cb423b","creation_timestamp":"2021-03-15T16:59:21.788Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/1ce37919-3ea7-416e-87ab-848fb1cb423b"},"conditions":null,"language":"perl","script":"s3://platform-sources/build_scripts/2dd5db9d3d82fffed2a682f960dc4bc4f41dcdbb62f4e83f4586c793452709f7/expat-2.2.9-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"4e341258-2369-5fa3-8a41-a4533416452e"}],"ingredient":{"creation_timestamp":"2019-10-01T16:55:36.729Z","ingredient_id":"005fec58-7763-5ccf-9fce-d35fa3bfd791","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/005fec58-7763-5ccf-9fce-d35fa3bfd791"},"name":"expat","normalized_name":"expat","primary_namespace":"shared","description":"The expat package"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-11-05T00:40:36.179Z","ingredient_id":"005fec58-7763-5ccf-9fce-d35fa3bfd791","ingredient_version_id":"a45dc564-3e7d-5b43-b2b3-2a941b0f5807","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/005fec58-7763-5ccf-9fce-d35fa3bfd791/versions/a45dc564-3e7d-5b43-b2b3-2a941b0f5807","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/005fec58-7763-5ccf-9fce-d35fa3bfd791"},"revision":12,"revision_timestamp":"2021-03-15T16:59:23.466Z","copyright_text":"To be added.","documentation_uri":"https://libexpat.github.io/doc/","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2019-09-24T00:00:00.000Z","source_uri":"https://github.com/libexpat/libexpat/archive/R_2_2_9.tar.gz","sortable_version":["2","2","9"],"version":"2.2.9","activestate_license_expression":"unknown","camel_extras":{"skip_test":"yes"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/4456e0aa72ecc7e1d4b3368cd545a5eec7f9de5133a8dc37fdb1efa6174c4947/expat-2.2.9.tar.gz","scanner_license_expression":"unknown","source_checksum":"4456e0aa72ecc7e1d4b3368cd545a5eec7f9de5133a8dc37fdb1efa6174c4947","status":"stable","provided_features":[{"feature":"expat","is_default_provider":null,"namespace":"shared","sortable_version":["2","2","9"],"version":"2.2.9"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":[{"creation_timestamp":"2021-03-15T16:59:22.286Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/patches/8a60877a-0007-4237-b698-239c46b8adfd"},"patch_id":"8a60877a-0007-4237-b698-239c46b8adfd","conditions":null,"content":"s3://platform-sources/patches/92f35efe9d078a78bc8ab10b92649ed3f814a3242b91d83ebe1f36f4bdd0e9a4.patch","description":"expat ~ Fix tests trying to use wine when not cross-compiling","sequence_number":4}],"resolved_requirements":[]},{"alternatives":[],"artifact_id":"1927acf9-a8b2-5c31-a2c2-0b50fbf19607","build_scripts":[{"build_script_id":"fc94cfbc-5ab5-4f79-bb71-096a30f727d4","creation_timestamp":"2021-06-22T18:14:21.137Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/fc94cfbc-5ab5-4f79-bb71-096a30f727d4"},"conditions":null,"language":"perl","script":"libffi-3.2.1-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"4e341258-2369-5fa3-8a41-a4533416452e"}],"ingredient":{"creation_timestamp":"2019-10-01T17:02:16.451Z","ingredient_id":"7d2671f1-de31-55a8-b3e5-7ffdbcad3f1f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7d2671f1-de31-55a8-b3e5-7ffdbcad3f1f"},"name":"ffi","normalized_name":"ffi","primary_namespace":"shared","description":"A Portable Foreign Function Interface Library"},"ingredient_options":[{"command_line_args":["--configure-flag=disable-multi-os-directory"],"condition_sets":null}],"ingredient_version":{"creation_timestamp":"2020-07-23T01:18:22.431Z","ingredient_id":"7d2671f1-de31-55a8-b3e5-7ffdbcad3f1f","ingredient_version_id":"04dfbfcd-33b0-585d-8444-1af40bde98fd","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7d2671f1-de31-55a8-b3e5-7ffdbcad3f1f/versions/04dfbfcd-33b0-585d-8444-1af40bde98fd","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/7d2671f1-de31-55a8-b3e5-7ffdbcad3f1f"},"revision":5,"revision_timestamp":"2021-06-22T18:14:21.576Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"MIT","release_timestamp":"2019-11-23T16:13:26.000Z","source_uri":"https://github.com/libffi/libffi/releases/download/v3.3/libffi-3.3.tar.gz","sortable_version":["3","3"],"version":"3.3","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056/libffi-3.3.tar.gz","scanner_license_expression":"unknown","source_checksum":"72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056","status":"stable","provided_features":[{"feature":"ffi","is_default_provider":null,"namespace":"shared","sortable_version":["3","3"],"version":"3.3"},{"feature":"libffi","is_default_provider":null,"namespace":"shared","sortable_version":["3","3"],"version":"3.3"}],"author_platform_user_id":"a4603881-68af-4a9f-9e4c-6de870d9cbb4","comment":"Initial upload.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"754fb735-1ba5-5a20-b374-5d8068892457","build_scripts":[{"build_script_id":"84a7de7e-ec6a-42cc-8313-e116cfea02a5","creation_timestamp":"2020-11-10T23:20:48.695Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/84a7de7e-ec6a-42cc-8313-e116cfea02a5"},"conditions":null,"language":"perl","script":"s3://platform-sources/build_scripts/da3cead76dda8533305e75ab4ea1a100420181a5753d8373b6d7d792dee12f15/liblzma-5.2.4-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"4e341258-2369-5fa3-8a41-a4533416452e"}],"ingredient":{"creation_timestamp":"2019-10-01T17:03:51.867Z","ingredient_id":"9a1f58db-e29b-5724-86d1-3ef893700703","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9a1f58db-e29b-5724-86d1-3ef893700703"},"name":"lzma","normalized_name":"lzma","primary_namespace":"shared","description":"A general-purpose data compression library"},"ingredient_options":[{"command_line_args":["--configure-flag=disable-shared","--configure-flag=enable-static"],"condition_sets":null},{"command_line_args":["--configure-flag=with-pic"],"condition_sets":null},{"command_line_args":["--env-var=CFLAGS=-fPIC"],"condition_sets":null}],"ingredient_version":{"creation_timestamp":"2019-10-01T17:03:51.867Z","ingredient_id":"9a1f58db-e29b-5724-86d1-3ef893700703","ingredient_version_id":"a59dcc34-5296-529e-a614-d1816ee25ebb","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9a1f58db-e29b-5724-86d1-3ef893700703/versions/a59dcc34-5296-529e-a614-d1816ee25ebb","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/9a1f58db-e29b-5724-86d1-3ef893700703"},"revision":6,"revision_timestamp":"2020-11-10T23:20:49.309Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/vendor-sources/python/xz-5.2.4.tar.gz","sortable_version":["5","2","4"],"version":"5.2.4","activestate_license_expression":"unknown","camel_extras":{"skip_test":"yes"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/b512f3b726d3b37b6dc4c8570e137b9311e7552e8ccbab4d39d47ce5f4177145/xz-5.2.4.tar.gz","scanner_license_expression":"unknown","source_checksum":"b512f3b726d3b37b6dc4c8570e137b9311e7552e8ccbab4d39d47ce5f4177145","status":"stable","provided_features":[{"feature":"lzma","is_default_provider":null,"namespace":"shared","sortable_version":["5","2","4"],"version":"5.2.4"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"a4f0e9ee-58ff-5dc4-ba78-dc84f65456e4","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"4e341258-2369-5fa3-8a41-a4533416452e"}],"ingredient":{"creation_timestamp":"2021-03-15T17:00:26.569Z","ingredient_id":"fa04eb9b-679b-58dd-ab58-9f1c31ea9e9a","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/fa04eb9b-679b-58dd-ab58-9f1c31ea9e9a"},"name":"ncurses","normalized_name":"ncurses","primary_namespace":"shared","description":"New Curses Lib","website":"https://invisible-island.net/ncurses/"},"ingredient_options":[{"command_line_args":["--configure-flag=disable-rpath","--configure-flag=enable-database","--configure-flag=enable-ext-colors","--configure-flag=enable-ext-mouse","--configure-flag=enable-pc-files","--configure-flag=enable-widec","--configure-flag=with-normal","--configure-flag=with-shared","--configure-flag=with-ticlib","--configure-flag=with-cxx-binding","--configure-flag=with-cxx-shared","--configure-flag=without-ada","--configure-flag=without-debug","--alias-executable=ncursesw6-config,ncurses-config","--alias-shared-library=ncursesw,curses","--alias-shared-library=ncursesw,ncurses","--alias-shared-library=ncurses++w,ncurses++","--alias-shared-library=formw,form","--alias-shared-library=panelw,panel","--alias-shared-library=menuw,menu","--alias-pkg-config=ncursesw,ncurses","--alias-pkg-config=ncurses++w,ncurses++","--alias-pkg-config=formw,form","--alias-pkg-config=panelw,panel","--alias-pkg-config=menuw,menu"],"condition_sets":null}],"ingredient_version":{"creation_timestamp":"2021-03-15T17:00:26.569Z","ingredient_id":"fa04eb9b-679b-58dd-ab58-9f1c31ea9e9a","ingredient_version_id":"93bf4699-657f-5fff-9bc0-417c4ac841e4","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/fa04eb9b-679b-58dd-ab58-9f1c31ea9e9a/versions/93bf4699-657f-5fff-9bc0-417c4ac841e4","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/fa04eb9b-679b-58dd-ab58-9f1c31ea9e9a"},"revision":3,"revision_timestamp":"2021-06-09T17:32:47.360Z","copyright_text":"To be added.","documentation_uri":"https://invisible-island.net/ncurses/","is_binary_only":false,"license_expression":"unknown","release_timestamp":"2020-02-12T01:00:00.000Z","source_uri":"https://invisible-island.net/datafiles/release/ncurses.tar.gz","sortable_version":["6","2"],"version":"6.2","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/30306e0c76e0f9f1f0de987cf1c82a5c21e1ce6568b9227f7da5b71cbea86c9d/ncurses.tar.gz","scanner_license_expression":"unknown","source_checksum":"30306e0c76e0f9f1f0de987cf1c82a5c21e1ce6568b9227f7da5b71cbea86c9d","status":"stable","provided_features":[{"feature":"ncurses","is_default_provider":null,"namespace":"shared","sortable_version":["6","2"],"version":"6.2"}],"author_platform_user_id":"bdb16658-8b3a-4061-bae9-67e55b0d8355","comment":"Dep on alt built language creates a cycle, attempting dep on not camel instead","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"f4f1817a-4571-5572-94c7-ea5f7599c0d1","build_scripts":[{"build_script_id":"5a360285-76f0-4290-8a43-e2fada316790","creation_timestamp":"2021-04-05T15:41:46.826Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/5a360285-76f0-4290-8a43-e2fada316790"},"conditions":null,"language":"perl","script":"s3://platform-sources/build_scripts/551fdae78a3d14becf5f413395980c444a911b907ed4e7809785c7618fafa755/openssl-2021-03-24-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"882ad631-b4c1-5778-8334-598aa2866423"}],"ingredient":{"creation_timestamp":"2019-10-01T16:56:17.721Z","ingredient_id":"c1256669-2a2d-5cf2-8860-804bf43ceb5f","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f"},"name":"openssl","normalized_name":"openssl","primary_namespace":"shared","description":"Open Secure Sockets Layer general cryptography library."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-04-05T15:41:47.335Z","ingredient_id":"c1256669-2a2d-5cf2-8860-804bf43ceb5f","ingredient_version_id":"b98a9a54-ca3d-509d-9295-7e499a0872a5","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f/versions/b98a9a54-ca3d-509d-9295-7e499a0872a5","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/c1256669-2a2d-5cf2-8860-804bf43ceb5f"},"revision":1,"revision_timestamp":"2021-04-05T15:41:47.335Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2020-04-21T02:22:00.000Z","source_uri":"https://www.openssl.org/source/openssl-1.1.1k.tar.gz","sortable_version":["1","11","0","11"],"version":"1.11.0.11","activestate_license_expression":"unknown","camel_extras":{"ppm_pkg":"no"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5/openssl-1.1.1k.tar.gz","scanner_license_expression":"unknown","source_checksum":"892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5","status":"stable","provided_features":[{"feature":"openssl","is_default_provider":null,"namespace":"shared","sortable_version":["1","11","0","11"],"version":"1.11.0.11"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Convert patch content to S3 URI and add condition on camel builder","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"6ced5e90-0f8d-5840-b4be-a96d744fb879","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"4e341258-2369-5fa3-8a41-a4533416452e"},{"dependency_types":["build"],"ingredient_version_id":"93bf4699-657f-5fff-9bc0-417c4ac841e4"}],"ingredient":{"creation_timestamp":"2021-03-15T17:00:28.881Z","ingredient_id":"fcc7e430-03ce-5545-a4b3-3d1fdab454eb","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/fcc7e430-03ce-5545-a4b3-3d1fdab454eb"},"name":"readline","normalized_name":"readline","primary_namespace":"shared","description":"GNU readline library","website":"http://www.gnu.org/software/readline/"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-05-17T22:48:03.715Z","ingredient_id":"fcc7e430-03ce-5545-a4b3-3d1fdab454eb","ingredient_version_id":"fc0a6031-9d27-5d2b-90cb-871ee6ad01d9","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/fcc7e430-03ce-5545-a4b3-3d1fdab454eb/versions/fc0a6031-9d27-5d2b-90cb-871ee6ad01d9","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/fcc7e430-03ce-5545-a4b3-3d1fdab454eb"},"revision":4,"revision_timestamp":"2021-07-02T20:23:51.361Z","copyright_text":"To be added.","documentation_uri":"https://tiswww.case.edu/php/chet/readline/readline.html","is_binary_only":false,"license_expression":"GNU","release_timestamp":"2020-12-07T04:30:21.000Z","source_uri":"http://git.savannah.gnu.org/cgit/readline.git/snapshot/readline-8.0.tar.gz","sortable_version":["8","1"],"version":"8.1","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":false,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/e76581b390f8a11b027d637c1b800a72ff6aed215061644e8873f0f63114f73e/readline-8.0.tar.gz","scanner_license_expression":"unknown","source_checksum":"e76581b390f8a11b027d637c1b800a72ff6aed215061644e8873f0f63114f73e","status":"stable","provided_features":[{"feature":"readline","is_default_provider":null,"namespace":"shared","sortable_version":["8","1"],"version":"8.1"}],"author_platform_user_id":"fe7c9294-51d6-4df6-a5b5-44cf5a924ebc","comment":"Initial upload.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"e4c49e72-8ac8-5f6d-a6e1-a254f783e482","build_scripts":[{"build_script_id":"0aa7fcf0-d2de-4b03-a2d0-a3e1c456ed09","creation_timestamp":"2021-06-21T18:13:56.587Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/0aa7fcf0-d2de-4b03-a2d0-a3e1c456ed09"},"conditions":null,"language":"perl","script":"sqlite3-3.15.2-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"4e341258-2369-5fa3-8a41-a4533416452e"},{"dependency_types":["build","runtime"],"ingredient_version_id":"c3b7c513-8be8-56d9-8d30-b19e9c56e393"}],"ingredient":{"creation_timestamp":"2019-10-01T17:07:11.488Z","ingredient_id":"380e1f63-4050-59d3-b14d-2b431b5fa2e0","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/380e1f63-4050-59d3-b14d-2b431b5fa2e0"},"name":"sqlite3","normalized_name":"sqlite3","primary_namespace":"shared","description":"SQL Lite Database"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-04-22T00:14:21.641Z","ingredient_id":"380e1f63-4050-59d3-b14d-2b431b5fa2e0","ingredient_version_id":"56725f0f-e7be-5f77-8a1e-27e33003d763","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/380e1f63-4050-59d3-b14d-2b431b5fa2e0/versions/56725f0f-e7be-5f77-8a1e-27e33003d763","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/380e1f63-4050-59d3-b14d-2b431b5fa2e0"},"revision":2,"revision_timestamp":"2021-06-21T18:13:56.777Z","copyright_text":"To be added.","documentation_uri":"https://www.sqlite.org/docs.html","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2020-08-14T08:00:00.000Z","source_uri":"https://www.sqlite.org/2021/sqlite-autoconf-3350500.tar.gz","sortable_version":["3","35","5"],"version":"3.35.5","activestate_license_expression":"unknown","camel_extras":{"skip_test":"yes"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/f52b72a5c319c3e516ed7a92e123139a6e87af08a2dc43d7757724f6132e6db0/sqlite-autoconf-3350500.tar.gz","scanner_license_expression":"unknown","source_checksum":"f52b72a5c319c3e516ed7a92e123139a6e87af08a2dc43d7757724f6132e6db0","status":"stable","provided_features":[{"feature":"sqlite3","is_default_provider":null,"namespace":"shared","sortable_version":["3","35","5"],"version":"3.35.5"}],"author_platform_user_id":"8fd0aa9c-0483-4ee7-9197-96c9194c0318","comment":"New version of sqlite3 released on Apr 2, 2021","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"f7624f3f-cde8-5b44-9df8-d784c74736a4","build_scripts":null,"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"0c5e9b16-d3fe-57c4-a58f-ecd97f2b47a4"}],"ingredient":{"creation_timestamp":"2021-03-15T17:00:38.625Z","ingredient_id":"f6337ce8-5342-5a92-90e5-2ddc28b51d17","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/f6337ce8-5342-5a92-90e5-2ddc28b51d17"},"name":"tcltktix","normalized_name":"tcltktix","primary_namespace":"shared","description":"Tcl, Tk and Tix bundled ingredient"},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2021-03-15T17:00:38.625Z","ingredient_id":"f6337ce8-5342-5a92-90e5-2ddc28b51d17","ingredient_version_id":"39d388df-21db-51e5-a550-a6cd04e15ba3","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/f6337ce8-5342-5a92-90e5-2ddc28b51d17/versions/39d388df-21db-51e5-a550-a6cd04e15ba3","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/f6337ce8-5342-5a92-90e5-2ddc28b51d17"},"revision":1,"revision_timestamp":"2021-03-15T17:00:38.625Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"1970-01-01T00:00:00.000Z","source_uri":"https://prdownloads.sourceforge.net/tcl/tcl8.6.10-src.tar.gz","sortable_version":["8","6","10"],"version":"8.6.10","activestate_license_expression":"unknown","camel_extras":{},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/fff102b6cc715f672003b32189c398dffafaf1e86a26c60bb9d1f2f1b05506b2/tcltktix-8.6.10.tar.gz","scanner_license_expression":"unknown","source_checksum":"fff102b6cc715f672003b32189c398dffafaf1e86a26c60bb9d1f2f1b05506b2","status":"stable","provided_features":[{"feature":"tcltktix","is_default_provider":null,"namespace":"shared","sortable_version":["8","6","10"],"version":"8.6.10"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]},{"alternatives":[],"artifact_id":"b078f93d-644c-551e-a368-bcd5c3026d39","build_scripts":[{"build_script_id":"5014adbe-e008-4d5a-a7fb-748ccfaa72ea","creation_timestamp":"2021-03-15T16:59:55.520Z","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/build-scripts/5014adbe-e008-4d5a-a7fb-748ccfaa72ea"},"conditions":null,"language":"perl","script":"zlib-1.2.8-AS-Makefile.PL"}],"dependencies":[{"dependency_types":["build"],"ingredient_version_id":"60e2b59f-9a3f-5af9-84ac-2e2cc8d69611"}],"ingredient":{"creation_timestamp":"2019-10-01T16:58:37.399Z","ingredient_id":"aaa00228-14b4-5dce-9fe2-3370801e423b","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/aaa00228-14b4-5dce-9fe2-3370801e423b"},"name":"zlib","normalized_name":"zlib","primary_namespace":"shared","description":"General purpose data compression library."},"ingredient_options":null,"ingredient_version":{"creation_timestamp":"2019-10-01T16:58:37.399Z","ingredient_id":"aaa00228-14b4-5dce-9fe2-3370801e423b","ingredient_version_id":"c3b7c513-8be8-56d9-8d30-b19e9c56e393","links":{"self":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/aaa00228-14b4-5dce-9fe2-3370801e423b/versions/c3b7c513-8be8-56d9-8d30-b19e9c56e393","ingredient":"https://platform.activestate.com/sv/inventory-api-v1/v1/ingredients/aaa00228-14b4-5dce-9fe2-3370801e423b"},"revision":6,"revision_timestamp":"2021-03-15T16:59:56.268Z","copyright_text":"To be added.","is_binary_only":false,"license_expression":"Unknown","release_timestamp":"2017-01-15T00:00:00.000Z","source_uri":"https://s3.amazonaws.com/camel-sources/src/Libraries/vendor/zlib-1.2.11.tar.gz","sortable_version":["1","2","11"],"version":"1.2.11","activestate_license_expression":"unknown","camel_extras":{"ppm_pkg":"no","skip_test":"yes"},"dependency_sets":null,"ingredient_options":null,"is_indemnified":true,"is_stable_release":true,"platform_source_uri":"s3://platform-sources/shared/c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1/zlib-1.2.11.tar.gz","scanner_license_expression":"unknown","source_checksum":"c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1","status":"stable","provided_features":[{"feature":"zlib","is_default_provider":null,"namespace":"shared","sortable_version":["1","2","11"],"version":"1.2.11"}],"author_platform_user_id":"36a36906-04a3-4221-adf1-805632ee9bb7","comment":"Created prior to addition of revision comments.","is_stable_revision":true},"patches":null,"resolved_requirements":[]}],"solver_version":1} \ No newline at end of file diff --git a/pkg/platform/runtime/testhelper/eventsmock.go b/pkg/platform/runtime/testhelper/eventsmock.go deleted file mode 100644 index 684cd27feb..0000000000 --- a/pkg/platform/runtime/testhelper/eventsmock.go +++ /dev/null @@ -1,83 +0,0 @@ -package testhelper - -import "github.com/go-openapi/strfmt" - -type MockProgressOutput struct { - BuildStartedCalled bool - BuildCompletedCalled bool - BuildTotal int64 - BuildCurrent int - InstallationStartedCalled bool - InstallationCompletedCalled bool - InstallationTotal int64 - InstallationCurrent int - ArtifactStartedCalled int - ArtifactIncrementCalled int - ArtifactCompletedCalled int - ArtifactFailureCalled int -} - -func (mpo *MockProgressOutput) BuildStarted(total int64) error { - mpo.BuildStartedCalled = true - mpo.BuildTotal = total - return nil -} -func (mpo *MockProgressOutput) BuildCompleted(bool) error { - mpo.BuildCompletedCalled = true - return nil -} - -func (mpo *MockProgressOutput) BuildArtifactStarted(artifactID strfmt.UUID, artifactName string) error { - return nil -} -func (mpo *MockProgressOutput) BuildArtifactCompleted(artifactID strfmt.UUID, artifactName, logURI string, cachedBuild bool) error { - mpo.BuildCurrent++ - return nil -} -func (mpo *MockProgressOutput) BuildArtifactFailure(artifactID strfmt.UUID, artifactName, logURI string, errorMessage string, cachedBuild bool) error { - return nil -} -func (mpo *MockProgressOutput) BuildArtifactProgress(artifactID strfmt.UUID, artifactName, timeStamp, message, facility, pipeName, source string) error { - return nil -} - -func (mpo *MockProgressOutput) InstallationStarted(total int64) error { - mpo.InstallationStartedCalled = true - mpo.InstallationTotal = total - return nil -} -func (mpo *MockProgressOutput) InstallationStatusUpdate(current, total int64) error { - mpo.InstallationCurrent = int(current) - return nil -} -func (mpo *MockProgressOutput) InstallationCompleted(bool) error { - mpo.InstallationCompletedCalled = true - return nil -} -func (mpo *MockProgressOutput) ArtifactStepStarted(strfmt.UUID, string, string, int64, bool) error { - mpo.ArtifactStartedCalled++ - return nil -} -func (mpo *MockProgressOutput) ArtifactStepIncrement(strfmt.UUID, string, string, int64) error { - mpo.ArtifactIncrementCalled++ - return nil -} -func (mpo *MockProgressOutput) ArtifactStepCompleted(strfmt.UUID, string, string) error { - mpo.ArtifactCompletedCalled++ - return nil -} -func (mpo *MockProgressOutput) ArtifactStepFailure(strfmt.UUID, string, string, string) error { - mpo.ArtifactFailureCalled++ - return nil -} -func (mpo *MockProgressOutput) StillBuilding(numCompleted, numTotal int) error { - return nil -} -func (mpo *MockProgressOutput) SolverStart() error { - return nil -} - -func (mpo *MockProgressOutput) SolverSuccess() error { - return nil -} -func (mpo *MockProgressOutput) Close() error { return nil } diff --git a/pkg/platform/runtime/testhelper/testhelper.go b/pkg/platform/runtime/testhelper/testhelper.go deleted file mode 100644 index bf4ec92afd..0000000000 --- a/pkg/platform/runtime/testhelper/testhelper.go +++ /dev/null @@ -1,85 +0,0 @@ -package testhelper - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - "testing" - - "github.com/ActiveState/cli/internal/environment" - "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" - "github.com/ActiveState/cli/pkg/platform/api/headchef/headchef_models" - "github.com/ActiveState/cli/pkg/platform/api/inventory/inventory_models" - "github.com/stretchr/testify/require" -) - -func dataPathErr() (string, error) { - root, err := environment.GetRootPath() - if err != nil { - return "", err - } - return filepath.Join(root, "pkg", "platform", "runtime", "testhelper", "data"), nil -} - -func dataPath(t *testing.T) string { - fp, err := dataPathErr() - require.NoError(t, err) - return fp -} - -func LoadRecipe(t *testing.T, name string) *inventory_models.Recipe { - d, err := os.ReadFile(filepath.Join(dataPath(t), "recipes", fmt.Sprintf("%s.json", name))) - require.NoError(t, err) - - var recipe inventory_models.Recipe - err = json.Unmarshal(d, &recipe) - require.NoError(t, err) - - return &recipe -} - -func LoadBuildPlan(t *testing.T, name string) *response.ProjectCommitResponse { - d, err := os.ReadFile(filepath.Join(dataPath(t), "buildplans", fmt.Sprintf("%s.json", name))) - require.NoError(t, err) - - var bp response.ProjectCommitResponse - err = json.Unmarshal(d, &bp) - require.NoError(t, err) - - return &bp -} - -func SaveRecipe(name string, m *inventory_models.Recipe) error { - return save("recipes", name, m) -} - -func save(dir, name string, m interface{}) error { - dp, err := dataPathErr() - if err != nil { - return err - } - fn := filepath.Join(dp, dir, fmt.Sprintf("%s.json", name)) - - d, err := json.Marshal(m) - if err != nil { - return err - } - - return os.WriteFile(fn, d, 0666) -} - -func LoadBuildResponse(t *testing.T, name string) *headchef_models.V1BuildStatusResponse { - d, err := os.ReadFile(filepath.Join(dataPath(t), "builds", fmt.Sprintf("%s.json", name))) - require.NoError(t, err) - - var status headchef_models.V1BuildStatusResponse - err = json.Unmarshal(d, &status) - require.NoError(t, err) - - return &status -} - -func SaveBuildResponse(name string, m *headchef_models.V1BuildStatusResponse) error { - return save("builds", name, m) -} diff --git a/pkg/platform/runtime/validate/testdata/bzip2_attestation.json b/pkg/platform/runtime/validate/testdata/bzip2_attestation.json deleted file mode 100644 index 4f3ec0b260..0000000000 --- a/pkg/platform/runtime/validate/testdata/bzip2_attestation.json +++ /dev/null @@ -1 +0,0 @@ -{"payloadType": "application/vnd.in-toto+json", "payload": "eyJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLCAiaW52b2NhdGlvbiI6IHsiY29uZmlnU291cmNlIjogeyJkaWdlc3QiOiB7InNoYTI1NiI6ICJhYjVhMDMxNzZlZTEwNmQzZjBmYTkwZTM4MWRhNDc4ZGRhZTQwNTkxODE1M2NjYTI0OGU2ODJjZDBjNGEyMjY5In0sICJlbnRyeVBvaW50IjogImJ1aWxkIiwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvc2hhcmVkL2FiNWEwMzE3NmVlMTA2ZDNmMGZhOTBlMzgxZGE0NzhkZGFlNDA1OTE4MTUzY2NhMjQ4ZTY4MmNkMGM0YTIyNjkvYnppcDItMS4wLjgtcHlzdm4udGFyLmd6In0sICJlbnZpcm9ubWVudCI6IHsiZW52Ijoge319LCAicGFyYW1ldGVycyI6IFsiLS1jbWFrZS1jYWNoZT1CVUlMRF9TSEFSRURfTElCUz10cnVlIl19LCAibWF0ZXJpYWxzIjogW3siZGlnZXN0IjogeyJzaGEyNTYiOiAiNjMyMGIwMDZiMjY4YzcyMTljNzFmNjA0NjJjNzlhMWZmMmM1MjJlZTY3ZWI1NzQzMTUxMDFiMmZiNWNiZDY3NSJ9LCAidXJpIjogInMzOi8vcGxhdGZvcm0tc291cmNlcy9idWlsZGVyLzYzMjBiMDA2YjI2OGM3MjE5YzcxZjYwNDYyYzc5YTFmZjJjNTIyZWU2N2ViNTc0MzE1MTAxYjJmYjVjYmQ2NzUvY29tbW9uLWJ1aWxkZXItbGliLnRhci5neiJ9LCB7ImRpZ2VzdCI6IHsic2hhMjU2IjogIjdkNjg5MmRjZjE2ZWFkZmEwYjU4YjllNWQzM2NkMzUwNGY5YzI0Mzc1ZGUwZGY1MjdlNzVhMzU0ZTI1ZTE5OGMifSwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvYnVpbGRlci83ZDY4OTJkY2YxNmVhZGZhMGI1OGI5ZTVkMzNjZDM1MDRmOWMyNDM3NWRlMGRmNTI3ZTc1YTM1NGUyNWUxOThjL2F1dG90b29scy1idWlsZGVyLWxpYi50YXIuZ3oifSwgeyJkaWdlc3QiOiB7InNoYTI1NiI6ICI4NGE4MTI4OGRiMDAzMWI2Y2MxOGRmMjUwNmJlNTU3MTAwMDk4MzY0NjFhMDg1OGUyMjcwMzFjYzgzYjFmYzg0In0sICJ1cmkiOiAiczM6Ly9wbGF0Zm9ybS1zb3VyY2VzL2J1aWxkZXIvODRhODEyODhkYjAwMzFiNmNjMThkZjI1MDZiZTU1NzEwMDA5ODM2NDYxYTA4NThlMjI3MDMxY2M4M2IxZmM4NC91bml4LWJ1aWxkZXItbGliLnRhci5neiJ9LCB7ImRpZ2VzdCI6IHsic2hhMjU2IjogImRlZmY1ODc0ZjcxNmFlOGRkMGYzNzlkMDc0NjkyODFlZGMzMGJkOTUyMGZiZGZlZWUyZWVhNjVjYTM2NWRlNGMifSwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvYnVpbGRlci9kZWZmNTg3NGY3MTZhZThkZDBmMzc5ZDA3NDY5MjgxZWRjMzBiZDk1MjBmYmRmZWVlMmVlYTY1Y2EzNjVkZTRjL2NtYWtlLWJ1aWxkZXItbGliLnRhci5neiJ9LCB7ImRpZ2VzdCI6IHsic2hhMjU2IjogIjg3NzFlYWUyZTg0OTA3MTZlYTQ2MzczYmQ3MGZlMGY3NDkxNjZiODQ0ZWZlMDNjYjRlNTUwNDcxMTVjOGE5NGEifSwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvYnVpbGRlci84NzcxZWFlMmU4NDkwNzE2ZWE0NjM3M2JkNzBmZTBmNzQ5MTY2Yjg0NGVmZTAzY2I0ZTU1MDQ3MTE1YzhhOTRhL2NtYWtlLWJ1aWxkZXIudGFyLmd6In0sIHsiZGlnZXN0IjogbnVsbCwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvcGF0Y2hlcy9jMGEzNTcxNjE4ODRiZjIzNGJlMjAyZGViNzZmMzcwYjIwYWRjYWI3Mzg4MDJmOWJkYTcyNjAyZGIwNWRhM2FhLzAwMDEtQWRkLUNNYWtlLWJ1aWxkZXItc3VwcG9ydC5wYXRjaCJ9XSwgInByZWRpY2F0ZSI6IHsiYnVpbGRDb25maWciOiB7InN0ZXBzIjogW3siY29tbWFuZCI6ICJidWlsZCIsICJwYXJhbWV0ZXJzIjogWyItLWNtYWtlLWNhY2hlPUJVSUxEX1NIQVJFRF9MSUJTPXRydWUiXX1dfSwgImJ1aWxkVHlwZSI6ICJodHRwczovL2FjdGl2ZXN0YXRlLmNvbS9wbGF0Zm9ybV9idWlsZGVyL3YwLjEiLCAiYnVpbGRlciI6IHsiaWQiOiAiaHR0cHM6Ly9hY3RpdmVzdGF0ZS5jb20vYnVpbGRlci9jbWFrZS1idWlsZGVyQDEuMC4wcjE3In0sICJtZXRhZGF0YSI6IHsiYnVpbGRGaW5pc2hlZE9uIjogIjIwMjItMDktMDZUMjI6MjM6NDQuMDI1NzU4WiIsICJidWlsZEludm9jYXRpb25JZCI6ICJCdWlsZGVyIGNtYWtlLWJ1aWxkZXIgMS4wLjAgYnVpbGRpbmcgc2hhcmVkIGJ6aXAyIDEuMC44IGZvciBhcnRpZmFjdCA4NWU4YThmZC03YzVkLTVmMzYtYWIwZi1lNDM0NzUzNTk0NmQiLCAiYnVpbGRTdGFydGVkT24iOiAiMjAyMi0wOS0wNlQyMjoyMzo0My44NTU3NThaIiwgImNvbXBsZXRlbmVzcyI6IHsiZW52aXJvbm1lbnQiOiB0cnVlLCAibWF0ZXJpYWxzIjogdHJ1ZSwgInBhcmFtZXRlcnMiOiB0cnVlfX0sICJyZXByb2R1Y2libGUiOiB0cnVlfSwgInByZWRpY2F0ZVR5cGUiOiAiaHR0cHM6Ly9zbHNhLmRldi9wcm92ZW5hbmNlL3YwLjIiLCAic3ViamVjdCI6IFt7ImRpZ2VzdCI6IHsic2hhMjU2IjogImQ0ZDdjMWUxN2EyNGJiZTg0ZDAwZjZiMmRiODNmOTJjYWFjNzM5ZGYyM2NkMjc2MTUwNzgxZTJjMmUyZGVhZjUifSwgInVyaSI6ICJzMzovL2FzLWJ1aWxkcy9wcm9kdWN0aW9uL3NoYXJlZC9iemlwMi8xLjAuOC85Lzg1ZThhOGZkLTdjNWQtNWYzNi1hYjBmLWU0MzQ3NTM1OTQ2ZC9hcnRpZmFjdC50YXIuZ3oifV19", "signatures": [{"sig": "jmXj6x1q6IIPfdcpgZXJc74E0nsKBxr/E8ZGk4dw5Nf7KJ84SWq+pyar3xqaSMyFZXn3ektiwBJtVZIVCUxLgXMzcVZTajOMueeV04LuLzy2P03iez8w6efPh3xSl8uPn63nUt2ugXKk4flOOAYBXNlES+QqgFjYZaU+NMpkePiWwyH7Hzjg4N9SiWYWGErobBpMfdewhKXmA5a7wozP1VtaBtVB922bccJqnTkQwst9UXBrMuuJbkA5tLFNoqyyaKoN4azSythZ8TC3StZAyo8Vigvy/r6grOeU86s3s/NgCIiyANH3piAyNZfXdLsoc3iGy2rm0d6UG3T5qdmRugt6H1hGs2RPg9QQi8gdfLVVTVdL5caJT30+L/zOIt7LH+JfbmjMvAc9XXqxgQD+t2Fq51ThSKG3Q3fY7Oix8R9rZHWX5sBfzKR39cqeEtzzvIMQLPcvPGifOwfLLaCVuJnbZYOv0FuQT4yI6QFu5vn/gVrm3fwgJ8jyVas9hckO+UfUuGBsx+EWI6qUI0jNsQ5qqTGwF5k163c4uId0gbNZpWnOTSmEY+9gikSB1iy3mgPC6nQzWL+i8mVd2KZ0mS715jcYmZdVSVI9e6L4NS/7++T5yDus8Did5gsjAPrjF1udLJmGrVO/wNHUDrSKI1aAwZ3hU8fO7FxqGgzpmYE=", "cert": "-----BEGIN CERTIFICATE-----\nMIIGWDCCBMCgAwIBAgIRAN/ggKF1YLuvioWPMvCo/XgwDQYJKoZIhvcNAQEMBQAw\nVDELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UE\nAxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIzNjAeFw0yMjA1MzAw\nMDAwMDBaFw0yNTA1MjkyMzU5NTlaMG4xCzAJBgNVBAYTAkNBMRkwFwYDVQQIDBBC\ncml0aXNoIENvbHVtYmlhMSEwHwYDVQQKDBhBY3RpdmVTdGF0ZSBTb2Z0d2FyZSBJ\nbmMxITAfBgNVBAMMGEFjdGl2ZVN0YXRlIFNvZnR3YXJlIEluYzCCAiIwDQYJKoZI\nhvcNAQEBBQADggIPADCCAgoCggIBAKbVI9jNHXKM6PB3zkdcO64/nnEUG97M1txD\nwK0aWVaMYOL/R3+JJ6BIaTSNN+NjJzrof/pGhbahwy1pbCDO9hQGBqkEFgjeswkS\n00B1oXiYxGIUIv2tqinROSrNu6uxzsiBtOSe9VC/Yc+370zW67d990h79Jg4aC8b\nglSsYSNQQOHlKmZIA5fYtVG2evyV0bR5sjFLXqkP82GfIcFGgucfFqQkojvr6wTE\nl2CHJ/kwxlxAVknocTb/4yrJ9Po3Db2t+Q6mjATiRgRyN7A5t4Qs6UZ8ItLKkfBV\nhaWZhamksSD0riO5jrDeaX/2KWsfKXD8QcRzIwEcZqbJVKN1qsF8boTQ+Q7Dtn0i\nZnPDugeTHK4+7c4OCUb6rTDG4vfbUVrvQdLLp7FJBElVa+Y6Fls3ohhkZQ8MZ6c8\nPZn/BFgo6Yb6j/iVKBQZ1D7Vzol8eZPsk3uBcC3YYZ03JYp3v27nfudfFqIaJi76\nKWvPkAc3GF8SSVLPTotxFNbKY+F4bkuMQQyoRgO5OxbJ9c90KxZSptwO+6jX16b8\nLD5GMbsYsXoMFTaWQ9Xn3vXTs3bKVIEIe8xiL9QwQHruArXgyj9PaadvzExJCZW0\nt5gFSdZDKF+8VgsZbscVJoQuDzTj+JyWe6p/q++1W1/vtqKITYu8dfvQKIXrdLP0\n7LTDSWOZAgMBAAGjggGJMIIBhTAfBgNVHSMEGDAWgBQPKssghyi47G9IritUpimq\nF6TNDDAdBgNVHQ4EFgQUQAAxgT6ilb56sYvs8HCO5xU3lwMwDgYDVR0PAQH/BAQD\nAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMw\nQTA1BgwrBgEEAbIxAQIBAwIwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdv\nLmNvbS9DUFMwCAYGZ4EMAQQBMEkGA1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwu\nc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkG\nCCsGAQUFBwEBBG0wazBEBggrBgEFBQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNv\nbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGG\nF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4IBgQCCSNSa\no7mSXjVrOC7K0Z7HlBTo8WyAA8BxLAQ7h+rCIWmuLEMoCBGRkYw/0fyfZaC4PCT8\nqh76RsjVhUDA6OsFVFV9I8YB/7S7praAJPX7P6ZTlTySCYp5hBT0gs1qzgA/M+dU\nVMN5E5jMbIFtssbd+yTkOE1Sxz3Xg+6PD92ruWs0X36WG/Q7+PDzTC9Gp2WYWifB\n3TXxv1b7POsmCUR8esJdqEOv5QkmmyI/YjMWDbCJ7xHOGs2OgPNv5rJbNM813+wk\nuriXqzRrVJU86HnQV9j3PNYEwPdsRjQvP3FSnqdRyo6IkRS1F5LJwN8fwt9fbb4r\n5A8vrBD/U7ntT9DRUd1ubVZy9dT43Wc7kmhjbnoB4RhTtHc5Bl6nZS/m8Yp1/X+k\n1CEvUoI6bHIgf2q0L7zn+o0Hd5h3n90SWmVM+fmTi62cObY0QwZN1TfwHZ6CezUJ\nHTPypB+BerbmSGdbUVKABgUSrBoMLwXzeHp33urpTPDXvoTohixbw3N2qe0=\n-----END CERTIFICATE-----\n"}]} \ No newline at end of file diff --git a/pkg/platform/runtime/validate/testdata/bzip2_attestation_bad_cert.json b/pkg/platform/runtime/validate/testdata/bzip2_attestation_bad_cert.json deleted file mode 100644 index edfbf85a8f..0000000000 --- a/pkg/platform/runtime/validate/testdata/bzip2_attestation_bad_cert.json +++ /dev/null @@ -1 +0,0 @@ -{"payloadType": "application/vnd.in-toto+json", "payload": "eyJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLCAiaW52b2NhdGlvbiI6IHsiY29uZmlnU291cmNlIjogeyJkaWdlc3QiOiB7InNoYTI1NiI6ICJhYjVhMDMxNzZlZTEwNmQzZjBmYTkwZTM4MWRhNDc4ZGRhZTQwNTkxODE1M2NjYTI0OGU2ODJjZDBjNGEyMjY5In0sICJlbnRyeVBvaW50IjogImJ1aWxkIiwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvc2hhcmVkL2FiNWEwMzE3NmVlMTA2ZDNmMGZhOTBlMzgxZGE0NzhkZGFlNDA1OTE4MTUzY2NhMjQ4ZTY4MmNkMGM0YTIyNjkvYnppcDItMS4wLjgtcHlzdm4udGFyLmd6In0sICJlbnZpcm9ubWVudCI6IHsiZW52Ijoge319LCAicGFyYW1ldGVycyI6IFsiLS1jbWFrZS1jYWNoZT1CVUlMRF9TSEFSRURfTElCUz10cnVlIl19LCAibWF0ZXJpYWxzIjogW3siZGlnZXN0IjogeyJzaGEyNTYiOiAiNjMyMGIwMDZiMjY4YzcyMTljNzFmNjA0NjJjNzlhMWZmMmM1MjJlZTY3ZWI1NzQzMTUxMDFiMmZiNWNiZDY3NSJ9LCAidXJpIjogInMzOi8vcGxhdGZvcm0tc291cmNlcy9idWlsZGVyLzYzMjBiMDA2YjI2OGM3MjE5YzcxZjYwNDYyYzc5YTFmZjJjNTIyZWU2N2ViNTc0MzE1MTAxYjJmYjVjYmQ2NzUvY29tbW9uLWJ1aWxkZXItbGliLnRhci5neiJ9LCB7ImRpZ2VzdCI6IHsic2hhMjU2IjogIjdkNjg5MmRjZjE2ZWFkZmEwYjU4YjllNWQzM2NkMzUwNGY5YzI0Mzc1ZGUwZGY1MjdlNzVhMzU0ZTI1ZTE5OGMifSwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvYnVpbGRlci83ZDY4OTJkY2YxNmVhZGZhMGI1OGI5ZTVkMzNjZDM1MDRmOWMyNDM3NWRlMGRmNTI3ZTc1YTM1NGUyNWUxOThjL2F1dG90b29scy1idWlsZGVyLWxpYi50YXIuZ3oifSwgeyJkaWdlc3QiOiB7InNoYTI1NiI6ICI4NGE4MTI4OGRiMDAzMWI2Y2MxOGRmMjUwNmJlNTU3MTAwMDk4MzY0NjFhMDg1OGUyMjcwMzFjYzgzYjFmYzg0In0sICJ1cmkiOiAiczM6Ly9wbGF0Zm9ybS1zb3VyY2VzL2J1aWxkZXIvODRhODEyODhkYjAwMzFiNmNjMThkZjI1MDZiZTU1NzEwMDA5ODM2NDYxYTA4NThlMjI3MDMxY2M4M2IxZmM4NC91bml4LWJ1aWxkZXItbGliLnRhci5neiJ9LCB7ImRpZ2VzdCI6IHsic2hhMjU2IjogImRlZmY1ODc0ZjcxNmFlOGRkMGYzNzlkMDc0NjkyODFlZGMzMGJkOTUyMGZiZGZlZWUyZWVhNjVjYTM2NWRlNGMifSwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvYnVpbGRlci9kZWZmNTg3NGY3MTZhZThkZDBmMzc5ZDA3NDY5MjgxZWRjMzBiZDk1MjBmYmRmZWVlMmVlYTY1Y2EzNjVkZTRjL2NtYWtlLWJ1aWxkZXItbGliLnRhci5neiJ9LCB7ImRpZ2VzdCI6IHsic2hhMjU2IjogIjg3NzFlYWUyZTg0OTA3MTZlYTQ2MzczYmQ3MGZlMGY3NDkxNjZiODQ0ZWZlMDNjYjRlNTUwNDcxMTVjOGE5NGEifSwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvYnVpbGRlci84NzcxZWFlMmU4NDkwNzE2ZWE0NjM3M2JkNzBmZTBmNzQ5MTY2Yjg0NGVmZTAzY2I0ZTU1MDQ3MTE1YzhhOTRhL2NtYWtlLWJ1aWxkZXIudGFyLmd6In0sIHsiZGlnZXN0IjogbnVsbCwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvcGF0Y2hlcy9jMGEzNTcxNjE4ODRiZjIzNGJlMjAyZGViNzZmMzcwYjIwYWRjYWI3Mzg4MDJmOWJkYTcyNjAyZGIwNWRhM2FhLzAwMDEtQWRkLUNNYWtlLWJ1aWxkZXItc3VwcG9ydC5wYXRjaCJ9XSwgInByZWRpY2F0ZSI6IHsiYnVpbGRDb25maWciOiB7InN0ZXBzIjogW3siY29tbWFuZCI6ICJidWlsZCIsICJwYXJhbWV0ZXJzIjogWyItLWNtYWtlLWNhY2hlPUJVSUxEX1NIQVJFRF9MSUJTPXRydWUiXX1dfSwgImJ1aWxkVHlwZSI6ICJodHRwczovL2FjdGl2ZXN0YXRlLmNvbS9wbGF0Zm9ybV9idWlsZGVyL3YwLjEiLCAiYnVpbGRlciI6IHsiaWQiOiAiaHR0cHM6Ly9hY3RpdmVzdGF0ZS5jb20vYnVpbGRlci9jbWFrZS1idWlsZGVyQDEuMC4wcjE3In0sICJtZXRhZGF0YSI6IHsiYnVpbGRGaW5pc2hlZE9uIjogIjIwMjItMDktMDZUMjI6MjM6NDQuMDI1NzU4WiIsICJidWlsZEludm9jYXRpb25JZCI6ICJCdWlsZGVyIGNtYWtlLWJ1aWxkZXIgMS4wLjAgYnVpbGRpbmcgc2hhcmVkIGJ6aXAyIDEuMC44IGZvciBhcnRpZmFjdCA4NWU4YThmZC03YzVkLTVmMzYtYWIwZi1lNDM0NzUzNTk0NmQiLCAiYnVpbGRTdGFydGVkT24iOiAiMjAyMi0wOS0wNlQyMjoyMzo0My44NTU3NThaIiwgImNvbXBsZXRlbmVzcyI6IHsiZW52aXJvbm1lbnQiOiB0cnVlLCAibWF0ZXJpYWxzIjogdHJ1ZSwgInBhcmFtZXRlcnMiOiB0cnVlfX0sICJyZXByb2R1Y2libGUiOiB0cnVlfSwgInByZWRpY2F0ZVR5cGUiOiAiaHR0cHM6Ly9zbHNhLmRldi9wcm92ZW5hbmNlL3YwLjIiLCAic3ViamVjdCI6IFt7ImRpZ2VzdCI6IHsic2hhMjU2IjogImQ0ZDdjMWUxN2EyNGJiZTg0ZDAwZjZiMmRiODNmOTJjYWFjNzM5ZGYyM2NkMjc2MTUwNzgxZTJjMmUyZGVhZjUifSwgInVyaSI6ICJzMzovL2FzLWJ1aWxkcy9wcm9kdWN0aW9uL3NoYXJlZC9iemlwMi8xLjAuOC85Lzg1ZThhOGZkLTdjNWQtNWYzNi1hYjBmLWU0MzQ3NTM1OTQ2ZC9hcnRpZmFjdC50YXIuZ3oifV19", "signatures": [{"sig": "jmXj6x1q6IIPfdcpgZXJc74E0nsKBxr/E8ZGk4dw5Nf7KJ84SWq+pyar3xqaSMyFZXn3ektiwBJtVZIVCUxLgXMzcVZTajOMueeV04LuLzy2P03iez8w6efPh3xSl8uPn63nUt2ugXKk4flOOAYBXNlES+QqgFjYZaU+NMpkePiWwyH7Hzjg4N9SiWYWGErobBpMfdewhKXmA5a7wozP1VtaBtVB922bccJqnTkQwst9UXBrMuuJbkA5tLFNoqyyaKoN4azSythZ8TC3StZAyo8Vigvy/r6grOeU86s3s/NgCIiyANH3piAyNZfXdLsoc3iGy2rm0d6UG3T5qdmRugt6H1hGs2RPg9QQi8gdfLVVTVdL5caJT30+L/zOIt7LH+JfbmjMvAc9XXqxgQD+t2Fq51ThSKG3Q3fY7Oix8R9rZHWX5sBfzKR39cqeEtzzvIMQLPcvPGifOwfLLaCVuJnbZYOv0FuQT4yI6QFu5vn/gVrm3fwgJ8jyVas9hckO+UfUuGBsx+EWI6qUI0jNsQ5qqTGwF5k163c4uId0gbNZpWnOTSmEY+9gikSB1iy3mgPC6nQzWL+i8mVd2KZ0mS715jcYmZdVSVI9e6L4NS/7++T5yDus8Did5gsjAPrjF1udLJmGrVO/wNHUDrSKI1aAwZ3hU8fO7FxqGgzpmYE=", "cert": "-----BEGIN CERTIFICATE-----\nTHISISABADCERTIFICATEN/ggKF1YLuvioWPMvCo/XgwDQYJKoZIhvcNAQEMBQAw\nVDELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UE\nAxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIzNjAeFw0yMjA1MzAw\nMDAwMDBaFw0yNTA1MjkyMzU5NTlaMG4xCzAJBgNVBAYTAkNBMRkwFwYDVQQIDBBC\ncml0aXNoIENvbHVtYmlhMSEwHwYDVQQKDBhBY3RpdmVTdGF0ZSBTb2Z0d2FyZSBJ\nbmMxITAfBgNVBAMMGEFjdGl2ZVN0YXRlIFNvZnR3YXJlIEluYzCCAiIwDQYJKoZI\nhvcNAQEBBQADggIPADCCAgoCggIBAKbVI9jNHXKM6PB3zkdcO64/nnEUG97M1txD\nwK0aWVaMYOL/R3+JJ6BIaTSNN+NjJzrof/pGhbahwy1pbCDO9hQGBqkEFgjeswkS\n00B1oXiYxGIUIv2tqinROSrNu6uxzsiBtOSe9VC/Yc+370zW67d990h79Jg4aC8b\nglSsYSNQQOHlKmZIA5fYtVG2evyV0bR5sjFLXqkP82GfIcFGgucfFqQkojvr6wTE\nl2CHJ/kwxlxAVknocTb/4yrJ9Po3Db2t+Q6mjATiRgRyN7A5t4Qs6UZ8ItLKkfBV\nhaWZhamksSD0riO5jrDeaX/2KWsfKXD8QcRzIwEcZqbJVKN1qsF8boTQ+Q7Dtn0i\nZnPDugeTHK4+7c4OCUb6rTDG4vfbUVrvQdLLp7FJBElVa+Y6Fls3ohhkZQ8MZ6c8\nPZn/BFgo6Yb6j/iVKBQZ1D7Vzol8eZPsk3uBcC3YYZ03JYp3v27nfudfFqIaJi76\nKWvPkAc3GF8SSVLPTotxFNbKY+F4bkuMQQyoRgO5OxbJ9c90KxZSptwO+6jX16b8\nLD5GMbsYsXoMFTaWQ9Xn3vXTs3bKVIEIe8xiL9QwQHruArXgyj9PaadvzExJCZW0\nt5gFSdZDKF+8VgsZbscVJoQuDzTj+JyWe6p/q++1W1/vtqKITYu8dfvQKIXrdLP0\n7LTDSWOZAgMBAAGjggGJMIIBhTAfBgNVHSMEGDAWgBQPKssghyi47G9IritUpimq\nF6TNDDAdBgNVHQ4EFgQUQAAxgT6ilb56sYvs8HCO5xU3lwMwDgYDVR0PAQH/BAQD\nAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMw\nQTA1BgwrBgEEAbIxAQIBAwIwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdv\nLmNvbS9DUFMwCAYGZ4EMAQQBMEkGA1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwu\nc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkG\nCCsGAQUFBwEBBG0wazBEBggrBgEFBQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNv\nbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGG\nF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4IBgQCCSNSa\no7mSXjVrOC7K0Z7HlBTo8WyAA8BxLAQ7h+rCIWmuLEMoCBGRkYw/0fyfZaC4PCT8\nqh76RsjVhUDA6OsFVFV9I8YB/7S7praAJPX7P6ZTlTySCYp5hBT0gs1qzgA/M+dU\nVMN5E5jMbIFtssbd+yTkOE1Sxz3Xg+6PD92ruWs0X36WG/Q7+PDzTC9Gp2WYWifB\n3TXxv1b7POsmCUR8esJdqEOv5QkmmyI/YjMWDbCJ7xHOGs2OgPNv5rJbNM813+wk\nuriXqzRrVJU86HnQV9j3PNYEwPdsRjQvP3FSnqdRyo6IkRS1F5LJwN8fwt9fbb4r\n5A8vrBD/U7ntT9DRUd1ubVZy9dT43Wc7kmhjbnoB4RhTtHc5Bl6nZS/m8Yp1/X+k\n1CEvUoI6bHIgf2q0L7zn+o0Hd5h3n90SWmVM+fmTi62cObY0QwZN1TfwHZ6CezUJ\nHTPypB+BerbmSGdbUVKABgUSrBoMLwXzeHp33urpTPDXvoTohixbw3N2qe0=\n-----END CERTIFICATE-----\n"}]} diff --git a/pkg/platform/runtime/validate/testdata/bzip2_attestation_bad_sig.json b/pkg/platform/runtime/validate/testdata/bzip2_attestation_bad_sig.json deleted file mode 100644 index 08a9336b25..0000000000 --- a/pkg/platform/runtime/validate/testdata/bzip2_attestation_bad_sig.json +++ /dev/null @@ -1 +0,0 @@ -{"payloadType": "application/vnd.in-toto+json", "payload": "eyJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLCAiaW52b2NhdGlvbiI6IHsiY29uZmlnU291cmNlIjogeyJkaWdlc3QiOiB7InNoYTI1NiI6ICJhYjVhMDMxNzZlZTEwNmQzZjBmYTkwZTM4MWRhNDc4ZGRhZTQwNTkxODE1M2NjYTI0OGU2ODJjZDBjNGEyMjY5In0sICJlbnRyeVBvaW50IjogImJ1aWxkIiwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvc2hhcmVkL2FiNWEwMzE3NmVlMTA2ZDNmMGZhOTBlMzgxZGE0NzhkZGFlNDA1OTE4MTUzY2NhMjQ4ZTY4MmNkMGM0YTIyNjkvYnppcDItMS4wLjgtcHlzdm4udGFyLmd6In0sICJlbnZpcm9ubWVudCI6IHsiZW52Ijoge319LCAicGFyYW1ldGVycyI6IFsiLS1jbWFrZS1jYWNoZT1CVUlMRF9TSEFSRURfTElCUz10cnVlIl19LCAibWF0ZXJpYWxzIjogW3siZGlnZXN0IjogeyJzaGEyNTYiOiAiNjMyMGIwMDZiMjY4YzcyMTljNzFmNjA0NjJjNzlhMWZmMmM1MjJlZTY3ZWI1NzQzMTUxMDFiMmZiNWNiZDY3NSJ9LCAidXJpIjogInMzOi8vcGxhdGZvcm0tc291cmNlcy9idWlsZGVyLzYzMjBiMDA2YjI2OGM3MjE5YzcxZjYwNDYyYzc5YTFmZjJjNTIyZWU2N2ViNTc0MzE1MTAxYjJmYjVjYmQ2NzUvY29tbW9uLWJ1aWxkZXItbGliLnRhci5neiJ9LCB7ImRpZ2VzdCI6IHsic2hhMjU2IjogIjdkNjg5MmRjZjE2ZWFkZmEwYjU4YjllNWQzM2NkMzUwNGY5YzI0Mzc1ZGUwZGY1MjdlNzVhMzU0ZTI1ZTE5OGMifSwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvYnVpbGRlci83ZDY4OTJkY2YxNmVhZGZhMGI1OGI5ZTVkMzNjZDM1MDRmOWMyNDM3NWRlMGRmNTI3ZTc1YTM1NGUyNWUxOThjL2F1dG90b29scy1idWlsZGVyLWxpYi50YXIuZ3oifSwgeyJkaWdlc3QiOiB7InNoYTI1NiI6ICI4NGE4MTI4OGRiMDAzMWI2Y2MxOGRmMjUwNmJlNTU3MTAwMDk4MzY0NjFhMDg1OGUyMjcwMzFjYzgzYjFmYzg0In0sICJ1cmkiOiAiczM6Ly9wbGF0Zm9ybS1zb3VyY2VzL2J1aWxkZXIvODRhODEyODhkYjAwMzFiNmNjMThkZjI1MDZiZTU1NzEwMDA5ODM2NDYxYTA4NThlMjI3MDMxY2M4M2IxZmM4NC91bml4LWJ1aWxkZXItbGliLnRhci5neiJ9LCB7ImRpZ2VzdCI6IHsic2hhMjU2IjogImRlZmY1ODc0ZjcxNmFlOGRkMGYzNzlkMDc0NjkyODFlZGMzMGJkOTUyMGZiZGZlZWUyZWVhNjVjYTM2NWRlNGMifSwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvYnVpbGRlci9kZWZmNTg3NGY3MTZhZThkZDBmMzc5ZDA3NDY5MjgxZWRjMzBiZDk1MjBmYmRmZWVlMmVlYTY1Y2EzNjVkZTRjL2NtYWtlLWJ1aWxkZXItbGliLnRhci5neiJ9LCB7ImRpZ2VzdCI6IHsic2hhMjU2IjogIjg3NzFlYWUyZTg0OTA3MTZlYTQ2MzczYmQ3MGZlMGY3NDkxNjZiODQ0ZWZlMDNjYjRlNTUwNDcxMTVjOGE5NGEifSwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvYnVpbGRlci84NzcxZWFlMmU4NDkwNzE2ZWE0NjM3M2JkNzBmZTBmNzQ5MTY2Yjg0NGVmZTAzY2I0ZTU1MDQ3MTE1YzhhOTRhL2NtYWtlLWJ1aWxkZXIudGFyLmd6In0sIHsiZGlnZXN0IjogbnVsbCwgInVyaSI6ICJzMzovL3BsYXRmb3JtLXNvdXJjZXMvcGF0Y2hlcy9jMGEzNTcxNjE4ODRiZjIzNGJlMjAyZGViNzZmMzcwYjIwYWRjYWI3Mzg4MDJmOWJkYTcyNjAyZGIwNWRhM2FhLzAwMDEtQWRkLUNNYWtlLWJ1aWxkZXItc3VwcG9ydC5wYXRjaCJ9XSwgInByZWRpY2F0ZSI6IHsiYnVpbGRDb25maWciOiB7InN0ZXBzIjogW3siY29tbWFuZCI6ICJidWlsZCIsICJwYXJhbWV0ZXJzIjogWyItLWNtYWtlLWNhY2hlPUJVSUxEX1NIQVJFRF9MSUJTPXRydWUiXX1dfSwgImJ1aWxkVHlwZSI6ICJodHRwczovL2FjdGl2ZXN0YXRlLmNvbS9wbGF0Zm9ybV9idWlsZGVyL3YwLjEiLCAiYnVpbGRlciI6IHsiaWQiOiAiaHR0cHM6Ly9hY3RpdmVzdGF0ZS5jb20vYnVpbGRlci9jbWFrZS1idWlsZGVyQDEuMC4wcjE3In0sICJtZXRhZGF0YSI6IHsiYnVpbGRGaW5pc2hlZE9uIjogIjIwMjItMDktMDZUMjI6MjM6NDQuMDI1NzU4WiIsICJidWlsZEludm9jYXRpb25JZCI6ICJCdWlsZGVyIGNtYWtlLWJ1aWxkZXIgMS4wLjAgYnVpbGRpbmcgc2hhcmVkIGJ6aXAyIDEuMC44IGZvciBhcnRpZmFjdCA4NWU4YThmZC03YzVkLTVmMzYtYWIwZi1lNDM0NzUzNTk0NmQiLCAiYnVpbGRTdGFydGVkT24iOiAiMjAyMi0wOS0wNlQyMjoyMzo0My44NTU3NThaIiwgImNvbXBsZXRlbmVzcyI6IHsiZW52aXJvbm1lbnQiOiB0cnVlLCAibWF0ZXJpYWxzIjogdHJ1ZSwgInBhcmFtZXRlcnMiOiB0cnVlfX0sICJyZXByb2R1Y2libGUiOiB0cnVlfSwgInByZWRpY2F0ZVR5cGUiOiAiaHR0cHM6Ly9zbHNhLmRldi9wcm92ZW5hbmNlL3YwLjIiLCAic3ViamVjdCI6IFt7ImRpZ2VzdCI6IHsic2hhMjU2IjogImQ0ZDdjMWUxN2EyNGJiZTg0ZDAwZjZiMmRiODNmOTJjYWFjNzM5ZGYyM2NkMjc2MTUwNzgxZTJjMmUyZGVhZjUifSwgInVyaSI6ICJzMzovL2FzLWJ1aWxkcy9wcm9kdWN0aW9uL3NoYXJlZC9iemlwMi8xLjAuOC85Lzg1ZThhOGZkLTdjNWQtNWYzNi1hYjBmLWU0MzQ3NTM1OTQ2ZC9hcnRpZmFjdC50YXIuZ3oifV19", "signatures": [{"sig": "THISISABADSIGNATUREJc74E0nsKBxr/E8ZGk4dw5Nf7KJ84SWq+pyar3xqaSMyFZXn3ektiwBJtVZIVCUxLgXMzcVZTajOMueeV04LuLzy2P03iez8w6efPh3xSl8uPn63nUt2ugXKk4flOOAYBXNlES+QqgFjYZaU+NMpkePiWwyH7Hzjg4N9SiWYWGErobBpMfdewhKXmA5a7wozP1VtaBtVB922bccJqnTkQwst9UXBrMuuJbkA5tLFNoqyyaKoN4azSythZ8TC3StZAyo8Vigvy/r6grOeU86s3s/NgCIiyANH3piAyNZfXdLsoc3iGy2rm0d6UG3T5qdmRugt6H1hGs2RPg9QQi8gdfLVVTVdL5caJT30+L/zOIt7LH+JfbmjMvAc9XXqxgQD+t2Fq51ThSKG3Q3fY7Oix8R9rZHWX5sBfzKR39cqeEtzzvIMQLPcvPGifOwfLLaCVuJnbZYOv0FuQT4yI6QFu5vn/gVrm3fwgJ8jyVas9hckO+UfUuGBsx+EWI6qUI0jNsQ5qqTGwF5k163c4uId0gbNZpWnOTSmEY+9gikSB1iy3mgPC6nQzWL+i8mVd2KZ0mS715jcYmZdVSVI9e6L4NS/7++T5yDus8Did5gsjAPrjF1udLJmGrVO/wNHUDrSKI1aAwZ3hU8fO7FxqGgzpmYE=", "cert": "-----BEGIN CERTIFICATE-----\nMIIGWDCCBMCgAwIBAgIRAN/ggKF1YLuvioWPMvCo/XgwDQYJKoZIhvcNAQEMBQAw\nVDELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UE\nAxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIzNjAeFw0yMjA1MzAw\nMDAwMDBaFw0yNTA1MjkyMzU5NTlaMG4xCzAJBgNVBAYTAkNBMRkwFwYDVQQIDBBC\ncml0aXNoIENvbHVtYmlhMSEwHwYDVQQKDBhBY3RpdmVTdGF0ZSBTb2Z0d2FyZSBJ\nbmMxITAfBgNVBAMMGEFjdGl2ZVN0YXRlIFNvZnR3YXJlIEluYzCCAiIwDQYJKoZI\nhvcNAQEBBQADggIPADCCAgoCggIBAKbVI9jNHXKM6PB3zkdcO64/nnEUG97M1txD\nwK0aWVaMYOL/R3+JJ6BIaTSNN+NjJzrof/pGhbahwy1pbCDO9hQGBqkEFgjeswkS\n00B1oXiYxGIUIv2tqinROSrNu6uxzsiBtOSe9VC/Yc+370zW67d990h79Jg4aC8b\nglSsYSNQQOHlKmZIA5fYtVG2evyV0bR5sjFLXqkP82GfIcFGgucfFqQkojvr6wTE\nl2CHJ/kwxlxAVknocTb/4yrJ9Po3Db2t+Q6mjATiRgRyN7A5t4Qs6UZ8ItLKkfBV\nhaWZhamksSD0riO5jrDeaX/2KWsfKXD8QcRzIwEcZqbJVKN1qsF8boTQ+Q7Dtn0i\nZnPDugeTHK4+7c4OCUb6rTDG4vfbUVrvQdLLp7FJBElVa+Y6Fls3ohhkZQ8MZ6c8\nPZn/BFgo6Yb6j/iVKBQZ1D7Vzol8eZPsk3uBcC3YYZ03JYp3v27nfudfFqIaJi76\nKWvPkAc3GF8SSVLPTotxFNbKY+F4bkuMQQyoRgO5OxbJ9c90KxZSptwO+6jX16b8\nLD5GMbsYsXoMFTaWQ9Xn3vXTs3bKVIEIe8xiL9QwQHruArXgyj9PaadvzExJCZW0\nt5gFSdZDKF+8VgsZbscVJoQuDzTj+JyWe6p/q++1W1/vtqKITYu8dfvQKIXrdLP0\n7LTDSWOZAgMBAAGjggGJMIIBhTAfBgNVHSMEGDAWgBQPKssghyi47G9IritUpimq\nF6TNDDAdBgNVHQ4EFgQUQAAxgT6ilb56sYvs8HCO5xU3lwMwDgYDVR0PAQH/BAQD\nAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMw\nQTA1BgwrBgEEAbIxAQIBAwIwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdv\nLmNvbS9DUFMwCAYGZ4EMAQQBMEkGA1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwu\nc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkG\nCCsGAQUFBwEBBG0wazBEBggrBgEFBQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNv\nbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGG\nF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4IBgQCCSNSa\no7mSXjVrOC7K0Z7HlBTo8WyAA8BxLAQ7h+rCIWmuLEMoCBGRkYw/0fyfZaC4PCT8\nqh76RsjVhUDA6OsFVFV9I8YB/7S7praAJPX7P6ZTlTySCYp5hBT0gs1qzgA/M+dU\nVMN5E5jMbIFtssbd+yTkOE1Sxz3Xg+6PD92ruWs0X36WG/Q7+PDzTC9Gp2WYWifB\n3TXxv1b7POsmCUR8esJdqEOv5QkmmyI/YjMWDbCJ7xHOGs2OgPNv5rJbNM813+wk\nuriXqzRrVJU86HnQV9j3PNYEwPdsRjQvP3FSnqdRyo6IkRS1F5LJwN8fwt9fbb4r\n5A8vrBD/U7ntT9DRUd1ubVZy9dT43Wc7kmhjbnoB4RhTtHc5Bl6nZS/m8Yp1/X+k\n1CEvUoI6bHIgf2q0L7zn+o0Hd5h3n90SWmVM+fmTi62cObY0QwZN1TfwHZ6CezUJ\nHTPypB+BerbmSGdbUVKABgUSrBoMLwXzeHp33urpTPDXvoTohixbw3N2qe0=\n-----END CERTIFICATE-----\n"}]} diff --git a/pkg/platform/runtime/validate/validate.go b/pkg/platform/runtime/validate/validate.go deleted file mode 100644 index 051ae9cbd1..0000000000 --- a/pkg/platform/runtime/validate/validate.go +++ /dev/null @@ -1,149 +0,0 @@ -package validate - -import ( - "crypto" - "crypto/rsa" - "crypto/sha256" - "crypto/x509" - "encoding/base64" - "encoding/json" - "encoding/pem" - "strings" - - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/httputil" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" - "go.mozilla.org/pkcs7" -) - -type signature struct { - Sig string `json:"sig"` - Cert string `json:"cert"` -} - -type attestation struct { - Payload string `json:"payload"` - Signatures []signature `json:"signatures"` -} - -func Attestation(attestationFile string) error { - data, err := fileutils.ReadFile(attestationFile) - if err != nil { - return errs.Wrap(err, "Could not read attestation: %s", attestationFile) - } - - att := attestation{} - err = json.Unmarshal(data, &att) - if err != nil { - return errs.Wrap(err, "Could not unmarshal attestation") - } - - if len(att.Signatures) == 0 { - return locale.NewError("validate_attestation_fail_no_signatures", "No signatures") - } - - // Verify signing certificate. - pemBlock, _ := pem.Decode([]byte(att.Signatures[0].Cert)) - if pemBlock == nil { - return locale.NewError("validate_attestation_fail_decode_cert", "Unable to decode attestation certificate") - } - - cert, err := x509.ParseCertificate(pemBlock.Bytes) - if err != nil { - return errs.Wrap(err, "Unable to parse attestation certificate") - } - - intermediates := x509.NewCertPool() - addIntermediatesToPool(intermediates, cert) - - opts := x509.VerifyOptions{ - Roots: nil, // use system root CAs - Intermediates: intermediates, - KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning}, - } - _, err = cert.Verify(opts) - if err != nil { - return errs.Wrap(err, "Unable to validate certificate") - } - - // Verify signature. - payload := make([]byte, len(att.Payload)) - n, err := base64.StdEncoding.Decode(payload, []byte(att.Payload)) - if err != nil { - return errs.Wrap(err, "Unable to decode attestation payload") - } - payload = payload[:n] - hash := sha256.New() - hash.Write(payload) - digest := hash.Sum(nil) - - signature := make([]byte, len(att.Signatures[0].Sig)) - n, err = base64.StdEncoding.Decode(signature, []byte(att.Signatures[0].Sig)) - if err != nil { - return errs.Wrap(err, "Unable to decode attestation signature") - } - signature = signature[:n] - - publicKey, ok := cert.PublicKey.(*rsa.PublicKey) - if !ok { - return locale.NewError("validate_attestation_fail_public_key", "Certificate's public key is not an expected RSA pubkey") - } - err = rsa.VerifyPSS(publicKey, crypto.SHA256, digest, signature, &rsa.PSSOptions{Hash: crypto.SHA256}) - if err != nil { - return errs.Wrap(err, "Unable to validate signature") - } - - return nil -} - -func addIntermediatesToPool(pool *x509.CertPool, cert *x509.Certificate) { - for _, url := range cert.IssuingCertificateURL { - bytes, err := httputil.GetDirect(url) - if err != nil { - logging.Debug("Unable to download intermediate certificate %s: %v", url, err) - continue - } - if !strings.HasSuffix(url, ".p7c") { - cert, err := x509.ParseCertificate(bytes) - if err != nil { - logging.Debug("Unable to parse intermediate certificate %s: %v", url, err) - continue - } - pool.AddCert(cert) - addIntermediatesToPool(pool, cert) - } else { - p7, err := pkcs7.Parse(bytes) - if err != nil { - logging.Debug("Unable to parse intermediate certificate %s: %v", url, err) - continue - } - for _, cert := range p7.Certificates { - pool.AddCert(cert) - addIntermediatesToPool(pool, cert) - } - } - } -} - -func Checksum(archivePath string, expectedChecksum string) error { - if expectedChecksum == "" { - logging.Debug("Skipping checksum validation for %s because the Platform did not provide a checksum to validate against.") - return nil - } - logging.Debug("Validating checksum for %s", archivePath) - - checksum, err := fileutils.Sha256Hash(archivePath) - if err != nil { - return errs.Wrap(err, "Failed to compute checksum for %s", archivePath) - } - - if checksum != expectedChecksum { - logging.Debug("Checksum validation failed. Expected '%s', but was '%s'", expectedChecksum, checksum) - // Note: the artifact name will be reported higher up the chain - return locale.WrapError(err, "artifact_checksum_failed", "Checksum validation failed") - } - - return nil -} diff --git a/pkg/platform/runtime/validate/validate_test.go b/pkg/platform/runtime/validate/validate_test.go deleted file mode 100644 index 0939cc380f..0000000000 --- a/pkg/platform/runtime/validate/validate_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package validate - -import ( - "path/filepath" - "runtime" - "testing" - - "github.com/ActiveState/cli/internal/testhelpers/osutil" - "github.com/stretchr/testify/assert" -) - -func TestValidate(t *testing.T) { - if runtime.GOOS == "darwin" { - t.Skip("Disabled on macOS due to non-standards compliant signing certificate") // DX-1451 - } - attestationFile := filepath.Join(osutil.GetTestDataDir(), "bzip2_attestation.json") - err := Attestation(attestationFile) - assert.NoError(t, err) - - attestationFile = filepath.Join(osutil.GetTestDataDir(), "bzip2_attestation_bad_cert.json") - err = Attestation(attestationFile) - assert.Error(t, err) - - attestationFile = filepath.Join(osutil.GetTestDataDir(), "bzip2_attestation_bad_sig.json") - err = Attestation(attestationFile) - assert.Error(t, err) -} diff --git a/pkg/project/project.go b/pkg/project/project.go index 07601c8aaf..22c3d46c60 100644 --- a/pkg/project/project.go +++ b/pkg/project/project.go @@ -49,7 +49,12 @@ type Project struct { } // Source returns the source projectfile -func (p *Project) Source() *projectfile.Project { return p.projectfile } +func (p *Project) Source() *projectfile.Project { + if p == nil { + return nil + } + return p.projectfile +} // Constants returns a reference to projectfile.Constants func (p *Project) Constants() []*Constant { diff --git a/pkg/projectfile/projectfile.go b/pkg/projectfile/projectfile.go index ae33283bb8..9761cbb17b 100644 --- a/pkg/projectfile/projectfile.go +++ b/pkg/projectfile/projectfile.go @@ -31,7 +31,6 @@ import ( "github.com/ActiveState/cli/internal/sliceutils" "github.com/ActiveState/cli/internal/strutils" "github.com/ActiveState/cli/pkg/sysinfo" - "github.com/go-openapi/strfmt" "github.com/google/uuid" "github.com/imdario/mergo" "github.com/spf13/cast" @@ -540,7 +539,7 @@ func parseData(dat []byte, configFilepath string) (*Project, error) { if err2 != nil { return nil, &ErrorParseProject{locale.NewExternalError( "err_project_parsed", - "Project file `{{.V1}}` could not be parsed, the parser produced the following error: {{.V0}}", err2.Error(), configFilepath), + "Project file `{{.V1}}` could not be parsed. The parser produced the following error: {{.V0}}", err2.Error(), configFilepath), } } @@ -660,19 +659,6 @@ func (p *Project) parseURL() (projectURL, error) { return parseURL(p.Project) } -func validateUUID(uuidStr string) error { - if ok := strfmt.Default.Validates("uuid", uuidStr); !ok { - return locale.NewError("err_commit_id_invalid", "", uuidStr) - } - - var uuid strfmt.UUID - if err := uuid.UnmarshalText([]byte(uuidStr)); err != nil { - return locale.WrapError(err, "err_commit_id_unmarshal", "Failed to unmarshal the commit id {{.V0}} read from activestate.yaml.", uuidStr) - } - - return nil -} - func parseURL(rawURL string) (projectURL, error) { p := projectURL{} @@ -701,12 +687,6 @@ func parseURL(rawURL string) (projectURL, error) { p.LegacyCommitID = c } - if p.LegacyCommitID != "" { - if err := validateUUID(p.LegacyCommitID); err != nil { - return p, err - } - } - if b := q.Get("branch"); b != "" { p.BranchName = b } diff --git a/pkg/projectfile/projectfile_test.go b/pkg/projectfile/projectfile_test.go index bffabb4db5..6ec6ed339b 100644 --- a/pkg/projectfile/projectfile_test.go +++ b/pkg/projectfile/projectfile_test.go @@ -377,13 +377,12 @@ func TestValidateProjectURL(t *testing.T) { func Test_parseURL(t *testing.T) { tests := []struct { - name string - rawURL string - want projectURL - wantErr bool + name string + rawURL string + want projectURL }{ { - "Valid full legacy URL", + "Full URL", "https://platform.activestate.com/Owner/Name?commitID=7BA74758-8665-4D3F-921C-757CD271A0C1&branch=main", projectURL{ Owner: "Owner", @@ -391,10 +390,9 @@ func Test_parseURL(t *testing.T) { LegacyCommitID: "7BA74758-8665-4D3F-921C-757CD271A0C1", BranchName: "main", }, - false, }, { - "Valid commit URL", + "Legacy commit URL", "https://platform.activestate.com/commit/7BA74758-8665-4D3F-921C-757CD271A0C1", projectURL{ Owner: "", @@ -402,23 +400,16 @@ func Test_parseURL(t *testing.T) { LegacyCommitID: "7BA74758-8665-4D3F-921C-757CD271A0C1", BranchName: "", }, - false, - }, - { - "Invalid commit", - "https://platform.activestate.com/commit/nope", - projectURL{}, - true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := parseURL(tt.rawURL) - if (err != nil) != tt.wantErr { - t.Errorf("parseURL() error = %v, wantErr %v", err, tt.wantErr) + if err != nil { + t.Errorf("parseURL() error = %v", err) return } - if !tt.wantErr && !reflect.DeepEqual(got, tt.want) { + if !reflect.DeepEqual(got, tt.want) { t.Errorf("parseURL() got = %v, want %v", got, tt.want) } }) diff --git a/pkg/projectfile/yamlfield.go b/pkg/projectfile/yamlfield.go index 2217d37a4b..13b5691530 100644 --- a/pkg/projectfile/yamlfield.go +++ b/pkg/projectfile/yamlfield.go @@ -7,6 +7,8 @@ import ( "regexp" "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/osutils" "gopkg.in/yaml.v2" ) @@ -56,6 +58,11 @@ func (y *yamlField) Save(path string) error { } if err := os.WriteFile(path, out, 0664); err != nil { + if osutils.IsAccessDeniedError(err) { + return locale.WrapInputError(err, "err_migrate_projectfile_access_denied", + "Your project file at '{{.V0}}' is out of date, but State Tool does not have permission to update it. Please make it writeable or re-checkout the project to a writeable location.", + path) + } return errs.Wrap(err, "ioutil.WriteFile %s failed", path) } diff --git a/pkg/runtime/build.go b/pkg/runtime/build.go new file mode 100644 index 0000000000..7ccdf5f690 --- /dev/null +++ b/pkg/runtime/build.go @@ -0,0 +1 @@ +package runtime diff --git a/pkg/runtime/depot.go b/pkg/runtime/depot.go new file mode 100644 index 0000000000..610418e952 --- /dev/null +++ b/pkg/runtime/depot.go @@ -0,0 +1,424 @@ +package runtime + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "runtime" + "sync" + + "github.com/go-openapi/strfmt" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/installation/storage" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/sliceutils" + "github.com/ActiveState/cli/internal/smartlink" +) + +const ( + depotFile = "depot.json" +) + +type depotConfig struct { + Deployments map[strfmt.UUID][]deployment `json:"deployments"` +} + +type deployment struct { + Type deploymentType `json:"type"` + Path string `json:"path"` + Files []string `json:"files"` + RelativeSrc string `json:"relativeSrc"` +} + +type deploymentType string + +const ( + deploymentTypeLink deploymentType = "link" + deploymentTypeCopy = "copy" +) + +type ErrVolumeMismatch struct { + DepotVolume string + PathVolume string +} + +func (e ErrVolumeMismatch) Error() string { + return fmt.Sprintf("volume mismatch: path volume is '%s', but depot volume is '%s'", e.PathVolume, e.DepotVolume) +} + +type depot struct { + config depotConfig + depotPath string + artifacts map[strfmt.UUID]struct{} + fsMutex *sync.Mutex +} + +func newDepot(runtimePath string) (*depot, error) { + depotPath := filepath.Join(storage.CachePath(), depotName) + + // Windows does not support hard-linking across drives, so determine if the runtime path is on a + // separate drive than the default depot path. If so, use a drive-specific depot path. + if runtime.GOOS == "windows" { + runtimeVolume := filepath.VolumeName(runtimePath) + storageVolume := filepath.VolumeName(storage.CachePath()) + if runtimeVolume != storageVolume { + depotPath = filepath.Join(runtimeVolume+"\\", "activestate", depotName) + } + } + + result := &depot{ + config: depotConfig{ + Deployments: map[strfmt.UUID][]deployment{}, + }, + depotPath: depotPath, + artifacts: map[strfmt.UUID]struct{}{}, + fsMutex: &sync.Mutex{}, + } + + if !fileutils.TargetExists(depotPath) { + return result, nil + } + + configFile := filepath.Join(depotPath, depotFile) + if fileutils.TargetExists(configFile) { + b, err := fileutils.ReadFile(configFile) + if err != nil { + return nil, errs.Wrap(err, "failed to read depot file") + } + if err := json.Unmarshal(b, &result.config); err != nil { + return nil, errs.Wrap(err, "failed to unmarshal depot file") + } + + // Filter out deployments that no longer exist (eg. user ran `state clean cache`) + for id, deployments := range result.config.Deployments { + if !fileutils.DirExists(result.Path(id)) { + delete(result.config.Deployments, id) + continue + } + result.config.Deployments[id] = sliceutils.Filter(deployments, func(d deployment) bool { + return someFilesExist(d.Files, d.Path) + }) + } + } + + files, err := os.ReadDir(depotPath) + if err != nil { + return nil, errs.Wrap(err, "failed to read depot path") + } + + for _, file := range files { + if !file.IsDir() { + continue + } + if strfmt.IsUUID(file.Name()) { + result.artifacts[strfmt.UUID(file.Name())] = struct{}{} + } + } + + return result, nil +} + +func (d *depot) Exists(id strfmt.UUID) bool { + _, ok := d.artifacts[id] + return ok +} + +func (d *depot) Path(id strfmt.UUID) string { + return filepath.Join(d.depotPath, id.String()) +} + +// Put updates our depot with the given artifact ID. It will fail unless a folder by that artifact ID can be found in +// the depot. +// This allows us to write to the depot externally, and then call this function in order for the depot to ingest the +// necessary information. Writing externally is preferred because otherwise the depot would need a lot of specialized +// logic that ultimately don't really need to be a concern of the depot. +func (d *depot) Put(id strfmt.UUID) error { + d.fsMutex.Lock() + defer d.fsMutex.Unlock() + + if !fileutils.TargetExists(d.Path(id)) { + return errs.New("could not put %s, as dir does not exist: %s", id, d.Path(id)) + } + d.artifacts[id] = struct{}{} + return nil +} + +// DeployViaLink will take an artifact from the depot and link it to the target path. +func (d *depot) DeployViaLink(id strfmt.UUID, relativeSrc, absoluteDest string) error { + d.fsMutex.Lock() + defer d.fsMutex.Unlock() + + if !d.Exists(id) { + return errs.New("artifact not found in depot") + } + + if err := d.validateVolume(absoluteDest); err != nil { + return errs.Wrap(err, "volume validation failed") + } + + // Collect artifact meta info + var err error + absoluteDest, err = fileutils.ResolvePath(absoluteDest) + if err != nil { + return errs.Wrap(err, "failed to resolve path") + } + + if err := fileutils.MkdirUnlessExists(absoluteDest); err != nil { + return errs.Wrap(err, "failed to create path") + } + + absoluteSrc := filepath.Join(d.Path(id), relativeSrc) + if !fileutils.DirExists(absoluteSrc) { + return errs.New("artifact src does not exist: %s", absoluteSrc) + } + + // Copy or link the artifact files, depending on whether the artifact in question relies on file transformations + if err := smartlink.LinkContents(absoluteSrc, absoluteDest); err != nil { + return errs.Wrap(err, "failed to link artifact") + } + + files, err := fileutils.ListDir(absoluteSrc, false) + if err != nil { + return errs.Wrap(err, "failed to list files") + } + + // Record deployment to config + if _, ok := d.config.Deployments[id]; !ok { + d.config.Deployments[id] = []deployment{} + } + d.config.Deployments[id] = append(d.config.Deployments[id], deployment{ + Type: deploymentTypeLink, + Path: absoluteDest, + Files: files.RelativePaths(), + RelativeSrc: relativeSrc, + }) + + return nil +} + +// DeployViaCopy will take an artifact from the depot and copy it to the target path. +func (d *depot) DeployViaCopy(id strfmt.UUID, relativeSrc, absoluteDest string) error { + d.fsMutex.Lock() + defer d.fsMutex.Unlock() + + if !d.Exists(id) { + return errs.New("artifact not found in depot") + } + + var err error + absoluteDest, err = fileutils.ResolvePath(absoluteDest) + if err != nil { + return errs.Wrap(err, "failed to resolve path") + } + + if err := d.validateVolume(absoluteDest); err != nil { + return errs.Wrap(err, "volume validation failed") + } + + if err := fileutils.MkdirUnlessExists(absoluteDest); err != nil { + return errs.Wrap(err, "failed to create path") + } + + absoluteSrc := filepath.Join(d.Path(id), relativeSrc) + if !fileutils.DirExists(absoluteSrc) { + return errs.New("artifact src does not exist: %s", absoluteSrc) + } + + // Copy or link the artifact files, depending on whether the artifact in question relies on file transformations + if err := fileutils.CopyFiles(absoluteSrc, absoluteDest); err != nil { + var errExist *fileutils.ErrAlreadyExist + if errors.As(err, &errExist) { + logging.Warning("Skipping files that already exist: " + errs.JoinMessage(errExist)) + } else { + return errs.Wrap(err, "failed to copy artifact") + } + } + + files, err := fileutils.ListDir(absoluteSrc, false) + if err != nil { + return errs.Wrap(err, "failed to list files") + } + + // Record deployment to config + if _, ok := d.config.Deployments[id]; !ok { + d.config.Deployments[id] = []deployment{} + } + d.config.Deployments[id] = append(d.config.Deployments[id], deployment{ + Type: deploymentTypeCopy, + Path: absoluteDest, + Files: files.RelativePaths(), + RelativeSrc: relativeSrc, + }) + + return nil +} + +func (d *depot) Undeploy(id strfmt.UUID, relativeSrc, path string) error { + d.fsMutex.Lock() + defer d.fsMutex.Unlock() + + if !d.Exists(id) { + return errs.New("artifact not found in depot") + } + + var err error + path, err = fileutils.ResolvePath(path) + if err != nil { + return errs.Wrap(err, "failed to resolve path") + } + + // Find record of our deployment + deployments, ok := d.config.Deployments[id] + if !ok { + return errs.New("deployment for %s not found in depot", id) + } + deployments = sliceutils.Filter(deployments, func(d deployment) bool { return d.Path == path }) + if len(deployments) != 1 { + return errs.New("no deployment found for %s in depot", path) + } + deploy := deployments[0] + + // Perform uninstall based on deployment type + if err := smartlink.UnlinkContents(filepath.Join(d.Path(id), relativeSrc), path); err != nil { + return errs.Wrap(err, "failed to unlink artifact") + } + + // Re-link or re-copy any files provided by other artifacts. + redeploys, err := d.getSharedFilesToRedeploy(id, deploy, path) + if err != nil { + return errs.Wrap(err, "failed to get shared files") + } + for sharedFile, relinkSrc := range redeploys { + switch deploy.Type { + case deploymentTypeLink: + if err := smartlink.Link(relinkSrc, sharedFile); err != nil { + return errs.Wrap(err, "failed to relink file") + } + case deploymentTypeCopy: + if err := fileutils.CopyFile(relinkSrc, sharedFile); err != nil { + return errs.Wrap(err, "failed to re-copy file") + } + } + } + + // Write changes to config + d.config.Deployments[id] = sliceutils.Filter(d.config.Deployments[id], func(d deployment) bool { return d.Path != path }) + + return nil +} + +func (d *depot) validateVolume(absoluteDest string) error { + if runtime.GOOS != "windows" { + return nil + } + + depotVolume := filepath.VolumeName(d.depotPath) + pathVolume := filepath.VolumeName(absoluteDest) + if pathVolume != depotVolume { + return &ErrVolumeMismatch{depotVolume, pathVolume} + } + + return nil +} + +// getSharedFilesToRedeploy returns a map of deployed files to re-link to (or re-copy from) another +// artifact that provides those files. The key is the deployed file path and the value is the +// source path from another artifact. +func (d *depot) getSharedFilesToRedeploy(id strfmt.UUID, deploy deployment, path string) (map[string]string, error) { + // Map of deployed paths to other sources that provides those paths. + redeploy := make(map[string]string, 0) + + // For each file deployed by this artifact, find another artifact (if any) that deploys its own copy. + for _, relativeDeployedFile := range deploy.Files { + deployedFile := filepath.Join(path, relativeDeployedFile) + for artifactId, artifactDeployments := range d.config.Deployments { + if artifactId == id { + continue + } + + findArtifact := func() bool { + for _, deployment := range artifactDeployments { + if deployment.Path != path { + continue // deployment is outside this one + } + for _, fileToDeploy := range deployment.Files { + if relativeDeployedFile != fileToDeploy { + continue + } + // We'll want to redeploy this from other artifact's copy after undeploying the currently deployed version. + newSrc := filepath.Join(d.Path(artifactId), deployment.RelativeSrc, relativeDeployedFile) + logging.Debug("More than one artifact provides '%s'", relativeDeployedFile) + logging.Debug("Will redeploy '%s' to '%s'", newSrc, deployedFile) + redeploy[deployedFile] = newSrc + return true + } + } + return false + } + + if findArtifact() { + break // ignore all other copies once one is found + } + } + } + + return redeploy, nil +} + +// Save will write config changes to disk (ie. links between depot artifacts and runtimes that use it). +// It will also delete any stale artifacts which are not used by any runtime. +func (d *depot) Save() error { + // Delete artifacts that are no longer used + for id := range d.artifacts { + if deployments, ok := d.config.Deployments[id]; !ok || len(deployments) == 0 { + if err := os.RemoveAll(d.Path(id)); err != nil { + return errs.Wrap(err, "failed to remove stale artifact") + } + } + } + + // Write config file changes to disk + configFile := filepath.Join(d.depotPath, depotFile) + b, err := json.Marshal(d.config) + if err != nil { + return errs.Wrap(err, "failed to marshal depot file") + } + if err := fileutils.WriteFile(configFile, b); err != nil { + return errs.Wrap(err, "failed to write depot file") + } + return nil +} + +func (d *depot) List(path string) map[strfmt.UUID]struct{} { + path = fileutils.ResolvePathIfPossible(path) + result := map[strfmt.UUID]struct{}{} + for id, deploys := range d.config.Deployments { + for _, p := range deploys { + if fileutils.ResolvePathIfPossible(p.Path) == path { + result[id] = struct{}{} + } + } + } + + return result +} + +// someFilesExist will check up to 10 files from the given filepaths, if any of them exist it returns true. +// This is a temporary workaround for https://activestatef.atlassian.net/browse/DX-2913 +// As of right now we cannot assert which artifact owns a given file, and so simply asserting if any one given file exists +// is inssuficient as an assertion. +func someFilesExist(filePaths []string, basePath string) bool { + for x, filePath := range filePaths { + if x == 10 { + break + } + if fileutils.TargetExists(filepath.Join(basePath, filePath)) { + return true + } + } + return false +} diff --git a/pkg/runtime/errors.go b/pkg/runtime/errors.go new file mode 100644 index 0000000000..7de15d14b5 --- /dev/null +++ b/pkg/runtime/errors.go @@ -0,0 +1,22 @@ +package runtime + +import ( + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/runtime/internal/buildlog" +) + +// ProgressReportError designates an error in the event handler for reporting progress. +type ProgressReportError struct { + *errs.WrapperError +} + +// buildlog aliases, because buildlog is internal +type ArtifactBuildError = buildlog.ArtifactBuildError +type BuildError = buildlog.BuildError + +// ArtifactCachedBuildFailed designates an error due to a build for an artifact that failed and has been cached +type ArtifactCachedBuildFailed struct { + *errs.WrapperError + Artifact *buildplan.Artifact +} diff --git a/pkg/runtime/events.go b/pkg/runtime/events.go new file mode 100644 index 0000000000..c0716b532f --- /dev/null +++ b/pkg/runtime/events.go @@ -0,0 +1,15 @@ +package runtime + +import ( + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/pkg/runtime/events" +) + +func (s *setup) fireEvent(ev events.Event) error { + for _, h := range s.opts.EventHandlers { + if err := h(ev); err != nil { + return errs.Wrap(err, "Event handler failed") + } + } + return nil +} diff --git a/pkg/platform/runtime/setup/events/events.go b/pkg/runtime/events/events.go similarity index 50% rename from pkg/platform/runtime/setup/events/events.go rename to pkg/runtime/events/events.go index 82d9546e88..9585c182b3 100644 --- a/pkg/platform/runtime/setup/events/events.go +++ b/pkg/runtime/events/events.go @@ -1,6 +1,7 @@ package events import ( + "github.com/ActiveState/cli/pkg/buildplan" "github.com/go-openapi/strfmt" ) @@ -10,14 +11,20 @@ The naming format of events should be in the form of []/ - // / - // artifact contents ... - // metadata.json - - // First: We need to identify the values for and - - var archiveName string - fs, err := os.ReadDir(tmpDir) +func NewEnvironmentDefinitions(rootDir string) (*envdef.EnvironmentDefinition, error) { + dirEntries, err := os.ReadDir(rootDir) if err != nil { - return nil, errs.Wrap(err, "Could not read temporary installation directory %s", tmpDir) + return nil, errs.Wrap(err, "Could not read directory") } - for _, f := range fs { - if f.IsDir() { - archiveName = f.Name() - } - } - if archiveName == "" { - return nil, errs.New("Expected sub-directory in extracted artifact tarball.") + if len(dirEntries) != 1 { + return nil, errs.New("Camel artifacts are expected to have a single directory at its root") } - tmpBaseDir := filepath.Join(tmpDir, archiveName) + baseDir := dirEntries[0].Name() + absoluteBaseDir := filepath.Join(rootDir, baseDir) - // parse the legacy metadata - md, err := InitMetaData(tmpBaseDir) + meta, err := newMetaData(absoluteBaseDir) if err != nil { - return nil, errs.Wrap(err, "Could not load meta data definitions for camel artifact.") + return nil, errs.Wrap(err, "Could not determine metadata") } - // convert file relocation commands into an envdef.FileTransform slice - transforms, err := convertToFileTransforms(tmpBaseDir, md.InstallDir, md) + fileTransforms, err := convertToFileTransforms(absoluteBaseDir, meta) if err != nil { - return nil, errs.Wrap(err, "Could not determine file transformations") - } - - // convert environment variables into an envdef.EnvironmentVariable slice - vars := convertToEnvVars(md) - - ed := &envdef.EnvironmentDefinition{ - InstallDir: filepath.Join(archiveName, md.InstallDir), - Transforms: transforms, - Env: vars, + return nil, errs.Wrap(err, "Could not determine file transforms") } - return ed, nil + return &envdef.EnvironmentDefinition{ + Env: convertToEnvVars(meta), + Transforms: fileTransforms, + InstallDir: filepath.Join(baseDir, meta.InstallDir), + }, nil } -func convertToEnvVars(metadata *MetaData) []envdef.EnvironmentVariable { +func convertToEnvVars(metadata *metaData) []envdef.EnvironmentVariable { var res []envdef.EnvironmentVariable if metadata.AffectedEnv != "" { res = append(res, envdef.EnvironmentVariable{ @@ -142,9 +105,9 @@ func paddingForBinaryFile(isBinary bool) *string { return &pad } -func convertToFileTransforms(tmpBaseDir string, relInstDir string, metadata *MetaData) ([]envdef.FileTransform, error) { +func convertToFileTransforms(tmpBaseDir string, metadata *metaData) ([]envdef.FileTransform, error) { var res []envdef.FileTransform - instDir := filepath.Join(tmpBaseDir, relInstDir) + instDir := filepath.Join(tmpBaseDir, metadata.InstallDir) for _, tr := range metadata.TargetedRelocations { // walk through files in tr.InDir and find files that need replacements. For those we create a FileTransform element trans, err := fileTransformsInDir(instDir, filepath.Join(instDir, tr.InDir), tr.SearchString, tr.Replacement, func(_ string, _ bool) bool { return true }) @@ -228,10 +191,3 @@ func fileTransformsInDir(instDir string, searchDir string, searchString string, }) return res, err } - -func (as *ArtifactSetup) Unarchiver() unarchiver.Unarchiver { - if runtime.GOOS == "windows" { - return unarchiver.NewZip() - } - return unarchiver.NewTarGz() -} diff --git a/pkg/platform/runtime/setup/implementations/camel/metadata.go b/pkg/runtime/internal/camel/metadata.go similarity index 69% rename from pkg/platform/runtime/setup/implementations/camel/metadata.go rename to pkg/runtime/internal/camel/metadata.go index c9462efaa5..71b0aca7d6 100644 --- a/pkg/platform/runtime/setup/implementations/camel/metadata.go +++ b/pkg/runtime/internal/camel/metadata.go @@ -6,16 +6,19 @@ import ( "path/filepath" "strings" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/logging" ) -type ErrMetaData struct{ *errs.WrapperError } +// runtimeInstallDirs represents the directory within a distribution archive where the distribution exists. +const runtimeInstallDirs = "INSTALLDIR,perl" -// TargetedRelocation is a relocation instruction for files in a specific directory -type TargetedRelocation struct { +// CamelRuntimeMetaFile is the json file that holds meta information about our runtime +const CamelRuntimeMetaFile = "metadata.json" + +// targetedRelocation is a relocation instruction for files in a specific directory +type targetedRelocation struct { // InDir is the directory in which files need to be relocated InDir string `json:"dir"` // SearchString to be replaced @@ -24,8 +27,8 @@ type TargetedRelocation struct { Replacement string `json:"replace"` } -// MetaData is used to parse the metadata.json file -type MetaData struct { +// metaData is used to parse the metadata.json file +type metaData struct { // InstallDir is the root directory of the artifact files that we need to copy on the user's machine InstallDir string @@ -39,7 +42,7 @@ type MetaData struct { PathListEnv map[string]string `json:"path_list_env"` // BinaryLocations are locations that we should add to the PATH - BinaryLocations []MetaDataBinary `json:"binaries_in"` + BinaryLocations []metaDataBinary `json:"binaries_in"` // RelocationDir is the string that we should replace with the actual install dir of the artifact RelocationDir string `json:"relocation_dir"` @@ -48,11 +51,11 @@ type MetaData struct { RelocationTargetBinaries string `json:"relocation_target_binaries"` // TargetedRelocations are relocations that only target specific parts of the installation - TargetedRelocations []TargetedRelocation `json:"custom_relocations"` + TargetedRelocations []targetedRelocation `json:"custom_relocations"` } -// MetaDataBinary is used to represent a binary path contained within the metadata.json file -type MetaDataBinary struct { +// metaDataBinary is used to represent a binary path contained within the metadata.json file +type metaDataBinary struct { Path string `json:"path"` Relative bool @@ -62,34 +65,34 @@ type MetaDataBinary struct { RelativeInt int `json:"relative"` } -// InitMetaData will create an instance of MetaData based on the metadata.json file found under the given artifact install dir -func InitMetaData(rootDir string) (*MetaData, error) { - var metaData *MetaData - metaFile := filepath.Join(rootDir, "support", constants.RuntimeMetaFile) +// newMetaData will create an instance of metaData based on the metadata.json file found under the given artifact install dir +func newMetaData(rootDir string) (*metaData, error) { + var md *metaData + metaFile := filepath.Join(rootDir, "support", CamelRuntimeMetaFile) if fileutils.FileExists(metaFile) { contents, err := fileutils.ReadFile(metaFile) if err != nil { return nil, err } - metaData, err = ParseMetaData(contents) + md, err = parseMetaData(contents) if err != nil { return nil, err } } else { - metaData = &MetaData{} + md = &metaData{} } - if metaData.Env == nil { - metaData.Env = map[string]string{} + if md.Env == nil { + md.Env = map[string]string{} } - if metaData.PathListEnv == nil { - metaData.PathListEnv = map[string]string{} + if md.PathListEnv == nil { + md.PathListEnv = map[string]string{} } var relInstallDir string - installDirs := strings.Split(constants.RuntimeInstallDirs, ",") + installDirs := strings.Split(runtimeInstallDirs, ",") for _, dir := range installDirs { if fileutils.DirExists(filepath.Join(rootDir, dir)) { relInstallDir = dir @@ -100,23 +103,23 @@ func InitMetaData(rootDir string) (*MetaData, error) { logging.Debug("Did not find an installation directory relative to metadata file.") } - metaData.InstallDir = relInstallDir - err := metaData.Prepare(filepath.Join(rootDir, relInstallDir)) + md.InstallDir = relInstallDir + err := md.Prepare(filepath.Join(rootDir, relInstallDir)) if err != nil { return nil, err } - return metaData, nil + return md, nil } -// ParseMetaData will parse the given bytes into the MetaData struct -func ParseMetaData(contents []byte) (*MetaData, error) { - metaData := &MetaData{ +// parseMetaData will parse the given bytes into the metaData struct +func parseMetaData(contents []byte) (*metaData, error) { + metaData := &metaData{ Env: make(map[string]string), } err := json.Unmarshal(contents, metaData) if err != nil { - return nil, &ErrMetaData{errs.Wrap(err, "Unmarshal failed")} + return nil, errs.Wrap(err, "Unmarshal failed") } // The JSON decoder does not recognize 0 and 1 as bools, so we have to get crafty @@ -127,7 +130,7 @@ func ParseMetaData(contents []byte) (*MetaData, error) { return metaData, nil } -func (m *MetaData) hasBinaryFile(root string, executable string) bool { +func (m *metaData) hasBinaryFile(root string, executable string) bool { for _, dir := range m.BinaryLocations { parent := "" if dir.Relative { @@ -142,7 +145,7 @@ func (m *MetaData) hasBinaryFile(root string, executable string) bool { return false } -func (m *MetaData) setPythonEnv() { +func (m *metaData) setPythonEnv() { // This is broken for two reasons: // 1. Checking in the OS environment will only happen on installation, but at a later point, the OS environment might have changed, and we will overwrite the user's choice here // 2. python code does not need to depend on PYTHONIOENCODING as pointed out here: https://stackoverflow.com/a/9942822 diff --git a/pkg/platform/runtime/setup/implementations/camel/metadata_test.go b/pkg/runtime/internal/camel/metadata_test.go similarity index 86% rename from pkg/platform/runtime/setup/implementations/camel/metadata_test.go rename to pkg/runtime/internal/camel/metadata_test.go index ec954b0d7a..d8edff9edf 100644 --- a/pkg/platform/runtime/setup/implementations/camel/metadata_test.go +++ b/pkg/runtime/internal/camel/metadata_test.go @@ -1,11 +1,10 @@ -package camel_test +package camel import ( "os" "testing" "github.com/ActiveState/cli/internal/testhelpers/suite" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/implementations/camel" ) type MetaDataTestSuite struct { @@ -37,7 +36,7 @@ func (suite *MetaDataTestSuite) TestMetaData() { "relocation_dir": "/relocate" }` - metaData, err := camel.ParseMetaData([]byte(contents)) + metaData, err := parseMetaData([]byte(contents)) suite.Require().NoError(err) suite.Equal("PYTHONPATH", metaData.AffectedEnv) suite.Equal("/relocate", metaData.RelocationDir) diff --git a/pkg/platform/runtime/setup/implementations/camel/prepare_lin_win.go b/pkg/runtime/internal/camel/prepare_lin_win.go similarity index 93% rename from pkg/platform/runtime/setup/implementations/camel/prepare_lin_win.go rename to pkg/runtime/internal/camel/prepare_lin_win.go index d1239eaa17..920daee8be 100644 --- a/pkg/platform/runtime/setup/implementations/camel/prepare_lin_win.go +++ b/pkg/runtime/internal/camel/prepare_lin_win.go @@ -13,11 +13,11 @@ import ( // Prepare will assume the LibLocation in cases where the metadata // doesn't contain it and we know what it should be -func (m *MetaData) Prepare(installRoot string) error { +func (m *metaData) Prepare(installRoot string) error { // BinaryLocations if m.BinaryLocations == nil || len(m.BinaryLocations) == 0 { - m.BinaryLocations = []MetaDataBinary{ - MetaDataBinary{ + m.BinaryLocations = []metaDataBinary{ + metaDataBinary{ Path: "bin", Relative: true, }, @@ -46,7 +46,7 @@ func (m *MetaData) Prepare(installRoot string) error { // Env m.setPythonEnv() - //Perl + // Perl } else if m.hasBinaryFile(installRoot, constants.ActivePerlExecutable) { logging.Debug("Detected Perl artifact, ensuring backwards compatibility") diff --git a/pkg/platform/runtime/setup/implementations/camel/prepare_lin_win_test.go b/pkg/runtime/internal/camel/prepare_lin_win_test.go similarity index 86% rename from pkg/platform/runtime/setup/implementations/camel/prepare_lin_win_test.go rename to pkg/runtime/internal/camel/prepare_lin_win_test.go index 5c193d6423..48dfdd9645 100644 --- a/pkg/platform/runtime/setup/implementations/camel/prepare_lin_win_test.go +++ b/pkg/runtime/internal/camel/prepare_lin_win_test.go @@ -1,6 +1,7 @@ +//go:build !darwin // +build !darwin -package camel_test +package camel import ( "fmt" @@ -10,7 +11,6 @@ import ( "strings" "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/implementations/camel" ) func (suite *MetaDataTestSuite) TestMetaData_Prepare() { @@ -41,7 +41,7 @@ func (suite *MetaDataTestSuite) TestMetaData_Prepare() { suite.Require().NoError(err) contents := fmt.Sprintf(template, tempDir) - metaData, err := camel.ParseMetaData([]byte(contents)) + metaData, err := parseMetaData([]byte(contents)) suite.Require().NoError(err) err = metaData.Prepare(suite.dir) diff --git a/pkg/platform/runtime/setup/implementations/camel/prepare_mac.go b/pkg/runtime/internal/camel/prepare_mac.go similarity index 94% rename from pkg/platform/runtime/setup/implementations/camel/prepare_mac.go rename to pkg/runtime/internal/camel/prepare_mac.go index 267559e3ff..bc6750381f 100644 --- a/pkg/platform/runtime/setup/implementations/camel/prepare_mac.go +++ b/pkg/runtime/internal/camel/prepare_mac.go @@ -18,9 +18,9 @@ import ( // Prepare ensures Metadata can handle Python runtimes on MacOS. // These runtimes do not include metadata files as they should // be runnable from where they are unarchived -func (m *MetaData) Prepare(installRoot string) error { +func (m *metaData) Prepare(installRoot string) error { frameWorkDir := "Library/Frameworks/Python.framework/Versions/" - m.BinaryLocations = []MetaDataBinary{ + m.BinaryLocations = []metaDataBinary{ { Path: filepath.Join(frameWorkDir, "Current", "bin"), Relative: true, @@ -86,7 +86,7 @@ func (m *MetaData) Prepare(installRoot string) error { return errs.New("could not find path %s/x.x in build artifact", frameWorkDir) } - m.TargetedRelocations = []TargetedRelocation{TargetedRelocation{ + m.TargetedRelocations = []targetedRelocation{targetedRelocation{ InDir: filepath.Join(frameWorkDir, "Current", "bin"), SearchString: "#!" + filepath.Join("/", relVersionedFrameWorkDir), Replacement: "#!" + filepath.Join("${INSTALLDIR}", relVersionedFrameWorkDir), diff --git a/pkg/platform/runtime/setup/implementations/camel/prepare_mac_test.go b/pkg/runtime/internal/camel/prepare_mac_test.go similarity index 90% rename from pkg/platform/runtime/setup/implementations/camel/prepare_mac_test.go rename to pkg/runtime/internal/camel/prepare_mac_test.go index 8a788fd687..2956054d9f 100644 --- a/pkg/platform/runtime/setup/implementations/camel/prepare_mac_test.go +++ b/pkg/runtime/internal/camel/prepare_mac_test.go @@ -1,6 +1,7 @@ +//go:build darwin // +build darwin -package camel_test +package camel import ( "fmt" @@ -8,7 +9,6 @@ import ( "path/filepath" "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/pkg/platform/runtime/setup/implementations/camel" ) func (suite *MetaDataTestSuite) TestMetaData_Prepare() { @@ -50,7 +50,7 @@ func (suite *MetaDataTestSuite) TestMetaData_Prepare() { suite.Require().NoError(err) contents := fmt.Sprintf(template, tempDir) - metaData, err := camel.ParseMetaData([]byte(contents)) + metaData, err := parseMetaData([]byte(contents)) suite.Require().NoError(err) err = metaData.Prepare(suite.dir) @@ -58,7 +58,7 @@ func (suite *MetaDataTestSuite) TestMetaData_Prepare() { suite.Assert().NotEmpty(metaData.Env["PYTHONIOENCODING"]) suite.Len(metaData.TargetedRelocations, 1, "expected one targeted relocation") - suite.Equal(camel.TargetedRelocation{ + suite.Equal(targetedRelocation{ InDir: relBinDir, SearchString: "#!" + filepath.Join("/", relVersionedDir), Replacement: "#!" + filepath.Join("${INSTALLDIR}", relVersionedDir), diff --git a/pkg/runtime/internal/envdef/collection.go b/pkg/runtime/internal/envdef/collection.go new file mode 100644 index 0000000000..3801ff4ba7 --- /dev/null +++ b/pkg/runtime/internal/envdef/collection.go @@ -0,0 +1,67 @@ +package envdef + +import ( + "path/filepath" + "sync" + + "github.com/ActiveState/cli/internal/errs" +) + +// EnvironmentDefinitionFilename is the filename for runtime meta data bundled with artifacts, if they are built by the alternative builder +const EnvironmentDefinitionFilename = "runtime.json" + +type raw struct { + EnvDefs map[string]*EnvironmentDefinition `json:"Definitions"` +} + +type Collection struct { + raw *raw // We use the raw struct so as to not directly expose the parsed JSON data to consumers + mutex *sync.Mutex +} + +var ErrFileNotFound = errs.New("Environment definition file not found") + +func New() *Collection { + return &Collection{&raw{EnvDefs: map[string]*EnvironmentDefinition{}}, &sync.Mutex{}} +} + +func (c *Collection) Load(path string) (*EnvironmentDefinition, error) { + envDef, err := NewEnvironmentDefinition(filepath.Join(path, EnvironmentDefinitionFilename)) + if err != nil { + return nil, errs.Wrap(err, "Failed to initialize environment definition") + } + + // Prevent concurrent writes + c.mutex.Lock() + defer c.mutex.Unlock() + + c.raw.EnvDefs[path] = envDef + return envDef, nil +} + +func (c *Collection) Unload(path string) error { + // Prevent concurrent reads and writes + c.mutex.Lock() + defer c.mutex.Unlock() + + if _, ok := c.raw.EnvDefs[path]; !ok { + return errs.New("Environment definition not found for path: %s", path) + } + + delete(c.raw.EnvDefs, path) + + return nil +} + +func (c *Collection) Environment(installPath string, inherit bool) (map[string]string, error) { + result := &EnvironmentDefinition{} + var err error + for _, envDef := range c.raw.EnvDefs { + result, err = result.Merge(envDef) + if err != nil { + return nil, errs.Wrap(err, "Failed to merge environment definitions") + } + } + constants := NewConstants(installPath) + return result.ExpandVariables(constants).GetEnv(inherit), nil +} diff --git a/pkg/platform/runtime/envdef/constants.go b/pkg/runtime/internal/envdef/constants.go similarity index 52% rename from pkg/platform/runtime/envdef/constants.go rename to pkg/runtime/internal/envdef/constants.go index d115247d21..a345f76eb6 100644 --- a/pkg/platform/runtime/envdef/constants.go +++ b/pkg/runtime/internal/envdef/constants.go @@ -1,22 +1,12 @@ package envdef -import ( - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/fileutils" -) - // Constants is a map of constants that are being expanded in environment variables and file transformations to their installation-specific values type Constants map[string]string // NewConstants initializes a new map of constants that will need to be set to installation-specific values // Currently it only has one field `INSTALLDIR` -func NewConstants(installdir string) (Constants, error) { - dir, err := fileutils.CaseSensitivePath(installdir) - if err != nil { - return nil, errs.Wrap(err, "Could not search for case sensitive install dir") - } - +func NewConstants(installdir string) Constants { return map[string]string{ - `INSTALLDIR`: dir, - }, nil + `INSTALLDIR`: installdir, + } } diff --git a/pkg/platform/runtime/envdef/environment.go b/pkg/runtime/internal/envdef/environment.go similarity index 77% rename from pkg/platform/runtime/envdef/environment.go rename to pkg/runtime/internal/envdef/environment.go index 4d75ff41e1..1a1eb771bb 100644 --- a/pkg/platform/runtime/envdef/environment.go +++ b/pkg/runtime/internal/envdef/environment.go @@ -3,16 +3,19 @@ package envdef import ( "encoding/json" "fmt" + "maps" "os" "path/filepath" + "runtime" "strings" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/osutils" + "github.com/ActiveState/cli/internal/sliceutils" "github.com/thoas/go-funk" "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/locale" ) // EnvironmentDefinition provides all the information needed to set up an @@ -28,6 +31,18 @@ type EnvironmentDefinition struct { InstallDir string `json:"installdir"` } +func (e *EnvironmentDefinition) Save(path string) error { + path = filepath.Join(path, EnvironmentDefinitionFilename) + b, err := json.Marshal(e) + if err != nil { + return errs.Wrap(err, "Could not marshal environment definition") + } + if err := fileutils.WriteFile(path, b); err != nil { + return errs.Wrap(err, "Could not write environment definition file") + } + return nil +} + // EnvironmentVariable defines a single environment variable and its values type EnvironmentVariable struct { Name string `json:"env_name"` @@ -50,9 +65,13 @@ const ( ) // MarshalText marshals a join directive for environment variables -func (j VariableJoin) MarshalText() ([]byte, error) { +func (j *VariableJoin) MarshalText() ([]byte, error) { + if j == nil { + return nil, errs.New("MarshalText called on nil pointer") + } + var res string - switch j { + switch *j { default: res = "prepend" case Append: @@ -102,13 +121,27 @@ func (ev *EnvironmentVariable) UnmarshalJSON(data []byte) error { func NewEnvironmentDefinition(fp string) (*EnvironmentDefinition, error) { blob, err := os.ReadFile(fp) if err != nil { - return nil, locale.WrapError(err, "envdef_file_not_found", "", fp) + return nil, errs.Wrap(err, "could not read environment definition file: %s", fp) } ed := &EnvironmentDefinition{} err = json.Unmarshal(blob, ed) if err != nil { - return nil, locale.WrapError(err, "envdef_unmarshal_error", "", fp) + return nil, errs.Wrap(err, "could not unmarshal environment definition file: %s", fp) + } + + if ignores := os.Getenv(constants.IgnoreEnvEnvVarName); ignores != "" { + ignore := make(map[string]bool) + for _, name := range strings.Split(ignores, ",") { + ignore[name] = true + } + + // Remove any environment variables to ignore. + ed.Env = sliceutils.Filter(ed.Env, func(e EnvironmentVariable) bool { + _, exists := ignore[e.Name] + return !exists + }) } + return ed, nil } @@ -121,7 +154,7 @@ func (ed *EnvironmentDefinition) WriteFile(filepath string) error { return os.WriteFile(filepath, blob, 0666) } -// WriteFile marshals an environment definition to a file +// Marshal marshals an environment definition to a file func (ed *EnvironmentDefinition) Marshal() ([]byte, error) { blob, err := json.MarshalIndent(ed, "", " ") if err != nil { @@ -159,8 +192,8 @@ func (ed *EnvironmentDefinition) ReplaceString(from string, replacement string) // EnvironmentVariable.Merge() and added to the result // - Environment variables that are defined in only one of the two definitions, // are added to the result directly -func (ed EnvironmentDefinition) Merge(other *EnvironmentDefinition) (*EnvironmentDefinition, error) { - res := ed +func (ed *EnvironmentDefinition) Merge(other *EnvironmentDefinition) (*EnvironmentDefinition, error) { + res := *ed if other == nil { return &res, nil } @@ -208,12 +241,12 @@ func (ed EnvironmentDefinition) Merge(other *EnvironmentDefinition) (*Environmen // ReplaceString replaces the string 'from' with 'replacement' in // environment variable values -func (ev EnvironmentVariable) ReplaceString(from string, replacement string) EnvironmentVariable { - res := ev +func (ev *EnvironmentVariable) ReplaceString(from string, replacement string) EnvironmentVariable { + res := *ev values := make([]string, 0, len(ev.Values)) for _, v := range ev.Values { - values = append(values, strings.ReplaceAll(v, "${INSTALLDIR}", replacement)) + values = append(values, strings.ReplaceAll(v, from, replacement)) } res.Values = values return res @@ -226,8 +259,8 @@ func (ev EnvironmentVariable) ReplaceString(from string, replacement string) Env // If join strategy is set to "disallowed", the variables need to have exactly // one value, and both merged values need to be identical, otherwise an error is // returned. -func (ev EnvironmentVariable) Merge(other EnvironmentVariable) (*EnvironmentVariable, error) { - res := ev +func (ev *EnvironmentVariable) Merge(other EnvironmentVariable) (*EnvironmentVariable, error) { + res := *ev // separators and inherit strategy always need to match for two merged variables if ev.Separator != other.Separator || ev.Inherit != other.Inherit { @@ -246,7 +279,7 @@ func (ev EnvironmentVariable) Merge(other EnvironmentVariable) (*EnvironmentVari res.Values = filterValuesUniquely(append(ev.Values, other.Values...), false) case Disallowed: if len(ev.Values) != 1 || len(other.Values) != 1 || (ev.Values[0] != other.Values[0]) { - sep := string(ev.Separator) + sep := ev.Separator // It's possible that the merged env vars will still be equal, so only error if they are not. if strings.Join(ev.Values, sep) != strings.Join(other.Values, sep) { return nil, fmt.Errorf( @@ -309,22 +342,43 @@ func filterValuesUniquely(values []string, keepFirst bool) []string { func (ev *EnvironmentVariable) ValueString() string { return strings.Join( filterValuesUniquely(ev.Values, ev.Join == Prepend), - string(ev.Separator)) + ev.Separator) } -// GetEnvBasedOn returns the environment variable names and values defined by +// getEnvBasedOn returns the environment variable names and values defined by // the EnvironmentDefinition. // If an environment variable is configured to inherit from the base // environment (`Inherit==true`), the base environment defined by the // `envLookup` method is joined with these environment variables. // This function is mostly used for testing. Use GetEnv() in production. -func (ed *EnvironmentDefinition) GetEnvBasedOn(envLookup func(string) (string, bool)) (map[string]string, error) { - res := map[string]string{} +func (ed *EnvironmentDefinition) getEnvBasedOn(envLookup map[string]string) (map[string]string, error) { + res := maps.Clone(envLookup) + + // On Windows, environment variable names are case-insensitive. + // For example, it uses "Path", but responds to "PATH" as well. + // This causes trouble with our environment merging, which will end up adding "PATH" (with the + // correct value) alongside "Path" (with the old value). + // In order to remedy this, track the OS-specific environment variable name and if it's + // modified/merged, replace it with our version (e.g. "Path" -> "PATH"). We do not use the OS name + // because we assume ours is the one that's used elsewhere in the codebase, and Windows will + // properly respond to a changed-case name anyway. + osEnvNames := map[string]string{} + if runtime.GOOS == "windows" { + for k := range envLookup { + osEnvNames[strings.ToLower(k)] = k + } + } for _, ev := range ed.Env { pev := &ev + osName := pev.Name + if runtime.GOOS == "windows" { + if name, ok := osEnvNames[strings.ToLower(osName)]; ok { + osName = name + } + } + osValue, hasOsValue := envLookup[osName] if pev.Inherit { - osValue, hasOsValue := envLookup(pev.Name) if hasOsValue { osEv := ev osEv.Values = []string{osValue} @@ -332,15 +386,21 @@ func (ed *EnvironmentDefinition) GetEnvBasedOn(envLookup func(string) (string, b pev, err = osEv.Merge(ev) if err != nil { return nil, err - } } - } else if _, hasOsValue := os.LookupEnv(pev.Name); hasOsValue { + } else if hasOsValue { res[pev.Name] = "" // unset } // only add environment variable if at least one value is set (This allows us to remove variables from the environment.) if len(ev.Values) > 0 { res[pev.Name] = pev.ValueString() + if pev.Name != osName { + // On Windows, delete the redundant (case-insensitive) version that our case-sensitive + // version could conflict with. (Our version has already processed the value of the + // redundant version.) + // For example, delete "Path" while preserving our "PATH". + delete(res, osName) + } } } return res, nil @@ -352,11 +412,11 @@ func (ed *EnvironmentDefinition) GetEnvBasedOn(envLookup func(string) (string, b // environment (`Inherit==true`), the base environment defined by the // `envLookup` method is joined with these environment variables. func (ed *EnvironmentDefinition) GetEnv(inherit bool) map[string]string { - lookupEnv := os.LookupEnv - if !inherit { - lookupEnv = func(_ string) (string, bool) { return "", false } + lookupEnv := map[string]string{} + if inherit { + lookupEnv = osutils.EnvSliceToMap(os.Environ()) } - res, err := ed.GetEnvBasedOn(lookupEnv) + res, err := ed.getEnvBasedOn(lookupEnv) if err != nil { panic(fmt.Sprintf("Could not inherit OS environment variable: %v", err)) } @@ -443,3 +503,11 @@ func (ed *EnvironmentDefinition) FindBinPathFor(executable string) string { } return "" } + +func (ed *EnvironmentDefinition) NeedsTransforms() bool { + return len(ed.Transforms) > 0 +} + +func (ed *EnvironmentDefinition) InstallationDir() string { + return ed.InstallDir +} diff --git a/pkg/platform/runtime/envdef/environment_test.go b/pkg/runtime/internal/envdef/environment_test.go similarity index 82% rename from pkg/platform/runtime/envdef/environment_test.go rename to pkg/runtime/internal/envdef/environment_test.go index 9e10762167..3741d5d393 100644 --- a/pkg/platform/runtime/envdef/environment_test.go +++ b/pkg/runtime/internal/envdef/environment_test.go @@ -1,4 +1,4 @@ -package envdef_test +package envdef import ( "encoding/json" @@ -7,11 +7,11 @@ import ( "strings" "testing" + "github.com/ActiveState/cli/internal/osutils" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/stretchr/testify/require" "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/pkg/platform/runtime/envdef" ) type EnvironmentTestSuite struct { @@ -20,20 +20,20 @@ type EnvironmentTestSuite struct { func (suite *EnvironmentTestSuite) TestMergeVariables() { - ev1 := envdef.EnvironmentVariable{} + ev1 := EnvironmentVariable{} err := json.Unmarshal([]byte(`{ "env_name": "V", "values": ["a", "b"] }`), &ev1) require.NoError(suite.T(), err) - ev2 := envdef.EnvironmentVariable{} + ev2 := EnvironmentVariable{} err = json.Unmarshal([]byte(`{ "env_name": "V", "values": ["b", "c"] }`), &ev2) require.NoError(suite.T(), err) - expected := &envdef.EnvironmentVariable{} + expected := &EnvironmentVariable{} err = json.Unmarshal([]byte(`{ "env_name": "V", "values": ["b", "c", "a"], @@ -50,7 +50,7 @@ func (suite *EnvironmentTestSuite) TestMergeVariables() { } func (suite *EnvironmentTestSuite) TestMerge() { - ed1 := &envdef.EnvironmentDefinition{} + ed1 := &EnvironmentDefinition{} err := json.Unmarshal([]byte(`{ "env": [{"env_name": "V", "values": ["a", "b"]}], @@ -58,14 +58,14 @@ func (suite *EnvironmentTestSuite) TestMerge() { }`), ed1) require.NoError(suite.T(), err) - ed2 := envdef.EnvironmentDefinition{} + ed2 := EnvironmentDefinition{} err = json.Unmarshal([]byte(`{ "env": [{"env_name": "V", "values": ["c", "d"]}], "installdir": "abc" }`), &ed2) require.NoError(suite.T(), err) - expected := envdef.EnvironmentDefinition{} + expected := EnvironmentDefinition{} err = json.Unmarshal([]byte(`{ "env": [{"env_name": "V", "values": ["c", "d", "a", "b"]}], "installdir": "abc" @@ -79,7 +79,7 @@ func (suite *EnvironmentTestSuite) TestMerge() { } func (suite *EnvironmentTestSuite) TestInheritPath() { - ed1 := &envdef.EnvironmentDefinition{} + ed1 := &EnvironmentDefinition{} err := json.Unmarshal([]byte(`{ "env": [{"env_name": "PATH", "values": ["NEWVALUE"]}], @@ -89,9 +89,7 @@ func (suite *EnvironmentTestSuite) TestInheritPath() { }`), ed1) require.NoError(suite.T(), err) - env, err := ed1.GetEnvBasedOn(func(k string) (string, bool) { - return "OLDVALUE", true - }) + env, err := ed1.getEnvBasedOn(map[string]string{"PATH": "OLDVALUE"}) require.NoError(suite.T(), err) suite.True(strings.HasPrefix(env["PATH"], "NEWVALUE"), "%s does not start with NEWVALUE", env["PATH"]) suite.True(strings.HasSuffix(env["PATH"], "OLDVALUE"), "%s does not end with OLDVALUE", env["PATH"]) @@ -100,11 +98,11 @@ func (suite *EnvironmentTestSuite) TestInheritPath() { func (suite *EnvironmentTestSuite) TestSharedTests() { type testCase struct { - Name string `json:"name"` - Definitions []envdef.EnvironmentDefinition `json:"definitions"` - BaseEnv map[string]string `json:"base_env"` - Expected map[string]string `json:"result"` - IsError bool `json:"error"` + Name string `json:"name"` + Definitions []EnvironmentDefinition `json:"definitions"` + BaseEnv map[string]string `json:"base_env"` + Expected map[string]string `json:"result"` + IsError bool `json:"error"` } td, err := os.ReadFile("runtime_test_cases.json") @@ -127,12 +125,7 @@ func (suite *EnvironmentTestSuite) TestSharedTests() { suite.Assert().NoError(err, "error merging %d-th definition", i) } - lookupEnv := func(k string) (string, bool) { - res, ok := tc.BaseEnv[k] - return res, ok - } - - res, err := ed.GetEnvBasedOn(lookupEnv) + res, err := ed.getEnvBasedOn(tc.BaseEnv) if tc.IsError { suite.Assert().Error(err) return @@ -145,7 +138,7 @@ func (suite *EnvironmentTestSuite) TestSharedTests() { } func (suite *EnvironmentTestSuite) TestValueString() { - ev1 := envdef.EnvironmentVariable{} + ev1 := EnvironmentVariable{} err := json.Unmarshal([]byte(`{ "env_name": "V", "values": ["a", "b"] @@ -157,17 +150,25 @@ func (suite *EnvironmentTestSuite) TestValueString() { } func (suite *EnvironmentTestSuite) TestGetEnv() { - ed1 := envdef.EnvironmentDefinition{} + ed1 := EnvironmentDefinition{} err := json.Unmarshal([]byte(`{ "env": [{"env_name": "V", "values": ["a", "b"]}], "installdir": "abc" }`), &ed1) require.NoError(suite.T(), err) - res := ed1.GetEnv(true) + res := ed1.GetEnv(false) suite.Assert().Equal(map[string]string{ "V": "a:b", }, res) + + res = ed1.GetEnv(true) + suite.Require().Contains(res, "V") + suite.Assert().Equal(res["V"], "a:b") + for k, v := range osutils.EnvSliceToMap(os.Environ()) { + suite.Require().Contains(res, k) + suite.Assert().Equal(res[k], v) + } } func (suite *EnvironmentTestSuite) TestFindBinPathFor() { @@ -175,7 +176,7 @@ func (suite *EnvironmentTestSuite) TestFindBinPathFor() { require.NoError(suite.T(), err, "creating temporary directory") defer os.RemoveAll(tmpDir) - ed1 := envdef.EnvironmentDefinition{} + ed1 := EnvironmentDefinition{} err = json.Unmarshal([]byte(`{ "env": [{"env_name": "PATH", "values": ["${INSTALLDIR}/bin", "${INSTALLDIR}/bin2"]}], "installdir": "abc" @@ -185,8 +186,7 @@ func (suite *EnvironmentTestSuite) TestFindBinPathFor() { tmpDir, err = fileutils.GetLongPathName(tmpDir) require.NoError(suite.T(), err) - constants, err := envdef.NewConstants(tmpDir) - require.NoError(suite.T(), err) + constants := NewConstants(tmpDir) // expand variables ed1.ExpandVariables(constants) @@ -247,7 +247,7 @@ func TestFilterPATH(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - envdef.FilterPATH(tt.args.env, tt.args.excludes...) + FilterPATH(tt.args.env, tt.args.excludes...) require.Equal(t, tt.want, tt.args.env["PATH"]) }) } diff --git a/pkg/platform/runtime/envdef/file_transform.go b/pkg/runtime/internal/envdef/file_transform.go similarity index 97% rename from pkg/platform/runtime/envdef/file_transform.go rename to pkg/runtime/internal/envdef/file_transform.go index f11216000b..afb6810473 100644 --- a/pkg/platform/runtime/envdef/file_transform.go +++ b/pkg/runtime/internal/envdef/file_transform.go @@ -136,11 +136,13 @@ func (ft *FileTransform) ApplyTransform(baseDir string, constants Constants) err } // ApplyFileTransforms applies all file transformations to the files in the base directory -func (ed *EnvironmentDefinition) ApplyFileTransforms(installDir string, constants Constants) error { +func (ed *EnvironmentDefinition) ApplyFileTransforms(installDir string) error { + constants := NewConstants(installDir) + for _, ft := range ed.Transforms { err := ft.ApplyTransform(installDir, constants) if err != nil { - return err + return errs.Wrap(err, "transformation failed") } } return nil diff --git a/pkg/platform/runtime/envdef/file_transform_test.go b/pkg/runtime/internal/envdef/file_transform_test.go similarity index 96% rename from pkg/platform/runtime/envdef/file_transform_test.go rename to pkg/runtime/internal/envdef/file_transform_test.go index 2c56cbc638..ca046c7e5d 100644 --- a/pkg/platform/runtime/envdef/file_transform_test.go +++ b/pkg/runtime/internal/envdef/file_transform_test.go @@ -63,9 +63,7 @@ func TestApplyConstTransforms(t *testing.T) { dir, err = fileutils.GetLongPathName(dir) assert.NoError(t, err) - cs, err := NewConstants(dir) - assert.NoError(t, err) - assert.NoError(t, err) + cs := NewConstants(dir) cases := []struct { Name string diff --git a/pkg/runtime/internal/envdef/readme.md b/pkg/runtime/internal/envdef/readme.md new file mode 100644 index 0000000000..2fbc67c60a --- /dev/null +++ b/pkg/runtime/internal/envdef/readme.md @@ -0,0 +1,105 @@ +Package envdef implements a parser for the runtime environment for alternative builds + +Builds that are built with the alternative build environment, include runtime.json files that define which environment +variables need to be set to install and use the provided artifacts. +The schema of this file can be downloaded [here](https://drive.google.com/drive/u/0/my-drive) + +The same parser and interpreter also exists +in [TheHomeRepot](https://github.com/ActiveState/TheHomeRepot/blob/master/service/build-wrapper/wrapper/runtime.py) + +Changes to the runtime environment definition schema should be synchronized between these two places. For now, this can +be most easily accomplished by keeping the description of test cases in +the [cli repo](https://github.com/ActiveState/cli/blob/master/pkg/platform/runtime/envdef/runtime_test_cases.json) +and [TheHomeRepot](https://github.com/ActiveState/TheHomeRepot/blob/master/service/build-wrapper/runtime_test_cases.json) +in sync. + +Examples: + +## Define a PATH and LD_LIBRARY_PATH variable + +Assuming the runtime is installed to a directory `/home/user/.cache/installdir`, the following definition asks to set +the PATH variables to`/home/user/.cache/installdir/bin:/home/user/.cache/installdir/usr/bin` and`LD_LIBRARY_PATH` +to`/home/user/.cache/installdir/lib`The set `inherit` flag on the `PATH` variable ensures that the `PATH` value is +prepended to the existing `PATH` that is already set in the environment. + +```json +{ + "env": [ + { + "env_name": "PATH", + "values": [ + "${INSTALLDIR}/bin", + "${INSTALLDIR}/usr/bin" + ], + "join": "prepend", + "inherit": true, + "separator": ":" + }, + { + "env_name": "LD_LIBRARY_PATH", + "values": [ + "${INSTALLDIR}/lib" + ], + "join": "prepend", + "inherit": false, + "separator": ":" + } + ], + "installdir": "installdir" +} +``` + +The installdir is used during the unpacking step to identify the directory inside the artifact tarball that needs to be +unpacked to `/home/user/.cache/installdir` + +## Joining two definitions + +Assume we have a second environment definition file exists with the following contents: + +```json +{ + "env": [ + { + "env_name": "PATH", + "values": [ + "${INSTALLDIR}/bin", + "${INSTALLDIR}/usr/local/bin" + ], + "join": "prepend", + "inherit": true, + "separator": ":" + }, + { + "env_name": "LD_LIBRARY_PATH", + "values": [ + "${INSTALLDIR}/lib", + "${INSTALLDIR}/lib64" + ], + "join": "prepend", + "inherit": false, + "separator": ":" + } + ], + "installdir": "installdir" +} +``` + +Merging this environment definition into the previous one sets the `PATH` +to `/home/user/.cache/installdir/bin:/home/user/.cache/installdir/usr/local/bin:/home/user/.cache/installdir/usr/bin`. +Note, that duplicate values are filtered out. Likewise the `LD_LIBRARY_PATH` will end up +as `/home/user/.cache/installdir/lib:/home/user/.cache/installdir/lib64` + +In this example, the values were joined by prepending the second definition to the first. Other join strategies +are `append` and `disallowed`. + +The `disallowed` join strategy can be used if a variable should have only ONE value, and this value needs to be the same +or undefined between all artifacts +that depend on it. + +## Usage + +- Environment definition files can be parsed from a file with the `NewEnvironmentDefinition()` function. +- Two environment definitions `ed1` and `ed2` can be merged like so: + ed1.Merge(ed2) +- Once the installation directory is specified, the variable values can be expanded: + ed.ExpandVariables("/home/user/.cache/installdir") diff --git a/pkg/platform/runtime/envdef/runtime_test_cases.json b/pkg/runtime/internal/envdef/runtime_test_cases.json similarity index 99% rename from pkg/platform/runtime/envdef/runtime_test_cases.json rename to pkg/runtime/internal/envdef/runtime_test_cases.json index 10225c7b0b..e0e554e31d 100644 --- a/pkg/platform/runtime/envdef/runtime_test_cases.json +++ b/pkg/runtime/internal/envdef/runtime_test_cases.json @@ -275,7 +275,8 @@ "B": "ba|bb|bc", "C": "ca", "D": "da", - "E": "ea" + "E": "ea", + "OTHER": "something" } } ] diff --git a/pkg/runtime/links_unix.go b/pkg/runtime/links_unix.go new file mode 100644 index 0000000000..a6ef37da62 --- /dev/null +++ b/pkg/runtime/links_unix.go @@ -0,0 +1,8 @@ +//go:build linux || darwin +// +build linux darwin + +package runtime + +func supportsHardLinks(path string) bool { + return true +} diff --git a/pkg/runtime/links_windows.go b/pkg/runtime/links_windows.go new file mode 100644 index 0000000000..0bdbbe79e8 --- /dev/null +++ b/pkg/runtime/links_windows.go @@ -0,0 +1,57 @@ +package runtime + +import ( + "os" + "path/filepath" + + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/multilog" + "github.com/ActiveState/cli/internal/smartlink" +) + +const linkTarget = "__target__" +const link = "__link__" + +func supportsHardLinks(path string) (supported bool) { + defer func() { + if !supported { + logging.Debug("Enforcing deployment via copy, as hardlinks are not supported") + } + }() + + target := filepath.Join(path, linkTarget) + err := fileutils.Touch(target) + if err != nil { + multilog.Error("Error touching target: %v", err) + return false + } + defer func() { + err := os.Remove(target) + if err != nil { + multilog.Error("Error removing target: %v", err) + } + }() + + lnk := filepath.Join(path, link) + if fileutils.TargetExists(lnk) { + err := os.Remove(lnk) + if err != nil { + multilog.Error("Error removing previous link: %v", err) + return false + } + } + + logging.Debug("Attempting to link '%s' to '%s'", lnk, target) + err = smartlink.Link(target, lnk) + if err != nil { + logging.Debug("Test link creation failed: %v", err) + return false + } + err = os.Remove(lnk) + if err != nil { + multilog.Error("Error removing link: %v", err) + } + + return true +} diff --git a/pkg/runtime/options.go b/pkg/runtime/options.go new file mode 100644 index 0000000000..dd150afaef --- /dev/null +++ b/pkg/runtime/options.go @@ -0,0 +1,32 @@ +package runtime + +import ( + "github.com/ActiveState/cli/pkg/runtime/events" + "github.com/go-openapi/strfmt" +) + +func WithEventHandlers(handlers ...events.HandlerFunc) SetOpt { + return func(opts *Opts) { opts.EventHandlers = handlers } +} + +func WithBuildlogFilePath(path string) SetOpt { + return func(opts *Opts) { opts.BuildlogFilePath = path } +} + +func WithPreferredLibcVersion(version string) SetOpt { + return func(opts *Opts) { opts.PreferredLibcVersion = version } +} + +func WithArchive(dir string, platformID strfmt.UUID, ext string) SetOpt { + return func(opts *Opts) { + opts.FromArchive = &fromArchive{dir, platformID, ext} + } +} + +func WithAnnotations(owner, project string, commitUUID strfmt.UUID) SetOpt { + return func(opts *Opts) { + opts.Annotations.Owner = owner + opts.Annotations.Project = project + opts.Annotations.CommitUUID = commitUUID + } +} diff --git a/pkg/runtime/readme.md b/pkg/runtime/readme.md new file mode 100644 index 0000000000..ac0a7efe45 --- /dev/null +++ b/pkg/runtime/readme.md @@ -0,0 +1,60 @@ +# Runtime Package + +The runtime package is responsible for sourcing a runtime based on a provided buildplan, as well as for providing +insights into that sourced runtime. + +## Design Goals + +A fundamental goal of the runtime package (and really any package) is that it is intuitive to maintain. Meaning when we +don't touch this code for 6 months and then come back to it we can still easily tell what's going on. + +The main method of achieving this goal is by minimizing the responsibilities of the runtime package. By having it no be +aware of projects, buildscripts, analytics, etc. we facilitate a much cleaner boilerplate that is easier to grok than +if it were dealing with all these concepts. + +Additionally we keep our use of channels very minimal, and centralize their use in key location so as to avoid passing +channels between functions or layers of logic. + +As we further grow this runtime package we may find that certain responsibilities start to obfuscate the core logic +again, we should remain sensitive to this, removing responsibilities and shifting it into other standalone packages is +always an option. + +### Avoid Dependencies + +The runtime package should itself have no awareness of projects, buildscripts, or anything else not absolutely vital +for the purpose of installing a runtime. + +Note we do provide project information for annotation purposes, because executors rely on it. Over time we should try +and remove executors from the runtime package, because it's really not part of sourcing a functional runtime, it's +more of a distinct post-processing step. + +## Responsibilities + +Anything not covered under these responsibilities should not be introduced into the runtime package without a good +reason and discussion with the tech-lead. + +- Sourcing a runtime based on a provided buildplan +- Providing insights into the sourced runtime +- Handle sharing of sourced artifacts between multiple runtimes + - Specifically this is handled by the "depot" +- Firing of events through the events package + +### Sub-Packages + +Any responsibilities provided by these sub-packages should NOT be handled anywhere else. + +- events + - Provide event hooks for interactions with runtime processes + - eg. for progress indication or analytics + - Note this is handled through the `events` sub-package. +- internal/buildlog + - Interact with buildlog streamer + - ie. provide progress information on in-progress builds + - Firing of events through the events package +- internal/camel + - Facilitate sourcing of camel runtimes + - It does this by pre-processing a camel artifact and injecting a runtime.json that alternate builds normally + produce +- internal/envdef + - Facilitate reading of runtime.json files, and merging multiple runtime.json files together. + diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go new file mode 100644 index 0000000000..1ce0c63fad --- /dev/null +++ b/pkg/runtime/runtime.go @@ -0,0 +1,188 @@ +package runtime + +import ( + "maps" + "os" + "path/filepath" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/runtime/internal/envdef" +) + +// Constants covering the stored runtime +const ( + configDir = ".activestate" + hashFile = "hash.txt" + buildLogFile = "build.log" + executorDir = "exec" +) + +// depotName is the directory name under which we store our artifact depot; ie. we symlink these artifacts into the +// actual runtimes. +const depotName = "depot" + +type Runtime struct { + path string + hash string // The stored hash for the given runtime path, if one exists (otherwise empty) + envCollection *envdef.Collection + env Environment + envInherit Environment + depot *depot +} + +type Environment struct { + Variables map[string]string + VariablesWithExecutors map[string]string + ExecutorsPath string +} + +func New(path string) (*Runtime, error) { + env := envdef.New() + + if err := fileutils.MkdirUnlessExists(path); err != nil { + return nil, errs.Wrap(err, "Could not create runtime directory") + } + + runtimePath := path // for readability; if we need to pass more info to the depot, use a struct + depot, err := newDepot(runtimePath) + if err != nil { + return nil, errs.Wrap(err, "Could not create depot") + } + + r := &Runtime{ + path: path, + envCollection: env, + depot: depot, + } + + if err := r.loadHash(); err != nil { + return nil, errs.Wrap(err, "Failed to load hash") + } + + if err := r.hydrateEnvironment(); err != nil { + return nil, errs.Wrap(err, "Failed to hydrate environment") + } + + return r, nil +} + +func (r *Runtime) Hash() string { + return r.hash +} + +func (r *Runtime) HasCache() bool { + return r.hash != "" +} + +func (r *Runtime) Update(bp *buildplan.BuildPlan, hash string, setOpts ...SetOpt) error { + if r.hash == hash { + logging.Debug("Runtime is already up to date") + return nil + } + + opts := &Opts{} + for _, setOpt := range setOpts { + setOpt(opts) + } + + if opts.BuildlogFilePath == "" { + opts.BuildlogFilePath = filepath.Join(r.path, configDir, buildLogFile) + } + + setup, err := newSetup(r.path, bp, r.envCollection, r.depot, opts) + if err != nil { + return errs.Wrap(err, "Failed to calculate artifacts to install") + } + + if err := setup.RunAndWait(); err != nil { + return errs.Wrap(err, "Failed to install runtime") + } + + if err := r.saveHash(hash); err != nil { + return errs.Wrap(err, "Failed to save hash") + } + + if err := r.hydrateEnvironment(); err != nil { + return errs.Wrap(err, "Failed to hydrate environment") + } + + return nil +} + +// hydrateEnvironment will populate the environment information so that when Env() is called it's just passing already +// calculated data +func (r *Runtime) hydrateEnvironment() error { + // Ingest environment files according to artifacts referenced in depot + for id := range r.depot.List(r.path) { + if _, err := r.envCollection.Load(r.depot.Path(id)); err != nil { + return errs.Wrap(err, "Failed to load environment") + } + } + + vars, execVars, err := r.getEnv(false) + if err != nil { + return errs.Wrap(err, "Failed to get environment variables") + } + + execPath := ExecutorsPath(r.path) + + r.env = Environment{ + Variables: vars, + VariablesWithExecutors: execVars, + ExecutorsPath: execPath, + } + + vars, execVars, err = r.getEnv(true) + if err != nil { + return errs.Wrap(err, "Failed to get inherited environment variables") + } + + r.envInherit = Environment{ + Variables: vars, + VariablesWithExecutors: execVars, + ExecutorsPath: execPath, + } + + return nil +} + +func (r *Runtime) getEnv(inherit bool) (map[string]string, map[string]string, error) { + empty := map[string]string{} + + vars, err := r.envCollection.Environment(r.path, inherit) + if err != nil { + return empty, empty, errs.Wrap(err, "Failed to get environment variables") + } + + executorsPath := ExecutorsPath(r.path) + + execVars := maps.Clone(vars) + execVars["PATH"] = executorsPath + if _, ok := vars["PATH"]; ok { + execVars["PATH"] += string(os.PathListSeparator) + vars["PATH"] + } + + return vars, execVars, nil +} + +func (r *Runtime) Env(inherit bool) Environment { + if inherit { + return r.envInherit + } + return r.env +} + +func (r *Runtime) Path() string { + return r.path +} + +func IsRuntimeDir(dir string) bool { + return fileutils.TargetExists(filepath.Join(dir, configDir, hashFile)) +} + +func ExecutorsPath(baseDir string) string { + return filepath.Join(baseDir, executorDir) +} diff --git a/pkg/runtime/setup.go b/pkg/runtime/setup.go new file mode 100644 index 0000000000..b59229af79 --- /dev/null +++ b/pkg/runtime/setup.go @@ -0,0 +1,548 @@ +package runtime + +import ( + "bytes" + "os" + "path/filepath" + "strings" + + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/pkg/executors" + "github.com/go-openapi/strfmt" + "golang.org/x/net/context" + + "github.com/ActiveState/cli/internal/chanutils/workerpool" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/httputil" + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/osutils" + "github.com/ActiveState/cli/internal/proxyreader" + "github.com/ActiveState/cli/internal/sliceutils" + "github.com/ActiveState/cli/internal/svcctl" + "github.com/ActiveState/cli/internal/unarchiver" + "github.com/ActiveState/cli/pkg/buildplan" + "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" + "github.com/ActiveState/cli/pkg/platform/model" + "github.com/ActiveState/cli/pkg/runtime/events" + "github.com/ActiveState/cli/pkg/runtime/events/progress" + "github.com/ActiveState/cli/pkg/runtime/internal/buildlog" + "github.com/ActiveState/cli/pkg/runtime/internal/camel" + "github.com/ActiveState/cli/pkg/runtime/internal/envdef" + "github.com/ActiveState/cli/pkg/sysinfo" +) + +// maxConcurrency is the maximum number of concurrent workers that can be running at any given time during an update +const maxConcurrency = 5 + +// fromArchive contains options for setting up a runtime from an archive. +type fromArchive struct { + Dir string + PlatformID strfmt.UUID + ArtifactExt string +} + +type Opts struct { + PreferredLibcVersion string + EventHandlers []events.HandlerFunc + BuildlogFilePath string + + FromArchive *fromArchive + + // Annotations are used strictly to pass information for the purposes of analytics + // These should never be used for business logic. If the need to use them for business logic arises either we are + // going down a wrong rabbit hole or we need to revisit the architecture. + Annotations struct { + Owner string + Project string + CommitUUID strfmt.UUID + } +} + +type SetOpt func(*Opts) + +type setup struct { + path string + opts *Opts + depot *depot + supportsHardLinks bool + env *envdef.Collection + buildplan *buildplan.BuildPlan + + // toBuild encompasses all artifacts that will need to be build for this runtime. + // This does NOT mean every artifact in the runtime closure if this is an update (as oppose to a fresh toInstall). + // Because when we update we likely already have some of the requisite artifacts installed, and thus we don't need their toBuild. + toBuild buildplan.ArtifactIDMap + + // toDownload encompasses all artifacts that will need to be downloaded for this runtime. The same caveat applies as for toBuild. + toDownload buildplan.ArtifactIDMap + + // toUnpack encompasses all artifacts that will need to be unpacked for this runtime. + // This is identical to toDownload except when setting up a runtime from an archive. In that case, + // toDownload is nil. + // The same caveat applies as for toBuild. + toUnpack buildplan.ArtifactIDMap + + // toInstall encompasses all artifacts that will need to be installed for this runtime. The same caveat applies as for toBuild. + toInstall buildplan.ArtifactIDMap + + // toUninstall encompasses all artifacts that will need to be uninstalled for this runtime. + toUninstall map[strfmt.UUID]struct{} +} + +func newSetup(path string, bp *buildplan.BuildPlan, env *envdef.Collection, depot *depot, opts *Opts) (*setup, error) { + installedArtifacts := depot.List(path) + + var platformID strfmt.UUID + if opts.FromArchive == nil { + var err error + platformID, err = model.FilterCurrentPlatform(sysinfo.OS().String(), bp.Platforms(), opts.PreferredLibcVersion) + if err != nil { + return nil, errs.Wrap(err, "Could not get platform ID") + } + } else { + platformID = opts.FromArchive.PlatformID + } + + filterInstallable := []buildplan.FilterArtifact{ + buildplan.FilterPlatformArtifacts(platformID), + buildplan.FilterStateArtifacts(), + } + if os.Getenv(constants.InstallBuildDependenciesEnvVarName) != "true" { + filterInstallable = append(filterInstallable, buildplan.FilterRuntimeArtifacts()) + } + + // Start off with the full range of artifacts relevant to our platform + installableArtifacts := bp.Artifacts(filterInstallable...) + + // Identify which artifacts we'll need to install, this filters out any artifacts that are already installed. + artifactsToInstall := installableArtifacts.Filter(func(a *buildplan.Artifact) bool { + _, installed := installedArtifacts[a.ArtifactID] + return !installed + }) + + // Identify which artifacts we can uninstall + installableArtifactsMap := installableArtifacts.ToIDMap() + artifactsToUninstall := map[strfmt.UUID]struct{}{} + for id := range installedArtifacts { + if _, required := installableArtifactsMap[id]; !required { + artifactsToUninstall[id] = struct{}{} + } + } + + // Calculate which artifacts need to be downloaded; if an artifact we want to install is not in our depot then + // by definition we'll need to download it (unless we're setting up the runtime from an archive). + // We also calculate which artifacts are immediately ready to be installed, as its the inverse condition of the above. + artifactsToDownload := artifactsToInstall.Filter(func(a *buildplan.Artifact) bool { + return !depot.Exists(a.ArtifactID) + }) + artifactsToUnpack := artifactsToDownload + if opts.FromArchive != nil { + artifactsToDownload = nil + } + + // Now that we know which artifacts we'll need to download we can use this as our basis for calculating which artifacts + // still need to be build. This encompasses the artifacts themselves, as well as any of their dependencies. And of + // course we only want to filter artifacts that actually require a build, as the build may be cached server side. + artifactsToBuild := append(artifactsToDownload, artifactsToDownload.Dependencies(true, nil)...).Filter(buildplan.FilterNotBuild()) + artifactsToBuild = sliceutils.UniqueByProperty(artifactsToBuild, func(a *buildplan.Artifact) any { return a.ArtifactID }) + + // Check for cached build failures + for _, a := range artifactsToBuild { + var aErr error + if a.Status == types.ArtifactFailedPermanently || a.Status == types.ArtifactFailedTransiently { + errV := &ArtifactCachedBuildFailed{errs.New("artifact failed, status: %s", a.Status), a} + if aErr == nil { + aErr = errV + } else { + aErr = errs.Pack(aErr, errV) + } + } + if aErr != nil { + return nil, aErr + } + } + + return &setup{ + path: path, + opts: opts, + env: env, + depot: depot, + supportsHardLinks: supportsHardLinks(depot.depotPath), + buildplan: bp, + toBuild: artifactsToBuild.ToIDMap(), + toDownload: artifactsToDownload.ToIDMap(), + toUnpack: artifactsToUnpack.ToIDMap(), + toInstall: artifactsToInstall.ToIDMap(), + toUninstall: artifactsToUninstall, + }, nil +} + +func (s *setup) RunAndWait() (rerr error) { + defer func() { + // Handle success / failure event + var name = "success" + var ev events.Event = events.Success{} + if rerr != nil { + name = "failure" + ev = events.Failure{ + Error: rerr, + } + } + + err := s.fireEvent(ev) + if err != nil { + rerr = errs.Pack(rerr, errs.Wrap(err, "Could not handle %s event", name)) + } + }() + + if err := s.fireEvent(events.Start{ + RecipeID: s.buildplan.LegacyRecipeID(), + RequiresBuild: s.buildplan.IsBuildInProgress() && len(s.toDownload) > 0, + LogFilePath: s.opts.BuildlogFilePath, + ArtifactsToBuild: s.toBuild, + ArtifactsToDownload: s.toDownload, + ArtifactsToUnpack: s.toUnpack, + ArtifactsToInstall: s.toInstall, + }); err != nil { + return errs.Wrap(err, "Could not handle Start event") + } + + if err := s.update(); err != nil { + return errs.Wrap(err, "Could not update") + } + + return nil +} + +func (s *setup) update() error { + if err := fileutils.MkdirUnlessExists(filepath.Join(s.path, configDir)); err != nil { + return errs.Wrap(err, "Could not create runtime config dir") + } + + blog := buildlog.New(s.buildplan.LegacyRecipeID(), s.toBuild). + WithEventHandler(s.opts.EventHandlers...). + WithLogFile(filepath.Join(s.path, configDir, buildLogFile)) + + // Download artifacts when ready, or unpack artifacts from archive. + // Note: if there are artifacts to download, s.toUnpack == s.toDownload, and downloaded artifacts + // are unpacked in the same step. + wp := workerpool.New(maxConcurrency) + for _, a := range s.toUnpack { // iterate over unpack as downloads will not be set if installing from archive + s.onArtifactBuildReady(blog, a, func() { + wp.Submit(func() error { + if err := s.obtain(a); err != nil { + return errs.Wrap(err, "obtain failed") + } + return nil + }) + }) + } + + // Wait for build to finish + if !s.buildplan.IsBuildReady() && len(s.toBuild) > 0 { + if err := blog.Wait(context.Background()); err != nil { + return errs.Wrap(err, "errors occurred during buildlog streaming") + } + } + + // Wait for workerpool handling build results to finish + if err := wp.Wait(); err != nil { + return errs.Wrap(err, "errors occurred during obtain") + } + + // Now we start modifying the runtime directory + // This happens AFTER all the download steps are finished, and should be very fast because installing is mostly just + // creating links to the depot. + // We do this as a separate step so we don't leave the runtime dir in a half-installed state if issues happen earlier + // on in the process. + + // Uninstall artifacts + for id := range s.toUninstall { + if err := s.uninstall(id); err != nil { + return errs.Wrap(err, "Could not uninstall artifact") + } + } + + // Install artifacts + wp = workerpool.New(maxConcurrency) + for _, a := range s.toInstall { + wp.Submit(func() error { + if err := s.install(a.ArtifactID); err != nil { + return errs.Wrap(err, "Could not install artifact") + } + return nil + }) + } + + // Wait for workerpool handling artifact installs to finish + if err := wp.Wait(); err != nil { + return errs.Wrap(err, "errors occurred during install") + } + + if err := s.postProcess(); err != nil { + return errs.Wrap(err, "Postprocessing failed") + } + + return nil +} + +func (s *setup) onArtifactBuildReady(blog *buildlog.BuildLog, artifact *buildplan.Artifact, cb func()) { + if _, ok := s.toBuild[artifact.ArtifactID]; !ok { + // No need to build, artifact can already be downloaded + cb() + return + } + + blog.OnArtifactReady(artifact.ArtifactID, cb) +} + +func (s *setup) obtain(artifact *buildplan.Artifact) (rerr error) { + var b []byte + if s.opts.FromArchive == nil { + // Download artifact + var err error + b, err = s.download(artifact) + if err != nil { + return errs.Wrap(err, "download failed") + } + } else { + // Read the artifact from the archive. + var err error + name := artifact.ArtifactID.String() + s.opts.FromArchive.ArtifactExt + artifactFile := filepath.Join(s.opts.FromArchive.Dir, name) + b, err = fileutils.ReadFile(artifactFile) + if err != nil { + return errs.Wrap(err, "read from archive failed") + } + } + + // Unpack artifact + if err := s.unpack(artifact, b); err != nil { + return errs.Wrap(err, "unpack failed") + } + + return nil +} + +func (s *setup) download(artifact *buildplan.Artifact) (_ []byte, rerr error) { + defer func() { + if rerr != nil { + if err := s.fireEvent(events.ArtifactDownloadFailure{artifact.ArtifactID, rerr}); err != nil { + rerr = errs.Pack(rerr, errs.Wrap(err, "Could not handle ArtifactDownloadFailure event")) + } + } + }() + + b, err := httputil.GetWithProgress(artifact.URL, &progress.Report{ + ReportSizeCb: func(size int) error { + if err := s.fireEvent(events.ArtifactDownloadStarted{artifact.ArtifactID, size}); err != nil { + return ProgressReportError{errs.Wrap(err, "Could not handle ArtifactDownloadStarted event")} + } + return nil + }, + ReportIncrementCb: func(inc int) error { + if err := s.fireEvent(events.ArtifactDownloadProgress{artifact.ArtifactID, inc}); err != nil { + return errs.Wrap(err, "Could not handle ArtifactDownloadProgress event") + } + return nil + }, + }) + if err != nil { + return nil, errs.Wrap(err, "Download %s failed", artifact.URL) + } + if err := s.fireEvent(events.ArtifactDownloadSuccess{artifact.ArtifactID}); err != nil { + return nil, errs.Wrap(errs.Pack(err, err), "Could not handle ArtifactDownloadSuccess event") + } + + return b, nil +} + +func (s *setup) unpack(artifact *buildplan.Artifact, b []byte) (rerr error) { + defer func() { + if rerr != nil { + if err := s.fireEvent(events.ArtifactUnpackFailure{artifact.ArtifactID, rerr}); err != nil { + rerr = errs.Pack(rerr, errs.Wrap(err, "Could not handle ArtifactUnpackFailure event")) + } + } else { + if err := s.fireEvent(events.ArtifactUnpackSuccess{artifact.ArtifactID}); err != nil { + rerr = errs.Pack(rerr, errs.Wrap(errs.Pack(err, err), "Could not handle ArtifactUnpackSuccess event")) + } + } + }() + + var ua unarchiver.Unarchiver = unarchiver.NewTarGz() + if strings.HasSuffix(strings.ToLower(artifact.URL), "zip") { + ua = unarchiver.NewZip() + } + + if err := s.fireEvent(events.ArtifactUnpackStarted{artifact.ArtifactID, len(b)}); err != nil { + return errs.Wrap(err, "Could not handle ArtifactUnpackStarted event") + } + + proxy := proxyreader.NewProxyReader(&progress.Report{ + ReportIncrementCb: func(inc int) error { + if err := s.fireEvent(events.ArtifactUnpackProgress{artifact.ArtifactID, inc}); err != nil { + return errs.Wrap(err, "Could not handle ArtifactUnpackProgress event") + } + return nil + }, + }, bytes.NewReader(b)) + if err := ua.Unarchive(proxy, int64(len(b)), s.depot.Path(artifact.ArtifactID)); err != nil { + return errs.Wrap(err, "unpack failed") + } + + if err := s.depot.Put(artifact.ArtifactID); err != nil { + return errs.Wrap(err, "Could not put artifact in depot") + } + + // Camel artifacts do not have runtime.json, so in order to not have multiple paths of logic we generate one based + // on the camel specific info in the artifact. + if s.buildplan.Engine() == types.Camel { + artifactDepotPath := s.depot.Path(artifact.ArtifactID) + envDef, err := camel.NewEnvironmentDefinitions(artifactDepotPath) + if err != nil { + return errs.Wrap(err, "Could not get camel env") + } + + if err := envDef.Save(artifactDepotPath); err != nil { + return errs.Wrap(err, "Could not save camel env") + } + } + + return nil +} + +func (s *setup) updateExecutors() error { + execPath := ExecutorsPath(s.path) + if err := fileutils.MkdirUnlessExists(execPath); err != nil { + return errs.Wrap(err, "Could not create executors directory") + } + + env, err := s.env.Environment(s.path, false) + if err != nil { + return errs.Wrap(err, "Could not get env") + } + + exePaths, err := osutils.ExecutablePaths(env) + if err != nil { + return errs.Wrap(err, "Could not get executable paths") + } + + execInit := executors.New(execPath) + if err := execInit.Apply(svcctl.NewIPCSockPathFromGlobals().String(), executors.NewTarget( + s.opts.Annotations.CommitUUID, + s.opts.Annotations.Owner, + s.opts.Annotations.Project, + s.path, + ), env, exePaths); err != nil { + return locale.WrapError(err, "err_deploy_executors", "Could not create executors") + } + + return nil +} + +func (s *setup) install(id strfmt.UUID) (rerr error) { + defer func() { + if rerr == nil { + if err := s.fireEvent(events.ArtifactInstallSuccess{id}); err != nil { + rerr = errs.Pack(rerr, errs.Wrap(err, "Could not handle ArtifactInstallSuccess event")) + } + } else { + if err := s.fireEvent(events.ArtifactInstallFailure{id, rerr}); err != nil { + rerr = errs.Pack(rerr, errs.Wrap(err, "Could not handle ArtifactInstallFailure event")) + } + } + }() + + if err := s.fireEvent(events.ArtifactInstallStarted{id}); err != nil { + return errs.Wrap(err, "Could not handle ArtifactInstallStarted event") + } + + artifactDepotPath := s.depot.Path(id) + envDef, err := s.env.Load(artifactDepotPath) + if err != nil { + return errs.Wrap(err, "Could not get env") + } + + if envDef.NeedsTransforms() || !s.supportsHardLinks { + if err := s.depot.DeployViaCopy(id, envDef.InstallDir, s.path); err != nil { + return errs.Wrap(err, "Could not deploy artifact via copy") + } + if envDef.NeedsTransforms() { + if err := envDef.ApplyFileTransforms(s.path); err != nil { + return errs.Wrap(err, "Could not apply env transforms") + } + } + } else { + if err := s.depot.DeployViaLink(id, envDef.InstallDir, s.path); err != nil { + return errs.Wrap(err, "Could not deploy artifact via link") + } + } + + return nil +} + +func (s *setup) uninstall(id strfmt.UUID) (rerr error) { + defer func() { + if rerr == nil { + if err := s.fireEvent(events.ArtifactUninstallSuccess{id}); err != nil { + rerr = errs.Pack(rerr, errs.Wrap(err, "Could not handle ArtifactUninstallSuccess event")) + } + } else { + if err := s.fireEvent(events.ArtifactUninstallFailure{id, rerr}); err != nil { + rerr = errs.Pack(rerr, errs.Wrap(err, "Could not handle ArtifactUninstallFailure event")) + } + } + }() + + if err := s.fireEvent(events.ArtifactUninstallStarted{id}); err != nil { + return errs.Wrap(err, "Could not handle ArtifactUninstallStarted event") + } + + artifactDepotPath := s.depot.Path(id) + envDef, err := s.env.Load(artifactDepotPath) + if err != nil { + return errs.Wrap(err, "Could not get env") + } + + if err := s.env.Unload(artifactDepotPath); err != nil { + return errs.Wrap(err, "Could not unload artifact envdef") + } + + if err := s.depot.Undeploy(id, envDef.InstallDir, s.path); err != nil { + return errs.Wrap(err, "Could not unlink artifact") + } + + return nil +} + +func (s *setup) postProcess() (rerr error) { + if err := s.fireEvent(events.PostProcessStarted{}); err != nil { + return errs.Wrap(err, "Could not handle PostProcessStarted event") + } + + defer func() { + if rerr == nil { + if err := s.fireEvent(events.PostProcessSuccess{}); err != nil { + rerr = errs.Pack(rerr, errs.Wrap(err, "Could not handle PostProcessSuccess event")) + } + } else { + if err := s.fireEvent(events.PostProcessFailure{rerr}); err != nil { + rerr = errs.Pack(rerr, errs.Wrap(err, "Could not handle PostProcessFailure event")) + } + } + }() + + // Update executors + if err := s.updateExecutors(); err != nil { + return errs.Wrap(err, "Could not update executors") + } + + // Save depot changes + if err := s.depot.Save(); err != nil { + return errs.Wrap(err, "Could not save depot") + } + + return nil +} diff --git a/pkg/runtime/store.go b/pkg/runtime/store.go new file mode 100644 index 0000000000..05a7bec4d9 --- /dev/null +++ b/pkg/runtime/store.go @@ -0,0 +1,32 @@ +package runtime + +import ( + "path/filepath" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" +) + +func (r *Runtime) loadHash() error { + path := filepath.Join(r.path, configDir, hashFile) + if !fileutils.TargetExists(path) { + return nil + } + + hash, err := fileutils.ReadFile(path) + if err != nil { + return errs.Wrap(err, "Failed to read hash file") + } + + r.hash = string(hash) + return nil +} + +func (r *Runtime) saveHash(hash string) error { + path := filepath.Join(r.path, configDir, hashFile) + if err := fileutils.WriteFile(path, []byte(hash)); err != nil { + return errs.Wrap(err, "Failed to write hash file") + } + + return nil +} diff --git a/pkg/runtime_helpers/helpers.go b/pkg/runtime_helpers/helpers.go new file mode 100644 index 0000000000..3ecad8c694 --- /dev/null +++ b/pkg/runtime_helpers/helpers.go @@ -0,0 +1,108 @@ +package runtime_helpers + +import ( + "path/filepath" + "strings" + + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/hash" + "github.com/ActiveState/cli/internal/installation/storage" + "github.com/ActiveState/cli/internal/multilog" + "github.com/ActiveState/cli/pkg/localcommit" + "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/cli/pkg/runtime" + "github.com/go-openapi/strfmt" +) + +/* +This package contains helpers for interacting with the runtime. Because while the runtime package itself may not deal +with certain concepts, like projects, we still want convenience layers for interacting with the runtime from the perspective +of projects. +*/ + +func FromProject(proj *project.Project) (*runtime.Runtime, error) { + targetDir := TargetDirFromProject(proj) + rt, err := runtime.New(targetDir) + if err != nil { + return nil, errs.Wrap(err, "Could not initialize runtime") + } + return rt, nil +} + +func NeedsUpdate(proj *project.Project, overrideCommitID *strfmt.UUID) (bool, error) { + rt, err := FromProject(proj) + if err != nil { + return false, errs.Wrap(err, "Could not obtain runtime") + } + + hash, err := Hash(proj, overrideCommitID) + if err != nil { + return false, errs.Wrap(err, "Could not get hash") + } + + return hash != rt.Hash(), nil +} + +func Hash(proj *project.Project, overrideCommitID *strfmt.UUID) (string, error) { + var err error + var commitID strfmt.UUID + if overrideCommitID == nil { + commitID, err = localcommit.Get(proj.Dir()) + if err != nil { + return "", errs.Wrap(err, "Failed to get local commit") + } + } else { + commitID = *overrideCommitID + } + + path, err := fileutils.ResolveUniquePath(proj.Dir()) + if err != nil { + return "", errs.Wrap(err, "Could not resolve unique path for projectDir") + } + + return hash.ShortHash(strings.Join([]string{proj.NamespaceString(), path, commitID.String(), constants.RevisionHashShort}, "")), nil +} + +func ExecutorPathFromProject(proj *project.Project) string { + return runtime.ExecutorsPath(TargetDirFromProject(proj)) +} + +func TargetDirFromProject(proj *project.Project) string { + if cache := proj.Cache(); cache != "" { + return cache + } + + return filepath.Join(storage.CachePath(), DirNameFromProjectDir(proj.Dir())) +} + +func DirNameFromProjectDir(dir string) string { + resolvedDir, err := fileutils.ResolveUniquePath(dir) + if err != nil { + multilog.Error("Could not resolve unique path for projectDir: %s, error: %s", dir, err.Error()) + resolvedDir = dir + } + + return hash.ShortHash(resolvedDir) +} + +func TargetDirFromProjectDir(path string) (string, error) { + // Attempt to route via project file if it exists, since this considers the configured cache dir + if fileutils.TargetExists(filepath.Join(path, constants.ConfigFileName)) { + proj, err := project.FromPath(path) + if err != nil { + return "", errs.Wrap(err, "Could not load project from path") + } + return TargetDirFromProject(proj), nil + } + + // Fall back on the provided path, because we can't assume the project file exists and is valid + resolvedDir, err := fileutils.ResolveUniquePath(path) + if err != nil { + multilog.Error("Could not resolve unique path for projectDir: %s, error: %s", path, err.Error()) + resolvedDir = path + } + + return filepath.Join(storage.CachePath(), hash.ShortHash(resolvedDir)), nil +} diff --git a/pkg/sysinfo/sysinfo_darwin.go b/pkg/sysinfo/sysinfo_darwin.go index 38666b6ebc..a615edbc44 100644 --- a/pkg/sysinfo/sysinfo_darwin.go +++ b/pkg/sysinfo/sysinfo_darwin.go @@ -124,7 +124,7 @@ func getDarwinProductVersion() (string, error) { version, err := exec.Command("sw_vers", "-productVersion").Output() if err != nil { - return "", locale.WrapError(err, "Could not detect your OS version, error received: %s", err.Error()) + return "", locale.WrapError(err, "Could not detect your OS version. Error received: %s", err.Error()) } return string(bytes.TrimSpace(version)), nil } diff --git a/readme.md b/readme.md index eee6dcc290..72b07ed38b 100644 --- a/readme.md +++ b/readme.md @@ -8,6 +8,7 @@ State Tool has a stated goal of "Replacing the Makefile". We're making progress, ## Installation ### Linux & macOS + In your favourite terminal: ``` @@ -15,6 +16,7 @@ sh <(curl -q https://platform.activestate.com/dl/cli/install.sh) ``` ### Windows + In Powershell with Administrator privileges: ``` @@ -22,11 +24,13 @@ IEX(New-Object Net.WebClient).downloadString('https://platform.activestate.com/d ``` ## Usage + For usage information please refer to the [State Tool Documentation](http://docs.activestate.com/platform/state/). ## Development ### Requirements + * Go 1.16 or above ### Building & Testing diff --git a/scripts/ci/update-version-list/main.go b/scripts/ci/update-version-list/main.go index 1acd76b088..dd2052ba09 100644 --- a/scripts/ci/update-version-list/main.go +++ b/scripts/ci/update-version-list/main.go @@ -66,7 +66,7 @@ func main() { continue } fmt.Printf("Found %s\n", file.RelativePath()) - bytes, err := fileutils.ReadFile(file.Path()) + bytes, err := fileutils.ReadFile(file.AbsolutePath()) if err != nil { log.Fatalf("Unable to read file: %s", err.Error()) } diff --git a/scripts/grab-mergecommits/main.go b/scripts/grab-mergecommits/main.go index af241ffeef..79af2ab719 100644 --- a/scripts/grab-mergecommits/main.go +++ b/scripts/grab-mergecommits/main.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "os" "os/exec" @@ -96,7 +97,8 @@ func orderCommits(hashes []string) []string { handled := false for oidx, ohash := range ordered { code, _, err := osutils.Execute("git", []string{"merge-base", "--is-ancestor", hash, ohash}, nil) - if err != nil && !errs.Matches(err, &exec.ExitError{}) { + var errExit *exec.ExitError + if err != nil && !errors.As(err, &errExit) { panic(err) } if code == 0 { diff --git a/scripts/to-buildexpression/main.go b/scripts/to-buildexpression/main.go index dccf2c5179..0d5cbae0de 100644 --- a/scripts/to-buildexpression/main.go +++ b/scripts/to-buildexpression/main.go @@ -7,29 +7,34 @@ import ( "os" "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/pkg/buildscript" ) func main() { - scanner := bufio.NewScanner(os.Stdin) var input string - for scanner.Scan() { - if errors.Is(scanner.Err(), bufio.ErrFinalToken) { - break + if len(os.Args) == 2 && fileutils.FileExists(os.Args[1]) { + input = string(fileutils.ReadFileUnsafe(os.Args[1])) + } else { + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + if errors.Is(scanner.Err(), bufio.ErrFinalToken) { + break + } + line := scanner.Text() + if line == "\x04" { // Ctrl+D character + break + } + input += line + "\n" } - line := scanner.Text() - if line == "\x04" { // Ctrl+D character - break - } - input += line + "\n" - } - if err := scanner.Err(); err != nil { - panic(fmt.Sprintf("error reading standard input: %v\n", err)) + if err := scanner.Err(); err != nil { + panic(fmt.Sprintf("error reading standard input: %v\n", err)) + } } if input == "" { - fmt.Printf("Usage: %s << \n", os.Args[0]) + fmt.Printf("Usage: %s [<< | ]\n", os.Args[0]) os.Exit(1) } diff --git a/scripts/to-buildscript/main.go b/scripts/to-buildscript/main.go index 6752489c4b..6800ddd78a 100644 --- a/scripts/to-buildscript/main.go +++ b/scripts/to-buildscript/main.go @@ -8,43 +8,55 @@ import ( "time" "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/pkg/buildscript" - "github.com/go-openapi/strfmt" ) func main() { - scanner := bufio.NewScanner(os.Stdin) var input string - for scanner.Scan() { - if errors.Is(scanner.Err(), bufio.ErrFinalToken) { - break + var argOffset = 0 + if len(os.Args) == 2 && fileutils.FileExists(os.Args[1]) { + input = string(fileutils.ReadFileUnsafe(os.Args[1])) + argOffset = 1 + } else { + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + if errors.Is(scanner.Err(), bufio.ErrFinalToken) { + break + } + line := scanner.Text() + if line == "\x04" { // Ctrl+D character + break + } + input += line + "\n" } - line := scanner.Text() - if line == "\x04" { // Ctrl+D character - break - } - input += line + "\n" - } - if err := scanner.Err(); err != nil { - panic(fmt.Sprintf("error reading standard input: %v\n", err)) + if err := scanner.Err(); err != nil { + panic(fmt.Sprintf("error reading standard input: %v\n", err)) + } } if input == "" { - fmt.Printf("Usage: %s [] << \n", os.Args[0]) + fmt.Printf("Usage: %s [<< | ] []\n", os.Args[0]) os.Exit(1) } + project := "https://platform.activestate.com/org/project?branch=main&commitID=00000000-0000-0000-0000-000000000000" var atTime *time.Time - if len(os.Args) == 2 { - t, err := time.Parse(strfmt.RFC3339Millis, os.Args[1]) + if len(os.Args) == (2 + argOffset) { + t, err := time.Parse(time.RFC3339, os.Args[1+argOffset]) if err != nil { panic(errs.JoinMessage(err)) } atTime = &t } - bs, err := buildscript.UnmarshalBuildExpression([]byte(input), atTime) + bs := buildscript.New() + bs.SetProject(project) + if atTime != nil { + bs.SetAtTime(*atTime, true) + } + err := bs.UnmarshalBuildExpression([]byte(input)) if err != nil { panic(errs.JoinMessage(err)) } diff --git a/test/activestate.yaml b/test/activestate.yaml index 60ef90dfd5..364b6b251b 100644 --- a/test/activestate.yaml +++ b/test/activestate.yaml @@ -25,3 +25,4 @@ scripts: value: pytest %projectDir%/tests - name: debug value: debug foo +config_version: 1 diff --git a/test/automation/invite_neg_automation_test.go b/test/automation/invite_neg_automation_test.go index 1e65f63fb9..c21a1ff759 100644 --- a/test/automation/invite_neg_automation_test.go +++ b/test/automation/invite_neg_automation_test.go @@ -110,7 +110,7 @@ func (suite *InviteNegativeAutomationTestSuite) TestInvite_NonExistentArgValues_ // Non existent Role test cp := ts.Spawn("invite", "qatesting+3@activestate.com", "--role", "first") cp.Expect("Invalid value for \"--role\" flag") - cp.Expect("Invalid role: first, should be one of: owner, member") + cp.Expect("Invalid role: 'first'. Should be one of: owner, member") cp.ExpectExitCode(1) // Non existent Organization test @@ -141,7 +141,7 @@ func (suite *InviteNegativeAutomationTestSuite) TestInvite_NonExistentArgValues_ // Non existent Role test cp := ts.Spawn("invite", "qatesting+3@activestate.com", "--role", "first") cp.Expect("Invalid value for \"--role\" flag") - cp.Expect("Invalid role: first, should be one of: owner, member") + cp.Expect("Invalid role: 'first'. Should be one of: owner, member") cp.ExpectExitCode(1) // Non existent Organization test diff --git a/test/integration/activate_int_test.go b/test/integration/activate_int_test.go index 80d19cb8b6..7cb4c87653 100644 --- a/test/integration/activate_int_test.go +++ b/test/integration/activate_int_test.go @@ -3,7 +3,6 @@ package integration import ( "errors" "fmt" - "os" "os/exec" "path/filepath" "regexp" @@ -12,9 +11,11 @@ import ( "testing" "time" - "github.com/ActiveState/cli/internal/testhelpers/suite" + "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/termtest" + "github.com/ActiveState/cli/internal/testhelpers/suite" + "github.com/ActiveState/cli/internal/rtutils" "github.com/ActiveState/cli/internal/constants" @@ -53,8 +54,7 @@ func (suite *ActivateIntegrationTestSuite) TestActivateWithoutRuntime() { close := suite.addForegroundSvc(ts) defer close() - cp := ts.Spawn("activate", "ActiveState-CLI/Python2") - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("activate", "ActiveState-CLI/Empty") cp.Expect("Activated") cp.ExpectInput() @@ -134,10 +134,8 @@ func (suite *ActivateIntegrationTestSuite) TestActivateUsingCommitID() { close := suite.addForegroundSvc(ts) defer close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", "ActiveState-CLI/Python3#6d9280e7-75eb-401a-9e71-0d99759fbad3", "--path", ts.Dirs.Work), - ) - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) + cp := ts.Spawn("activate", "ActiveState-CLI/Empty#6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8", "--path", ts.Dirs.Work) + cp.Expect("Activated") cp.ExpectInput() cp.SendLine("exit") @@ -151,12 +149,9 @@ func (suite *ActivateIntegrationTestSuite) TestActivateNotOnPath() { close := suite.addForegroundSvc(ts) defer close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", "activestate-cli/small-python", "--path", ts.Dirs.Work), - ) - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("activate", "activestate-cli/empty", "--path", ts.Dirs.Work) cp.Expect("Activated") - cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) + cp.ExpectInput() if runtime.GOOS == "windows" { cp.SendLine("doskey /macros | findstr state=") @@ -182,15 +177,12 @@ func (suite *ActivateIntegrationTestSuite) TestActivatePythonByHostOnly() { defer close() projectName := "Python-LinuxWorks" - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", "cli-integration-tests/"+projectName, "--path="+ts.Dirs.Work), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("activate", "cli-integration-tests/"+projectName, "--path="+ts.Dirs.Work) if runtime.GOOS == "linux" { cp.Expect("Creating a Virtual Environment") cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectInput(termtest.OptExpectTimeout(40 * time.Second)) + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) } else { @@ -228,7 +220,6 @@ func (suite *ActivateIntegrationTestSuite) activatePython(version string, extraE cp := ts.SpawnWithOpts( e2e.OptArgs("activate", namespace), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), e2e.OptAppendEnv(extraEnv...), ) @@ -257,16 +248,16 @@ func (suite *ActivateIntegrationTestSuite) activatePython(version string, extraE cp.SendLine("state activate --default") cp.Expect("Creating a Virtual Environment") - cp.ExpectInput(termtest.OptExpectTimeout(40 * time.Second)) + cp.ExpectInput(e2e.RuntimeSourcingTimeoutOpt) pythonShim := pythonExe + osutils.ExeExtension // test that existing environment variables are inherited by the activated shell if runtime.GOOS == "windows" { - cp.SendLine(fmt.Sprintf("echo %%%s%%", constants.DisableRuntime)) + cp.SendLine(fmt.Sprintf("echo %%%s%%", constants.E2ETestEnvVarName)) } else { - cp.SendLine("echo $" + constants.DisableRuntime) + cp.SendLine("echo $" + constants.E2ETestEnvVarName) } - cp.Expect("false") + cp.Expect("true") // test that other executables that use python work as well pipExe := "pip" + version @@ -288,7 +279,6 @@ func (suite *ActivateIntegrationTestSuite) activatePython(version string, extraE cp = ts.SpawnCmdWithOpts( executor, e2e.OptArgs("-c", "import sys; print(sys.copyright);"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.Expect("ActiveState Software Inc.", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) @@ -304,10 +294,7 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_PythonPath() { namespace := "ActiveState-CLI/Python3" - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", namespace), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("activate", namespace) cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) // ensure that shell is functional @@ -320,18 +307,6 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_PythonPath() { } else { cp.SendLine("echo $PYTHONPATH") } - suite.Assert().NotContains(cp.Output(), constants.LocalRuntimeTempDirectory) - // Verify the temp runtime setup directory has been removed. - runtimeFound := false - entries, err := fileutils.ListDir(ts.Dirs.Cache, true) - suite.Require().NoError(err) - for _, entry := range entries { - if entry.IsDir() && fileutils.DirExists(filepath.Join(entry.Path(), constants.LocalRuntimeEnvironmentDirectory)) { - runtimeFound = true - suite.Assert().NoDirExists(filepath.Join(entry.Path(), constants.LocalRuntimeTempDirectory)) - } - } - suite.Assert().True(runtimeFound, "runtime directory was not found in ts.Dirs.Cache") // test that PYTHONPATH is preserved in environment (https://www.pivotaltracker.com/story/show/178458102) if runtime.GOOS == "windows" { @@ -360,9 +335,8 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_SpaceInCacheDir() { suite.Require().NoError(err) cp := ts.SpawnWithOpts( - e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.CacheEnvVarName, cacheDir)), - e2e.OptAppendEnv(fmt.Sprintf(`%s=""`, constants.DisableRuntime)), e2e.OptArgs("activate", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.CacheEnvVarName, cacheDir)), ) cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) @@ -384,10 +358,7 @@ func (suite *ActivateIntegrationTestSuite) TestActivatePerlCamel() { close := suite.addForegroundSvc(ts) defer close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", "ActiveState-CLI/Perl"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("activate", "ActiveState-CLI/Perl") cp.Expect("Downloading", termtest.OptExpectTimeout(40*time.Second)) cp.Expect("Installing", termtest.OptExpectTimeout(140*time.Second)) @@ -419,18 +390,13 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_Subdir() { // Create the project file at the root of the temp dir content := strings.TrimSpace(fmt.Sprintf(` -project: "https://platform.activestate.com/ActiveState-CLI/Python3" +project: "https://platform.activestate.com/ActiveState-CLI/Empty" branch: %s version: %s `, constants.ChannelName, constants.Version)) ts.PrepareActiveStateYAML(content) - ts.PrepareCommitIdFile("59404293-e5a9-4fd0-8843-77cd4761b5b5") - - // Pull to ensure we have an up to date config file - cp := ts.Spawn("pull") - cp.Expect("activestate.yaml has been updated to") - cp.ExpectExitCode(0) + ts.PrepareCommitIdFile("6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") // Activate in the subdirectory c2 := ts.SpawnWithOpts( @@ -458,29 +424,24 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_NamespaceWins() { // Create the project file at the root of the temp dir ts.PrepareProject("ActiveState-CLI/Python3", "59404293-e5a9-4fd0-8843-77cd4761b5b5") - // Pull to ensure we have an up to date config file - cp := ts.Spawn("pull") - cp.Expect("activestate.yaml has been updated to") - cp.ExpectExitCode(0) - // Activate in the subdirectory - c2 := ts.SpawnWithOpts( - e2e.OptArgs("activate", "ActiveState-CLI/Python2"), // activate a different namespace + cp := ts.SpawnWithOpts( + e2e.OptArgs("activate", "ActiveState-CLI/Empty"), // activate a different namespace e2e.OptWD(targetPath), e2e.OptAppendEnv(constants.DisableLanguageTemplates+"=true"), ) - c2.Expect("ActiveState-CLI/Python2") - c2.Expect("Activated") + cp.Expect("ActiveState-CLI/Empty") + cp.Expect("Activated") - c2.ExpectInput() + cp.ExpectInput() if runtime.GOOS == "windows" { - c2.SendLine("@echo %cd%") + cp.SendLine("@echo %cd%") } else { - c2.SendLine("pwd") + cp.SendLine("pwd") } - c2.Expect(identifyPath) - c2.SendLine("exit") - c2.ExpectExitCode(0) + cp.Expect(identifyPath) + cp.SendLine("exit") + cp.ExpectExitCode(0) } func (suite *ActivateIntegrationTestSuite) TestActivate_InterruptedInstallation() { @@ -488,14 +449,14 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_InterruptedInstallation( if runtime.GOOS == "windows" && e2e.RunningOnCI() { suite.T().Skip("interrupting installation does not work on Windows on CI") } - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() close := suite.addForegroundSvc(ts) defer close() - cp := ts.SpawnShellWithOpts("bash", e2e.OptAppendEnv(constants.DisableRuntime+"=false")) - cp.SendLine("state deploy install ActiveState-CLI/small-python") - cp.Expect("Installing Runtime") // Ensure we don't send Ctrl+C too soon + cp := ts.SpawnShellWithOpts("bash") + cp.SendLine("state deploy install ActiveState-CLI/Empty") + cp.Expect(locale.T("install_runtime")) // Ensure we don't send Ctrl+C too soon cp.SendCtrlC() cp.Expect("User interrupted") cp.SendLine("exit") @@ -504,19 +465,16 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_InterruptedInstallation( func (suite *ActivateIntegrationTestSuite) TestActivate_FromCache() { suite.OnlyRunForTags(tagsuite.Activate, tagsuite.Critical) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) err := ts.ClearCache() suite.Require().NoError(err) defer ts.Close() close := suite.addForegroundSvc(ts) defer close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Downloading") - cp.Expect("Installing") + // Note: cannot use Empty project since we need artifacts to download and install. + // Pick the langless project, which just has some small, non-language artifacts. + cp := ts.Spawn("activate", "ActiveState-CLI/langless", "--path", ts.Dirs.Work) cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) suite.assertCompletedStatusBarReport(cp.Output()) @@ -524,10 +482,7 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_FromCache() { cp.ExpectExitCode(0) // next activation is cached - cp = ts.SpawnWithOpts( - e2e.OptArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("activate", "ActiveState-CLI/langless", "--path", ts.Dirs.Work) cp.ExpectInput(e2e.RuntimeSourcingTimeoutOpt) cp.SendLine("exit") @@ -565,10 +520,9 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_AlreadyActive() { close := suite.addForegroundSvc(ts) defer close() - namespace := "ActiveState-CLI/Python3" + namespace := "ActiveState-CLI/Empty" - cp := ts.SpawnWithOpts(e2e.OptArgs("activate", namespace)) - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("activate", namespace) cp.Expect("Activated") // ensure that shell is functional cp.ExpectInput() @@ -586,10 +540,9 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_AlreadyActive_SameNamesp close := suite.addForegroundSvc(ts) defer close() - namespace := "ActiveState-CLI/Python3" + namespace := "ActiveState-CLI/Empty" - cp := ts.SpawnWithOpts(e2e.OptArgs("activate", namespace)) - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("activate", namespace) cp.Expect("Activated") // ensure that shell is functional cp.ExpectInput() @@ -607,10 +560,9 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_AlreadyActive_DifferentN close := suite.addForegroundSvc(ts) defer close() - namespace := "ActiveState-CLI/Python3" + namespace := "ActiveState-CLI/Empty" - cp := ts.SpawnWithOpts(e2e.OptArgs("activate", namespace)) - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("activate", namespace) cp.Expect("Activated") // ensure that shell is functional cp.ExpectInput() @@ -630,11 +582,8 @@ func (suite *ActivateIntegrationTestSuite) TestActivateBranch() { namespace := "ActiveState-CLI/Branches" - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", namespace, "--branch", "firstbranch"), - ) - cp.Expect("Skipping runtime setup") - cp.Expect("Activated") + cp := ts.Spawn("activate", namespace, "--branch", "firstbranch") + cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) // note: activate always sources the runtime cp.SendLine("exit") cp.ExpectExitCode(0) } @@ -649,59 +598,7 @@ func (suite *ActivateIntegrationTestSuite) TestActivateBranchNonExistant() { namespace := "ActiveState-CLI/Branches" - cp := ts.SpawnWithOpts(e2e.OptArgs("activate", namespace, "--branch", "does-not-exist")) + cp := ts.Spawn("activate", namespace, "--branch", "does-not-exist") cp.Expect("has no branch") } - -func (suite *ActivateIntegrationTestSuite) TestActivateArtifactsCached() { - suite.OnlyRunForTags(tagsuite.Activate) - - ts := e2e.New(suite.T(), false) - defer ts.Close() - close := suite.addForegroundSvc(ts) - defer close() - - namespace := "ActiveState-CLI/Python3" - - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", namespace), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.SendLine("exit") - cp.ExpectExitCode(0) - - artifactCacheDir := filepath.Join(ts.Dirs.Cache, constants.ArtifactMetaDir) - suite.True(fileutils.DirExists(artifactCacheDir), "artifact cache directory does not exist") - artifactInfoJson := filepath.Join(artifactCacheDir, constants.ArtifactCacheFileName) - suite.True(fileutils.FileExists(artifactInfoJson), "artifact cache info json file does not exist") - - files, err := fileutils.ListDir(artifactCacheDir, false) - suite.NoError(err) - suite.True(len(files) > 1, "artifact cache is empty") // ignore json file - - // Clear all cached data except artifact cache. - // This removes the runtime so that it needs to be created again. - files, err = fileutils.ListDir(ts.Dirs.Cache, true) - suite.NoError(err) - for _, entry := range files { - if entry.IsDir() && entry.RelativePath() != constants.ArtifactMetaDir { - os.RemoveAll(entry.Path()) - } - } - - cp = ts.SpawnWithOpts( - e2e.OptArgs("activate", namespace), - e2e.OptAppendEnv( - constants.DisableRuntime+"=false", - "VERBOSE=true", // Necessary to assert "Fetched cached artifact" - ), - ) - - cp.Expect("Fetched cached artifact") - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.SendLine("exit") - cp.ExpectExitCode(0) -} diff --git a/test/integration/analytics_int_test.go b/test/integration/analytics_int_test.go index 1ce91867c7..3abc9dc148 100644 --- a/test/integration/analytics_int_test.go +++ b/test/integration/analytics_int_test.go @@ -10,8 +10,8 @@ import ( "testing" "time" + "github.com/ActiveState/cli/internal/runbits/runtime/trigger" "github.com/ActiveState/cli/internal/testhelpers/suite" - "github.com/ActiveState/termtest" "github.com/thoas/go-funk" "github.com/ActiveState/cli/internal/analytics/client/sync/reporters" @@ -23,7 +23,6 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/e2e" helperSuite "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/ActiveState/cli/pkg/platform/runtime/target" ) type AnalyticsIntegrationTestSuite struct { @@ -40,7 +39,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeartbeats() { /* TEST SETUP */ - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() namespace := "ActiveState-CLI/Alternate-Python" @@ -54,7 +53,6 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeartbeats() { sleepTime = sleepTime + (sleepTime / 2) env := []string{ - constants.DisableRuntime + "=false", fmt.Sprintf("%s=%d", constants.HeartbeatIntervalEnvVarName, heartbeatInterval), } @@ -78,7 +76,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeartbeats() { cp.Expect("Creating a Virtual Environment") cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectInput(termtest.OptExpectTimeout(120 * time.Second)) + cp.ExpectInput() time.Sleep(time.Second) // Ensure state-svc has time to report events @@ -144,7 +142,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeartbeats() { if e.Dimensions == nil || e.Dimensions.Trigger == nil { return false } - return (*e.Dimensions.Trigger) == target.TriggerExecutor.String() + return (*e.Dimensions.Trigger) == trigger.TriggerExecutor.String() }) suite.Require().Equal(1, countEvents(executorEvents, anaConst.CatRuntimeUsage, anaConst.ActRuntimeAttempt, anaConst.SrcExecutor), ts.DebugMessage("Should have a runtime attempt, events:\n"+suite.summarizeEvents(executorEvents))) @@ -213,7 +211,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestExecEvents() { /* TEST SETUP */ - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() namespace := "ActiveState-CLI/Alternate-Python" @@ -227,7 +225,6 @@ func (suite *AnalyticsIntegrationTestSuite) TestExecEvents() { sleepTime = sleepTime + (sleepTime / 2) env := []string{ - constants.DisableRuntime + "=false", fmt.Sprintf("%s=%d", constants.HeartbeatIntervalEnvVarName, heartbeatInterval), } @@ -383,7 +380,7 @@ func parseAnalyticsEvents(suite TestingSuiteForAnalytics, ts *e2e.Session) []rep func (suite *AnalyticsIntegrationTestSuite) TestSend() { suite.OnlyRunForTags(tagsuite.Analytics, tagsuite.Critical) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() suite.eventsfile = filepath.Join(ts.Dirs.Config, reporters.TestReportFilename) @@ -417,7 +414,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestSend() { func (suite *AnalyticsIntegrationTestSuite) TestSequenceAndFlags() { suite.OnlyRunForTags(tagsuite.Analytics) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() cp := ts.Spawn("--version") @@ -442,7 +439,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestSequenceAndFlags() { func (suite *AnalyticsIntegrationTestSuite) TestInputError() { suite.OnlyRunForTags(tagsuite.Analytics) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() suite.eventsfile = filepath.Join(ts.Dirs.Config, reporters.TestReportFilename) @@ -468,21 +465,20 @@ func (suite *AnalyticsIntegrationTestSuite) TestInputError() { func (suite *AnalyticsIntegrationTestSuite) TestAttempts() { suite.OnlyRunForTags(tagsuite.Analytics) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() ts.PrepareProject("ActiveState-CLI/test", "9090c128-e948-4388-8f7f-96e2c1e00d98") cp := ts.SpawnWithOpts( e2e.OptArgs("activate", "ActiveState-CLI/Alternate-Python"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - e2e.OptAppendEnv(constants.DisableActivateEventsEnvVarName+"=false"), e2e.OptWD(ts.Dirs.Work), + e2e.OptAppendEnv(constants.DisableActivateEventsEnvVarName+"=false"), ) cp.Expect("Creating a Virtual Environment") cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectInput(termtest.OptExpectTimeout(120 * time.Second)) + cp.ExpectInput() cp.SendLine("python3 --version") cp.Expect("Python 3.") @@ -514,18 +510,19 @@ func (suite *AnalyticsIntegrationTestSuite) TestAttempts() { func (suite *AnalyticsIntegrationTestSuite) TestHeapEvents() { suite.OnlyRunForTags(tagsuite.Analytics) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts(e2e.OptArgs("activate", "ActiveState-CLI/Alternate-Python"), + cp := ts.SpawnWithOpts( + e2e.OptArgs("activate", "ActiveState-CLI/Alternate-Python"), e2e.OptWD(ts.Dirs.Work), ) cp.Expect("Creating a Virtual Environment") - cp.Expect("Activated") - cp.ExpectInput(termtest.OptExpectTimeout(120 * time.Second)) + cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) + cp.ExpectInput() time.Sleep(time.Second) // Ensure state-svc has time to report events @@ -556,17 +553,19 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeapEvents() { func (suite *AnalyticsIntegrationTestSuite) TestConfigEvents() { suite.OnlyRunForTags(tagsuite.Analytics, tagsuite.Config) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.OptArgs("config", "set", "optin.unstable", "false"), + cp := ts.SpawnWithOpts( + e2e.OptArgs("config", "set", "optin.unstable", "false"), e2e.OptWD(ts.Dirs.Work), ) cp.Expect("Successfully set config key") time.Sleep(time.Second) // Ensure state-svc has time to report events - cp = ts.SpawnWithOpts(e2e.OptArgs("config", "set", "optin.unstable", "true"), + cp = ts.SpawnWithOpts( + e2e.OptArgs("config", "set", "optin.unstable", "true"), e2e.OptWD(ts.Dirs.Work), ) cp.Expect("Successfully set config key") @@ -603,7 +602,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestConfigEvents() { func (suite *AnalyticsIntegrationTestSuite) TestCIAndInteractiveDimensions() { suite.OnlyRunForTags(tagsuite.Analytics) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() for _, interactive := range []bool{true, false} { @@ -612,7 +611,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestCIAndInteractiveDimensions() { if !interactive { args = append(args, "--non-interactive") } - cp := ts.SpawnWithOpts(e2e.OptArgs(args...)) + cp := ts.Spawn(args...) cp.Expect("ActiveState CLI") cp.ExpectExitCode(0) diff --git a/test/integration/api_int_test.go b/test/integration/api_int_test.go index bc8167903a..c00cf5c6a6 100644 --- a/test/integration/api_int_test.go +++ b/test/integration/api_int_test.go @@ -1,9 +1,12 @@ package integration import ( + "path/filepath" + "strings" "testing" "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -20,8 +23,8 @@ func (suite *ApiIntegrationTestSuite) TestRequestHeaders() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python3", "."), - e2e.OptAppendEnv(constants.PlatformApiPrintRequestsEnvVarName+"=true", "VERBOSE=true"), + e2e.OptArgs("checkout", "ActiveState-CLI/Empty", "."), + e2e.OptAppendEnv(constants.DebugServiceRequestsEnvVarName+"=true", "VERBOSE=true"), ) // e.g. User-Agent: state/0.38.0-SHA0deadbeef0; release (Windows; 10.0.22621; x86_64) cp.ExpectRe(`User-Agent: state/(\d+\.?)+-SHA[[:xdigit:]]+; \S+ \([^;]+; [^;]+; [^)]+\)`) @@ -29,6 +32,30 @@ func (suite *ApiIntegrationTestSuite) TestRequestHeaders() { cp.ExpectExitCode(0) } +// TestNoApiCallsForPlainInvocation asserts that a bare `state` does not make any API calls. +func (suite *ApiIntegrationTestSuite) TestNoApiCallsForPlainInvocation() { + suite.OnlyRunForTags(tagsuite.Critical) + + ts := e2e.New(suite.T(), false) + defer ts.Close() + + cp := ts.SpawnWithOpts( + e2e.OptAppendEnv(constants.DebugServiceRequestsEnvVarName + "=true"), + ) + cp.ExpectExitCode(0) + + readLogFile := false + for _, path := range ts.LogFiles() { + if !strings.HasPrefix(filepath.Base(path), "state-") { + continue + } + contents := string(fileutils.ReadFileUnsafe(path)) + suite.Assert().NotContains(contents, "URL: ") // pkg/platform/api logs URL, User-Agent, and X-Requestor for API calls + readLogFile = true + } + suite.Assert().True(readLogFile, "did not read log file") +} + func TestApiIntegrationTestSuite(t *testing.T) { suite.Run(t, new(ApiIntegrationTestSuite)) } diff --git a/test/integration/artifactcache_int_test.go b/test/integration/artifactcache_int_test.go deleted file mode 100644 index 9d0e6ad252..0000000000 --- a/test/integration/artifactcache_int_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package integration - -import ( - "os" - "path/filepath" - "testing" - "time" - - "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/testhelpers/osutil" - "github.com/ActiveState/cli/pkg/platform/runtime/artifactcache" - "github.com/go-openapi/strfmt" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestArtifactCache(t *testing.T) { - // Note: the length in bytes of each artifact is its index. - testArtifacts := []strfmt.UUID{ - "000000000-0000-0000-0000-000000000000", - "74D554B3-6B0F-434B-AFE2-9F2F0B5F32BA", - "87ADD1B0-169D-4C01-8179-191BB9910799", - "5D8D933F-09FA-45A3-81FF-E6F33E91C9ED", - "992B8488-C61D-433C-ADF2-D76EBD8DAE59", - "2C36A315-59ED-471B-8629-2663ECC95476", - "57E8EAF4-F7EE-4BEF-B437-D9F0A967BA52", - "E299F10C-7B5D-4B25-B821-90E30193A916", - "F95C0ECE-9F69-4998-B83F-CE530BACD468", - "CAC9708D-FAA6-4295-B640-B8AA41A8AABC", - "009D20C9-0E38-44E8-A095-7B6FEF01D7DA", - } - - dir, err := os.MkdirTemp("", "") - require.NoError(t, err) - defer os.RemoveAll(dir) - - // Test cache creation. - cache, err := artifactcache.NewTestArtifactCache(dir, 10) // bytes - require.NoError(t, err) - assert.Equal(t, cache.Dir(), dir) - assert.False(t, fileutils.FileExists(cache.InfoJson())) // not yet - assert.Equal(t, cache.MaxSize(), int64(10)) - assert.Equal(t, cache.CurrentSize(), int64(0)) - assert.Empty(t, cache.Artifacts()) - - // Test cache.Get() with empty cache. - path, found := cache.Get(testArtifacts[1]) - assert.Empty(t, path) - assert.False(t, found) - - // Test cache.Store(). - testArtifactFile := osutil.GetTestFile("artifact-cache", string(testArtifacts[1])) - err = cache.Store(testArtifacts[1], testArtifactFile) - require.NoError(t, err) - assert.Equal(t, len(cache.Artifacts()), 1) - assert.Equal(t, cache.CurrentSize(), int64(1)) - // Verify artifacts can be overwritten. - err = cache.Store(testArtifacts[1], testArtifactFile) - require.NoError(t, err) - assert.Equal(t, len(cache.Artifacts()), 1) - assert.Equal(t, cache.CurrentSize(), int64(1)) - - cached := cache.Artifacts()[testArtifacts[1]] // will test cache.Get() later; avoid last access time update - assert.Equal(t, cached.Id, testArtifacts[1]) - assert.Equal(t, cached.ArchivePath, filepath.Join(cache.Dir(), string(testArtifacts[1]))) - assert.Equal(t, cached.Size, int64(1)) - assert.True(t, cached.LastAccessTime > 0) - - cachedFile := cached.ArchivePath - assert.True(t, fileutils.FileExists(cachedFile)) - assert.Equal(t, fileutils.ReadFileUnsafe(testArtifactFile), fileutils.ReadFileUnsafe(cachedFile)) - - // Test cache.Get() and last access time updating. - lastAccessTime := cached.LastAccessTime - time.Sleep(1 * time.Second) - path, found = cache.Get(testArtifacts[1]) - assert.Equal(t, path, cachedFile) - assert.True(t, found) - assert.True(t, cached.LastAccessTime > lastAccessTime) - - // Test cache.Store() and removing least-recently accessed artifacts. - time.Sleep(1 * time.Second) - cache.Store(testArtifacts[3], osutil.GetTestFile("artifact-cache", string(testArtifacts[3]))) - cache.Store(testArtifacts[5], osutil.GetTestFile("artifact-cache", string(testArtifacts[5]))) - assert.Equal(t, cache.CurrentSize(), int64(9)) - assert.Equal(t, len(cache.Artifacts()), 3) - - cache.Store(testArtifacts[2], osutil.GetTestFile("artifact-cache", string(testArtifacts[2]))) - assert.Equal(t, cache.CurrentSize(), int64(10)) - assert.Equal(t, len(cache.Artifacts()), 3) - assert.Nil(t, cache.Artifacts()[testArtifacts[1]]) - assert.NotNil(t, cache.Artifacts()[testArtifacts[2]]) - assert.NotNil(t, cache.Artifacts()[testArtifacts[3]]) - assert.NotNil(t, cache.Artifacts()[testArtifacts[5]]) - - // Test cache.Save(). - err = cache.Save() - require.NoError(t, err) - assert.True(t, fileutils.FileExists(cache.InfoJson())) - - reloaded, err := artifactcache.NewTestArtifactCache(cache.Dir(), 10) - require.NoError(t, err) - assert.Equal(t, reloaded.CurrentSize(), int64(10)) - assert.Equal(t, len(reloaded.Artifacts()), 3) - assert.NotNil(t, reloaded.Artifacts()[testArtifacts[2]]) - assert.NotNil(t, reloaded.Artifacts()[testArtifacts[3]]) - assert.NotNil(t, reloaded.Artifacts()[testArtifacts[5]]) - - // Test too small of a cache max size. - dir, err = os.MkdirTemp("", "") - require.NoError(t, err) - defer os.RemoveAll(dir) - - cache, err = artifactcache.NewTestArtifactCache(dir, 1) // bytes - require.NoError(t, err) - cache.Store(testArtifacts[1], osutil.GetTestFile("artifact-cache", string(testArtifacts[1]))) - cache.Store(testArtifacts[2], osutil.GetTestFile("artifact-cache", string(testArtifacts[2]))) // should not store nor erase existing artifacts - assert.Equal(t, cache.CurrentSize(), int64(1)) - assert.Equal(t, len(cache.Artifacts()), 1) - assert.NotNil(t, cache.Artifacts()[testArtifacts[1]]) -} diff --git a/test/integration/artifacts_int_test.go b/test/integration/artifacts_int_test.go index 50bffb0738..56de44972e 100644 --- a/test/integration/artifacts_int_test.go +++ b/test/integration/artifacts_int_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/runners/artifacts" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/termtest" @@ -29,16 +28,8 @@ func (suite *ArtifactsIntegrationTestSuite) TestArtifacts() { ts.PrepareProject("ActiveState-CLI/Python-With-Custom-Builds", "993454c7-6613-4b1a-8981-1cee43cc249e") - cp := ts.SpawnWithOpts( - e2e.OptArgs("refresh"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) - - // In order to reuse the runtime cache and reduce test time we run the rest in subtests - suite.Run("no flags", func() { - cp = ts.Spawn("artifacts") + cp := ts.Spawn("artifacts") cp.Expect("Operating on project ActiveState-CLI/Python-With-Custom-Builds, located at") cp.Expect("CentOS") cp.Expect("Docker Image") @@ -53,7 +44,7 @@ func (suite *ArtifactsIntegrationTestSuite) TestArtifacts() { }) suite.Run("--all flag", func() { - cp = ts.Spawn("artifacts", "--all") + cp := ts.Spawn("artifacts", "--all") cp.Expect("CentOS") cp.Expect("Docker Image") cp.Expect("Installer") @@ -69,12 +60,11 @@ func (suite *ArtifactsIntegrationTestSuite) TestArtifacts() { }) suite.Run("json without flags", func() { - cp = ts.SpawnWithOpts(e2e.OptArgs("artifacts", "--output=json"), e2e.OptTermTest(termtest.OptRows(100))) + cp := ts.SpawnWithOpts(e2e.OptArgs("artifacts", "--output=json"), e2e.OptTermTest(termtest.OptRows(100))) cp.ExpectExitCode(0) output := artifacts.StructuredOutput{} - out := strings.TrimLeft(cp.StrippedSnapshot(), locale.T("notice_runtime_disabled")) - suite.Require().NoError(json.Unmarshal([]byte(out), &output), ts.DebugMessage("")) + suite.Require().NoError(json.Unmarshal([]byte(cp.StrippedSnapshot()), &output), ts.DebugMessage("")) suite.Equal(3, len(output.Platforms)) for _, platform := range output.Platforms { @@ -86,12 +76,11 @@ func (suite *ArtifactsIntegrationTestSuite) TestArtifacts() { }) suite.Run("json with --all flag", func() { - cp = ts.SpawnWithOpts(e2e.OptArgs("artifacts", "--output=json", "--all"), e2e.OptTermTest(termtest.OptRows(500))) + cp := ts.SpawnWithOpts(e2e.OptArgs("artifacts", "--output=json", "--all"), e2e.OptTermTest(termtest.OptRows(500))) cp.ExpectExitCode(0) output := artifacts.StructuredOutput{} - out := strings.TrimLeft(cp.StrippedSnapshot(), locale.T("notice_runtime_disabled")) - suite.Require().NoError(json.Unmarshal([]byte(out), &output), ts.DebugMessage("")) + suite.Require().NoError(json.Unmarshal([]byte(cp.StrippedSnapshot()), &output), ts.DebugMessage("")) suite.Equal(3, len(output.Platforms)) for _, platform := range output.Platforms { @@ -161,12 +150,6 @@ func (suite *ArtifactsIntegrationTestSuite) TestArtifacts_Download() { ts.PrepareProject("ActiveState-CLI/Python-With-Custom-Builds", "993454c7-6613-4b1a-8981-1cee43cc249e") - cp := ts.SpawnWithOpts( - e2e.OptArgs("refresh"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) - var buildID string if runtime.GOOS == "windows" { // On Windows we need the specific build ID as the terminal buffer is not @@ -177,11 +160,9 @@ func (suite *ArtifactsIntegrationTestSuite) TestArtifacts_Download() { } suite.Require().NotEmpty(buildID) - cp = ts.SpawnWithOpts( - e2e.OptArgs("artifacts", "dl", buildID, "."), - ) + cp := ts.Spawn("artifacts", "dl", buildID, ".") cp.Expect("Operating on project ActiveState-CLI/Python-With-Custom-Builds, located at") - cp.Expect("Downloaded bzip2", e2e.RuntimeSourcingTimeoutOpt) + cp.Expect("Downloaded bzip2") cp.ExpectExitCode(0) require.FileExists(suite.T(), filepath.Join(ts.Dirs.Work, "bzip2-1.0.8.tar.gz"), ts.DebugMessage("")) } @@ -202,7 +183,7 @@ func (suite *ArtifactsIntegrationTestSuite) TestArtifacts_Download_Remote() { suite.Require().NotEmpty(buildID) cp := ts.Spawn("artifacts", "dl", buildID, ".", "--namespace", "ActiveState-CLI/Python-With-Custom-Builds") - cp.Expect("Downloaded bzip2", e2e.RuntimeSourcingTimeoutOpt) + cp.Expect("Downloaded bzip2") suite.Assert().NotContains(cp.Snapshot(), "Operating on project") cp.ExpectExitCode(0) require.FileExists(suite.T(), filepath.Join(ts.Dirs.Work, "bzip2-1.0.8.tar.gz")) @@ -214,9 +195,7 @@ func (suite *ArtifactsIntegrationTestSuite) extractBuildID(ts *e2e.Session, name args = append(args, "--namespace", namespace) } - cp := ts.SpawnWithOpts( - e2e.OptArgs(args...), - ) + cp := ts.Spawn(args...) cp.Expect(`"}`) cp.ExpectExitCode(0) diff --git a/test/integration/auth_int_test.go b/test/integration/auth_int_test.go index f4959fec92..c34dab906a 100644 --- a/test/integration/auth_int_test.go +++ b/test/integration/auth_int_test.go @@ -46,11 +46,11 @@ func (suite *AuthIntegrationTestSuite) TestAuthToken() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn(tagsuite.Auth, "--token", e2e.PersistentToken, "-n") + cp := ts.Spawn("auth", "--token", e2e.PersistentToken, "-n") cp.Expect("logged in", termtest.OptExpectTimeout(40*time.Second)) cp.ExpectExitCode(0) - cp = ts.Spawn(tagsuite.Auth, "--non-interactive") + cp = ts.Spawn("auth", "--non-interactive") cp.Expect("logged in", termtest.OptExpectTimeout(40*time.Second)) cp.ExpectExitCode(0) @@ -59,7 +59,7 @@ func (suite *AuthIntegrationTestSuite) TestAuthToken() { } func (suite *AuthIntegrationTestSuite) interactiveLogin(ts *e2e.Session, username, password string) { - cp := ts.Spawn(tagsuite.Auth, "--prompt") + cp := ts.Spawn("auth", "--prompt") cp.Expect("username:") cp.SendLine(username) cp.Expect("password:") @@ -68,20 +68,20 @@ func (suite *AuthIntegrationTestSuite) interactiveLogin(ts *e2e.Session, usernam cp.ExpectExitCode(0) // still logged in? - c2 := ts.Spawn(tagsuite.Auth) + c2 := ts.Spawn("auth") c2.Expect("You are logged in") c2.ExpectExitCode(0) } func (suite *AuthIntegrationTestSuite) loginFlags(ts *e2e.Session, username string) { - cp := ts.Spawn(tagsuite.Auth, "--username", username, "--password", "bad-password") - cp.Expect("You are not authorized, did you provide valid login credentials?") + cp := ts.Spawn("auth", "--username", username, "--password", "bad-password") + cp.Expect("You are not authorized. Did you provide valid login credentials?") cp.ExpectExitCode(1) ts.IgnoreLogErrors() } func (suite *AuthIntegrationTestSuite) ensureLogout(ts *e2e.Session) { - cp := ts.Spawn(tagsuite.Auth, "--prompt") + cp := ts.Spawn("auth", "--prompt") cp.Expect("username:") cp.SendCtrlC() } @@ -101,7 +101,7 @@ func (suite *AuthIntegrationTestSuite) authOutput(method string) { expected := string(data) ts.LoginAsPersistentUser() - cp := ts.Spawn(tagsuite.Auth, "--output", method) + cp := ts.Spawn("auth", "--output", method) cp.Expect(`"}`) cp.ExpectExitCode(0) suite.Contains(cp.Output(), string(expected)) diff --git a/test/integration/branch_int_test.go b/test/integration/branch_int_test.go index a229d412dc..e437c36344 100644 --- a/test/integration/branch_int_test.go +++ b/test/integration/branch_int_test.go @@ -40,12 +40,9 @@ func (suite *BranchIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Branches", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareProject("ActiveState-CLI/Branches", e2e.CommitIDNotChecked) - cp = ts.Spawn("branch", "-o", "json") + cp := ts.Spawn("branch", "-o", "json") cp.Expect(`"branchID":`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) diff --git a/test/integration/buildscript_int_test.go b/test/integration/buildscript_int_test.go index 03876060d4..adaf3e9ae6 100644 --- a/test/integration/buildscript_int_test.go +++ b/test/integration/buildscript_int_test.go @@ -1,15 +1,24 @@ package integration import ( + "archive/zip" + "encoding/json" "fmt" "path/filepath" + "runtime" "testing" + "time" "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/environment" + "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/rtutils" + "github.com/ActiveState/cli/internal/runners/artifacts" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/ActiveState/cli/pkg/projectfile" + "github.com/ActiveState/termtest" ) type BuildScriptIntegrationTestSuite struct { @@ -22,23 +31,134 @@ func (suite *BuildScriptIntegrationTestSuite) TestBuildScript_NeedsReset() { defer ts.Close() ts.PrepareActiveStateYAML(fmt.Sprintf("project: https://%s/%s?commitID=%s\nconfig_version: %d\n", - constants.DefaultAPIHost, "ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b", projectfile.ConfigVersion)) + constants.DefaultAPIHost, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8", projectfile.ConfigVersion)) cp := ts.Spawn("config", "set", constants.OptinBuildscriptsConfig, "true") cp.ExpectExitCode(0) suite.Require().NoFileExists(filepath.Join(ts.Dirs.Work, constants.BuildScriptFileName)) - cp = ts.SpawnWithOpts(e2e.OptArgs("refresh"), e2e.OptAppendEnv(constants.DisableRuntime+"=false")) + cp = ts.Spawn("refresh") cp.Expect("Your project is missing its buildscript file") cp.ExpectExitCode(1) - cp = ts.SpawnWithOpts(e2e.OptArgs("reset", "LOCAL"), e2e.OptAppendEnv(constants.DisableRuntime+"=false")) - cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("reset", "LOCAL") + cp.ExpectExitCode(0) suite.Require().FileExists(filepath.Join(ts.Dirs.Work, constants.BuildScriptFileName), ts.DebugMessage("")) } +func (suite *BuildScriptIntegrationTestSuite) TestBuildScript_IngredientFunc() { + suite.OnlyRunForTags(tagsuite.BuildScripts) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.LoginAsPersistentUser() + + projectURL := fmt.Sprintf("https://%s/%s?commitID=%s", constants.DefaultAPIHost, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") + ts.PrepareActiveStateYAML(fmt.Sprintf("project: %s\nconfig_version: %d\n", projectURL, projectfile.ConfigVersion)) + + var platformID string + switch runtime.GOOS { + case "windows": + platformID = constants.Win10Bit64UUID + case "darwin": + platformID = constants.MacBit64UUID + default: + platformID = constants.LinuxBit64UUID + } + + denoter := "```" + ts.PrepareBuildScript(fmt.Sprintf(` +%s +Project: %s +Time: "2024-10-30T21:31:33.000Z" +%s +wheel = make_wheel( + at_time = at_time, + src = tag( + plan = ingredient( + build_deps = [ + Req(name = "python-module-builder", namespace = "builder", version = Gte(value = "0")), + Req(name = "python", namespace = "language", version = Gte(value = "3")), + Req(name = "setuptools", namespace = "language/python", version = Gte(value = "43.0.0")), + Req(name = "wheel", namespace = "language/python", version = Gte(value = "0")) + ], + src = [ + "sample_ingredient/**" + ] + ), + tag = "platform:%s" + ) +) + +main = wheel +`, denoter, projectURL, denoter, platformID)) + + // Prepare sample ingredient source files + root := environment.GetRootPathUnsafe() + sampleSource := filepath.Join(root, "test", "integration", "testdata", "sample_ingredient") + sampleTarget := filepath.Join(ts.Dirs.Work, "sample_ingredient") + suite.Require().NoError(fileutils.Mkdir(sampleTarget)) + suite.Require().NoError(fileutils.CopyFiles(sampleSource, sampleTarget)) + + // Create a new commit, which will use the source files to create an ingredient if it doesn't already exist + cp := ts.Spawn("commit") + cp.ExpectExitCode(0, e2e.RuntimeSolvingTimeoutOpt, termtest.OptExpectErrorMessage(ts.DebugMessage(""))) + + // Running commit again should say there are no changes + // If this fails then there's likely an issue with calculating the file hash, or checking whether an ingredient + // already exists with the given hash. + cp = ts.Spawn("commit") + cp.Expect("no new changes") + cp.ExpectExit() + + // Commit should've given us the hash + suite.Contains(string(fileutils.ReadFileUnsafe(filepath.Join(ts.Dirs.Work, constants.BuildScriptFileName))), "hash_readonly") + + // Wait for build + var out artifacts.StructuredOutput + suite.Require().NoError(rtutils.Timeout(func() error { + for { + cp = ts.Spawn("artifacts", "--output=json") + if err := cp.ExpectExitCode(0, termtest.OptExpectSilenceErrorHandler()); err != nil { + return err + } + + if err := json.Unmarshal(AssertValidJSON(suite.T(), cp), &out); err != nil { + return err + } + if out.BuildComplete { + break + } + time.Sleep(time.Second * 5) + } + return nil + }, e2e.RuntimeBuildSourcingTimeout), ts.DebugMessage("")) + + // Ensure build didn't fail + suite.False(out.HasFailedArtifacts) + suite.Empty(out.Platforms[0].Artifacts[0].Errors, "Log: %s", out.Platforms[0].Artifacts[0].LogURL) + + // Download the wheel artifact that was produced from our source ingredient + cp = ts.Spawn("artifacts", "dl", "--output=json", out.Platforms[0].Artifacts[0].ID) + cp.ExpectExitCode(0) + + var path string + suite.Require().NoError(json.Unmarshal(AssertValidJSON(suite.T(), cp), &path)) + + // Read wheel archive and ensure it contains the expected files + zipReader, err := zip.OpenReader(path) + suite.Require().NoError(err) + defer zipReader.Close() + files := map[string]struct{}{} + for _, f := range zipReader.File { + files[f.Name] = struct{}{} + } + suite.Contains(files, "sample_activestate/__init__.py") + suite.Contains(files, "sample_activestate-1.0.0.dist-info/WHEEL") +} + func TestBuildScriptIntegrationTestSuite(t *testing.T) { suite.Run(t, new(BuildScriptIntegrationTestSuite)) } diff --git a/test/integration/bundle_int_test.go b/test/integration/bundle_int_test.go index cef8b72d85..58ca8caa0a 100644 --- a/test/integration/bundle_int_test.go +++ b/test/integration/bundle_int_test.go @@ -3,6 +3,7 @@ package integration import ( "testing" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -35,6 +36,24 @@ func (suite *BundleIntegrationTestSuite) TestBundle_project_name_noData() { cp.ExpectExitCode(0) } +func (suite *BundleIntegrationTestSuite) TestBundle_install_uninstall() { + suite.OnlyRunForTags(tagsuite.Bundle) + ts := e2e.New(suite.T(), false) + defer ts.Close() + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("bundles", "install", "python-module-build-support") + cp.Expect("project has been updated") + cp.ExpectExitCode(0) + + cp = ts.Spawn("bundles", "uninstall", "python-module-build-support") + cp.Expect("project has been updated") + cp.ExpectExitCode(0) +} + func (suite *BundleIntegrationTestSuite) TestBundle_searchSimple() { suite.OnlyRunForTags(tagsuite.Bundle) ts := e2e.New(suite.T(), false) @@ -63,32 +82,15 @@ func (suite *BundleIntegrationTestSuite) TestJSON() { suite.OnlyRunForTags(tagsuite.Bundle, tagsuite.JSON) ts := e2e.New(suite.T(), false) defer ts.Close() + suite.PrepareActiveStateYAML(ts) cp := ts.Spawn("bundles", "search", "Email", "--language", "Perl", "-o", "json") cp.Expect(`"Name":"Email"`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Bundles", "."), - e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), - ) - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - - cp = ts.SpawnWithOpts( - e2e.OptArgs("bundles", "install", "Testing", "--output", "json"), - ) - cp.Expect(`"name":"Testing"`) + cp = ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) - AssertValidJSON(suite.T(), cp) - - cp = ts.SpawnWithOpts( - e2e.OptArgs("bundles", "uninstall", "Testing", "-o", "editor"), - ) - cp.Expect(`"name":"Testing"`) - cp.ExpectExitCode(0) - AssertValidJSON(suite.T(), cp) } func TestBundleIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/checkout_int_test.go b/test/integration/checkout_int_test.go index 4bf4cb93cb..e73e621326 100644 --- a/test/integration/checkout_int_test.go +++ b/test/integration/checkout_int_test.go @@ -9,15 +9,19 @@ import ( "strings" "testing" + "github.com/mholt/archiver/v3" + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/environment" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/osutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" + "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" + rt "github.com/ActiveState/cli/pkg/runtime" + "github.com/ActiveState/cli/pkg/runtime_helpers" ) type CheckoutIntegrationTestSuite struct { @@ -31,10 +35,7 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutPython() { defer ts.Close() // Checkout and verify. - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9", "."), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/Python-3.9", ".") cp.Expect("Checking out project: ActiveState-CLI/Python-3.9") cp.Expect("Setting up the following dependencies:") cp.Expect("All dependencies have been installed and verified", e2e.RuntimeSourcingTimeoutOpt) @@ -44,32 +45,13 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutPython() { suite.Require().True(fileutils.FileExists(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)), "ActiveState-CLI/Python3 was not checked out properly") // Verify runtime was installed correctly and works. - targetDir := target.ProjectDirToTargetDir(ts.Dirs.Work, ts.Dirs.Cache) - pythonExe := filepath.Join(setup.ExecDir(targetDir), "python3"+osutils.ExeExtension) + proj, err := project.FromPath(ts.Dirs.Work) + suite.Require().NoError(err) + targetDir := filepath.Join(ts.Dirs.Cache, runtime_helpers.DirNameFromProjectDir(proj.Dir())) + pythonExe := filepath.Join(rt.ExecutorsPath(targetDir), "python3"+osutils.ExeExtension) cp = ts.SpawnCmd(pythonExe, "--version") cp.Expect("Python 3") cp.ExpectExitCode(0) - - suite.Run("Cached", func() { - artifactCacheDir := filepath.Join(ts.Dirs.Cache, constants.ArtifactMetaDir) - projectCacheDir := target.ProjectDirToTargetDir(ts.Dirs.Work, ts.Dirs.Cache) - suite.Require().NotEmpty(fileutils.ListFilesUnsafe(artifactCacheDir), "Artifact cache dir should have files") - suite.Require().NotEmpty(fileutils.ListFilesUnsafe(projectCacheDir), "Project cache dir should have files") - - suite.Require().NoError(os.RemoveAll(projectCacheDir)) // Ensure we can hit the cache by deleting the cache - suite.Require().NoError(os.Remove(filepath.Join(ts.Dirs.Work, constants.ConfigFileName))) // Ensure we can do another checkout - - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9", "."), - e2e.OptAppendEnv( - constants.DisableRuntime+"=false", - "VERBOSE=true", // Necessary to assert "Fetched cached artifact" - ), - ) - cp.Expect("Fetched cached artifact", e2e.RuntimeSourcingTimeoutOpt) // Comes from log, which is why we're using VERBOSE=true - cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectExitCode(0) - }) } func (suite *CheckoutIntegrationTestSuite) TestCheckoutPerl() { @@ -79,21 +61,22 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutPerl() { defer ts.Close() // Checkout and verify. - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Perl-Alternative", "."), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/Perl-Alternative", ".") cp.Expect("Checking out project: ") cp.Expect("Setting up the following dependencies:") cp.Expect("All dependencies have been installed and verified", e2e.RuntimeSourcingTimeoutOpt) cp.Expect("Checked out project") // Verify runtime was installed correctly and works. - targetDir := target.ProjectDirToTargetDir(ts.Dirs.Work, ts.Dirs.Cache) - perlExe := filepath.Join(setup.ExecDir(targetDir), "perl"+osutils.ExeExtension) + proj, err := project.FromPath(ts.Dirs.Work) + suite.Require().NoError(err) + + execPath := rt.ExecutorsPath(filepath.Join(ts.Dirs.Cache, runtime_helpers.DirNameFromProjectDir(proj.Dir()))) + perlExe := filepath.Join(execPath, "perl"+osutils.ExeExtension) + cp = ts.SpawnCmd(perlExe, "--version") cp.Expect("This is perl") - cp.ExpectExitCode(0) + cp.ExpectExit() } func (suite *CheckoutIntegrationTestSuite) TestCheckoutNonEmptyDir() { @@ -109,9 +92,7 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutNonEmptyDir() { suite.Require().NoError(err2, "could not write test file") // Checkout and verify. - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python3", tmpdir), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty", tmpdir) cp.Expect("already a project checked out at") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -122,9 +103,7 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutNonEmptyDir() { // remove file suite.Require().NoError(os.Remove(filepath.Join(tmpdir, constants.ConfigFileName))) - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python3", tmpdir), - ) + cp = ts.Spawn("checkout", "ActiveState-CLI/Empty", tmpdir) cp.Expect("Checked out project") cp.ExpectExitCode(0) } @@ -141,10 +120,9 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutMultiDir() { for x, dir := range dirs { cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python3", "."), + e2e.OptArgs("checkout", "ActiveState-CLI/Empty", "."), e2e.OptWD(dir), ) - cp.Expect("Skipping runtime setup") cp.Expect("Checked out") cp.ExpectExitCode(0) suite.Require().FileExists(filepath.Join(dir, constants.ConfigFileName), "Dir %d", x) @@ -158,27 +136,25 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutWithFlags() { defer ts.Close() // Test checking out to current working directory. - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3", ".")) - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty", ".") cp.Expect("Checked out") cp.Expect(ts.Dirs.Work) - suite.Assert().True(fileutils.FileExists(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)), "ActiveState-CLI/Python3 was not checked out to the current working directory") + suite.Assert().True(fileutils.FileExists(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)), "ActiveState-CLI/Empty was not checked out to the current working directory") // Test checkout out to a generic path. - python3Dir := filepath.Join(ts.Dirs.Work, "MyPython3") - cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3#6d9280e7-75eb-401a-9e71-0d99759fbad3", python3Dir)) - cp.Expect("Skipping runtime setup") + projectDir := filepath.Join(ts.Dirs.Work, "MyProject") + cp = ts.Spawn("checkout", "ActiveState-CLI/Empty#6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8", projectDir) cp.Expect("Checked out") cp.ExpectExitCode(0) - suite.Require().True(fileutils.DirExists(python3Dir), "state checkout should have created "+python3Dir) - asy := filepath.Join(python3Dir, constants.ConfigFileName) - suite.Require().True(fileutils.FileExists(asy), "ActiveState-CLI/Python3 was not checked out properly") - suite.Assert().True(bytes.Contains(fileutils.ReadFileUnsafe(asy), []byte("6d9280e7-75eb-401a-9e71-0d99759fbad3")), "did not check out specific commit ID") + suite.Require().True(fileutils.DirExists(projectDir), "state checkout should have created "+projectDir) + asy := filepath.Join(projectDir, constants.ConfigFileName) + suite.Require().True(fileutils.FileExists(asy), "ActiveState-CLI/Empty was not checked out properly") + suite.Assert().True(bytes.Contains(fileutils.ReadFileUnsafe(asy), []byte("6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8")), "did not check out specific commit ID") // Test --branch mismatch in non-checked-out project. branchPath := filepath.Join(ts.Dirs.Base, "branch") - cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9", branchPath, "--branch", "doesNotExist")) + cp = ts.Spawn("checkout", "ActiveState-CLI/Empty", branchPath, "--branch", "doesNotExist") cp.Expect("This project has no branch with label matching 'doesNotExist'") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -187,7 +163,7 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutWithFlags() { func (suite *CheckoutIntegrationTestSuite) TestCheckoutCustomRTPath() { suite.OnlyRunForTags(tagsuite.Checkout) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() customRTPath, err := fileutils.ResolveUniquePath(filepath.Join(ts.Dirs.Work, "custom-cache")) @@ -196,13 +172,10 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutCustomRTPath() { suite.Require().NoError(err) // Checkout and verify. - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python3", fmt.Sprintf("--runtime-path=%s", customRTPath)), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/Python3", fmt.Sprintf("--runtime-path=%s", customRTPath)) cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) - pythonExe := filepath.Join(setup.ExecDir(customRTPath), "python3"+osutils.ExeExtension) + pythonExe := filepath.Join(rt.ExecutorsPath(customRTPath), "python3"+osutils.ExeExtension) suite.Require().True(fileutils.DirExists(customRTPath)) suite.Require().True(fileutils.FileExists(pythonExe)) @@ -214,15 +187,10 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutCustomRTPath() { // Verify that state exec works with custom cache. cp = ts.SpawnWithOpts( e2e.OptArgs("exec", "python3", "--", "-c", "import sys;print(sys.executable)"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), e2e.OptWD(filepath.Join(ts.Dirs.Work, "Python3")), ) - if runtime.GOOS == "windows" { - customRTPath, err = fileutils.GetLongPathName(customRTPath) - suite.Require().NoError(err) - customRTPath = strings.ToUpper(customRTPath[:1]) + strings.ToLower(customRTPath[1:]) // capitalize drive letter - } cp.Expect(customRTPath, e2e.RuntimeSourcingTimeoutOpt) + cp.ExpectExit() } func (suite *CheckoutIntegrationTestSuite) TestCheckoutNotFound() { @@ -231,7 +199,7 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutNotFound() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Bogus-Project-That-Doesnt-Exist")) + cp := ts.Spawn("checkout", "ActiveState-CLI/Bogus-Project-That-Doesnt-Exist") cp.Expect("does not exist under") // error cp.Expect("If this is a private project") // tip cp.ExpectExitCode(1) @@ -248,11 +216,11 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutAlreadyCheckedOut() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python")) + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") cp.Expect("Checked out project") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python")) + cp = ts.Spawn("checkout", "ActiveState-CLI/Empty") cp.Expect("already a project checked out at") cp.ExpectNotExitCode(0) ts.IgnoreLogErrors() @@ -263,11 +231,11 @@ func (suite *CheckoutIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "-o", "json")) + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty", "-o", "json") cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) - cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Bogus-Project-That-Doesnt-Exist", "-o", "json")) + cp = ts.Spawn("checkout", "ActiveState-CLI/Bogus-Project-That-Doesnt-Exist", "-o", "json") cp.Expect("does not exist") // error cp.Expect(`"tips":["If this is a private project`) // tip cp.ExpectNotExitCode(0) @@ -281,14 +249,13 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutCaseInsensitive() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ACTIVESTATE-CLI/SMALL-PYTHON")) - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("checkout", "ACTIVESTATE-CLI/EMPTY") cp.Expect("Checked out project") cp.ExpectExitCode(0) - bytes := fileutils.ReadFileUnsafe(filepath.Join(ts.Dirs.Work, "SMALL-PYTHON", constants.ConfigFileName)) - suite.Assert().Contains(string(bytes), "ActiveState-CLI/small-python", "did not match namespace case") - suite.Assert().NotContains(string(bytes), "ACTIVESTATE-CLI/SMALL-PYTHON", "kept incorrect namespace case") + bytes := fileutils.ReadFileUnsafe(filepath.Join(ts.Dirs.Work, "EMPTY", constants.ConfigFileName)) + suite.Assert().Contains(string(bytes), "ActiveState-CLI/Empty", "did not match namespace case") + suite.Assert().NotContains(string(bytes), "ACTIVESTATE-CLI/EMPTY", "kept incorrect namespace case") } func (suite *CheckoutIntegrationTestSuite) TestCheckoutBuildtimeClosure() { @@ -303,8 +270,7 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutBuildtimeClosure() { cp := ts.SpawnWithOpts( e2e.OptArgs("checkout", "ActiveState-CLI/small-python#5a1e49e5-8ceb-4a09-b605-ed334474855b"), - e2e.OptAppendEnv(constants.InstallBuildDependencies+"=true"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), + e2e.OptAppendEnv(constants.InstallBuildDependenciesEnvVarName+"=true"), ) // Expect the number of build deps to be 27 which is more than the number of runtime deps. // Also expect ncurses which should not be in the runtime closure. @@ -318,27 +284,18 @@ func (suite *CheckoutIntegrationTestSuite) TestFail() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/fail"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/fail") cp.Expect("failed to build") cp.ExpectNotExitCode(0) suite.Assert().NoDirExists(filepath.Join(ts.Dirs.Work, "fail"), "state checkout fail did not remove created directory") ts.IgnoreLogErrors() - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/fail", "."), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("checkout", "ActiveState-CLI/fail", ".") cp.Expect("failed to build") cp.ExpectNotExitCode(0) suite.Assert().NoFileExists(filepath.Join(ts.Dirs.Work, constants.ConfigFileName), "state checkout fail did not remove created activestate.yaml") - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/fail", "--force"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("checkout", "ActiveState-CLI/fail", "--force") cp.Expect("failed to build") cp.ExpectNotExitCode(0) suite.Assert().DirExists(filepath.Join(ts.Dirs.Work, "fail"), "state checkout fail did not leave created directory there despite --force flag override") @@ -349,23 +306,21 @@ func (suite *CheckoutIntegrationTestSuite) TestBranch() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Branches", "--branch", "firstbranch", ".") - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty", "--branch", "mingw", ".") cp.Expect("Checked out") cp.ExpectExitCode(0) asy := filepath.Join(ts.Dirs.Work, constants.ConfigFileName) - suite.Assert().Contains(string(fileutils.ReadFileUnsafe(asy)), "branch=firstbranch", "activestate.yaml does not have correct branch") + suite.Assert().Contains(string(fileutils.ReadFileUnsafe(asy)), "branch=mingw", "activestate.yaml does not have correct branch") suite.Require().NoError(os.Remove(asy)) // Infer branch name from commit. - cp = ts.Spawn("checkout", "ActiveState-CLI/Branches#46c83477-d580-43e2-a0c6-f5d3677517f1", ".") - cp.Expect("Skipping runtime setup") + cp = ts.Spawn("checkout", "ActiveState-CLI/Empty#830c81b1-95e7-4de0-b48e-4f4579cba794", ".") cp.Expect("Checked out") cp.ExpectExitCode(0) - suite.Assert().Contains(string(fileutils.ReadFileUnsafe(asy)), "branch=secondbranch", "activestate.yaml does not have correct branch") + suite.Assert().Contains(string(fileutils.ReadFileUnsafe(asy)), "branch=mingw", "activestate.yaml does not have correct branch") } func (suite *CheckoutIntegrationTestSuite) TestNoLanguage() { @@ -377,11 +332,8 @@ func (suite *CheckoutIntegrationTestSuite) TestNoLanguage() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/langless", "."), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) + cp := ts.Spawn("checkout", "ActiveState-CLI/langless", ".") + cp.Expect("Checked out project") cp.ExpectExitCode(0) } @@ -391,7 +343,6 @@ func (suite *CheckoutIntegrationTestSuite) TestChangeSummary() { defer ts.Close() cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") - cp.Expect("Successfully set") cp.ExpectExitCode(0) cp = ts.Spawn("checkout", "ActiveState-CLI/small-python") @@ -403,6 +354,47 @@ func (suite *CheckoutIntegrationTestSuite) TestChangeSummary() { cp.ExpectExitCode(0) } +func (suite *CheckoutIntegrationTestSuite) TestCveReport() { + suite.OnlyRunForTags(tagsuite.Checkout) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.LoginAsPersistentUser() + + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") + cp.Expect("Checking for vulnerabilities") + cp.ExpectExitCode(0) +} + +func (suite *CheckoutIntegrationTestSuite) TestCheckoutFromArchive() { + suite.OnlyRunForTags(tagsuite.Checkout) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + root := environment.GetRootPathUnsafe() + dir := filepath.Join(root, "test", "integration", "testdata", "checkout-from-archive", runtime.GOOS) + tgz := fileutils.TempFilePath("", runtime.GOOS+".tar.gz") + files, err := fileutils.ListDirSimple(dir, false) + suite.Require().NoError(err) + gz := archiver.TarGz{Tar: &archiver.Tar{StripComponents: 1000}} // use a big number to strip all leading dirs + suite.Require().NoError(gz.Archive(files, tgz)) + defer os.Remove(tgz) + + cp := ts.SpawnWithOpts( + e2e.OptArgs("checkout", tgz), + e2e.OptAppendEnv("HTTPS_PROXY=none://"), // simulate lack of network connection + ) + cp.Expect("Checking out project: ActiveState-CLI/AlmostEmpty") + cp.Expect("Setting up the following dependencies:") + cp.Expect("└─ provides_hello@0.0.1") + cp.Expect("Sourcing Runtime") + cp.Expect("Unpacking") + cp.Expect("Installing") + cp.Expect("All dependencies have been installed and verified") + cp.Expect("Checked out project ActiveState-CLI/AlmostEmpty") + cp.ExpectExitCode(0) +} + func TestCheckoutIntegrationTestSuite(t *testing.T) { suite.Run(t, new(CheckoutIntegrationTestSuite)) } diff --git a/test/integration/commit_int_test.go b/test/integration/commit_int_test.go index 2af43c1c3f..3904e72793 100644 --- a/test/integration/commit_int_test.go +++ b/test/integration/commit_int_test.go @@ -8,7 +8,7 @@ import ( "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" - "github.com/ActiveState/cli/internal/runbits/buildscript" + buildscript_runbit "github.com/ActiveState/cli/internal/runbits/buildscript" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -45,15 +45,18 @@ func (suite *CommitIntegrationTestSuite) TestCommitManualBuildScriptMod() { data = bytes.ReplaceAll(data, []byte("casestyle"), []byte("case")) suite.Require().NoError(fileutils.WriteFile(scriptPath, data), "Update buildscript") - cp = ts.SpawnWithOpts( - e2e.OptArgs("commit"), - ) + ts.LoginAsPersistentUser() // for CVE reporting + + cp = ts.Spawn("commit") + cp.Expect("Operating on project") + cp.Expect("Creating commit") + cp.Expect("Resolving Dependencies") + cp.Expect("Installing case@") + cp.Expect("Checking for vulnerabilities") cp.Expect("successfully created") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("pkg"), - ) + cp = ts.Spawn("pkg") cp.Expect("case ", e2e.RuntimeSourcingTimeoutOpt) // note: intentional trailing whitespace to not match 'casestyle' cp.ExpectExitCode(0) } @@ -72,11 +75,11 @@ func (suite *CommitIntegrationTestSuite) TestCommitAtTimeChange() { suite.Require().NoError(err) // verify validity // Update top-level at_time variable. - dateTime := "2023-03-01T12:34:56.789Z" + dateTime := "2023-06-21T12:34:56Z" buildScriptFile := filepath.Join(proj.Dir(), constants.BuildScriptFileName) contents, err := fileutils.ReadFile(buildScriptFile) suite.Require().NoError(err) - contents = bytes.Replace(contents, []byte("2023-06-22T21:56:10.504Z"), []byte(dateTime), 1) + contents = bytes.Replace(contents, []byte("2023-06-22T21:56:10Z"), []byte(dateTime), 1) suite.Require().NoError(fileutils.WriteFile(buildScriptFile, contents)) suite.Require().Contains(string(fileutils.ReadFileUnsafe(filepath.Join(proj.Dir(), constants.BuildScriptFileName))), dateTime) diff --git a/test/integration/condition_int_test.go b/test/integration/condition_int_test.go index bff6c30d83..374fe5fe0a 100644 --- a/test/integration/condition_int_test.go +++ b/test/integration/condition_int_test.go @@ -5,10 +5,8 @@ import ( "strings" "testing" - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/testhelpers/suite" - "github.com/ActiveState/cli/internal/testhelpers/e2e" + "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" ) @@ -23,9 +21,7 @@ func (suite *ConditionIntegrationTestSuite) TestCondition() { suite.PrepareActiveStateYAML(ts) - cp := ts.SpawnWithOpts( - e2e.OptArgs("run", "test"), - ) + cp := ts.Spawn("run", "test") cp.Expect(`projectNameValue`) cp.Expect(`projectOwnerValue`) cp.Expect(`projectNamespaceValue`) @@ -35,24 +31,20 @@ func (suite *ConditionIntegrationTestSuite) TestCondition() { cp.Expect(`shellValue`) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("activate"), - e2e.OptAppendEnv(constants.DisableActivateEventsEnvVarName+"=false"), - ) - cp.Expect(`Activation Event Ran`) - cp.ExpectInput() - cp.SendLine("exit") - cp.ExpectExitCode(0) + if runtime.GOOS != "windows" { + // https://activestatef.atlassian.net/browse/DX-2925 + cp = ts.Spawn("activate") + cp.Expect(`Activation Event Ran`) + cp.ExpectInput() + cp.SendLine("exit") + cp.ExpectExitCode(0) + } - cp = ts.SpawnWithOpts( - e2e.OptArgs("run", "complex-true"), - ) + cp = ts.Spawn("run", "complex-true") cp.Expect(`I exist`) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("run", "complex-false"), - ) + cp = ts.Spawn("run", "complex-false") cp.ExpectExitCode(1) } @@ -63,9 +55,7 @@ func (suite *ConditionIntegrationTestSuite) TestMixin() { suite.PrepareActiveStateYAML(ts) - cp := ts.SpawnWithOpts( - e2e.OptArgs("run", "MixinUser"), - ) + cp := ts.Spawn("run", "MixinUser") cp.ExpectExitCode(0) suite.Assert().NotContains(cp.Output(), "authenticated: yes", "expected not to be authenticated, output was:\n%s.", cp.Output()) suite.Assert().NotContains(cp.Output(), e2e.PersistentUsername, "expected not to be authenticated, output was:\n%s", cp.Output()) @@ -73,9 +63,7 @@ func (suite *ConditionIntegrationTestSuite) TestMixin() { ts.LoginAsPersistentUser() defer ts.LogoutUser() - cp = ts.SpawnWithOpts( - e2e.OptArgs("run", "MixinUser"), - ) + cp = ts.Spawn("run", "MixinUser") cp.Expect("authenticated: yes") cp.Expect(e2e.PersistentUsername) cp.ExpectExitCode(0) @@ -88,9 +76,7 @@ func (suite *ConditionIntegrationTestSuite) TestConditionOSName() { suite.PrepareActiveStateYAML(ts) - cp := ts.SpawnWithOpts( - e2e.OptArgs("run", "OSName"), - ) + cp := ts.Spawn("run", "OSName") switch runtime.GOOS { case "windows": cp.Expect(`using-windows`) @@ -109,9 +95,7 @@ func (suite *ConditionIntegrationTestSuite) TestConditionSyntaxError() { suite.PrepareActiveStateYAMLWithSyntaxError(ts) - cp := ts.SpawnWithOpts( - e2e.OptArgs("run", "test"), - ) + cp := ts.Spawn("run", "test") cp.Expect(`not defined`) // for now we aren't passing the error up the chain, so invalid syntax will lead to empty result cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -119,7 +103,7 @@ func (suite *ConditionIntegrationTestSuite) TestConditionSyntaxError() { func (suite *ConditionIntegrationTestSuite) PrepareActiveStateYAML(ts *e2e.Session) { asyData := strings.TrimSpace(` -project: https://platform.activestate.com/ActiveState-CLI/test +project: https://platform.activestate.com/ActiveState-CLI/Empty constants: - name: projectName value: invalidProjectName @@ -211,18 +195,18 @@ events: if: false - name: ACTIVATE value: echo "Activation Event Ran" - if: ne .Shell "" + if: ne .OS.Name "" - name: ACTIVATE value: echo "Wrong event" if: false `) ts.PrepareActiveStateYAML(asyData) - ts.PrepareCommitIdFile("9090c128-e948-4388-8f7f-96e2c1e00d98") + ts.PrepareCommitIdFile("6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") } func (suite *ConditionIntegrationTestSuite) PrepareActiveStateYAMLWithSyntaxError(ts *e2e.Session) { asyData := strings.TrimSpace(` -project: https://platform.activestate.com/ActiveState-CLI/test +project: https://platform.activestate.com/ActiveState-CLI/Empty scripts: - name: test language: bash @@ -237,7 +221,7 @@ scripts: `) ts.PrepareActiveStateYAML(asyData) - ts.PrepareCommitIdFile("9090c128-e948-4388-8f7f-96e2c1e00d98") + ts.PrepareCommitIdFile("6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") } func TestConditionIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/config_int_test.go b/test/integration/config_int_test.go index 4a2bdd8b00..df2021309e 100644 --- a/test/integration/config_int_test.go +++ b/test/integration/config_int_test.go @@ -1,12 +1,14 @@ package integration import ( + "strings" "testing" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" + vulnModel "github.com/ActiveState/cli/pkg/platform/api/vulnerabilities/model" ) type ConfigIntegrationTestSuite struct { @@ -41,6 +43,33 @@ func (suite *ConfigIntegrationTestSuite) TestConfig() { cp.Expect("Invalid boolean value") } +func (suite *ConfigIntegrationTestSuite) TestEnum() { + suite.OnlyRunForTags(tagsuite.Config) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + cp := ts.Spawn("config", "get", constants.SecurityPromptLevelConfig) + cp.Expect(vulnModel.SeverityCritical) + + severities := []string{ + vulnModel.SeverityCritical, + vulnModel.SeverityHigh, + vulnModel.SeverityMedium, + vulnModel.SeverityLow, + } + + cp = ts.Spawn("config", "set", constants.SecurityPromptLevelConfig, "invalid") + cp.Expect("Invalid value 'invalid': expected one of: " + strings.Join(severities, ", ")) + cp.ExpectNotExitCode(0) + + cp = ts.Spawn("config", "set", constants.SecurityPromptLevelConfig, vulnModel.SeverityLow) + cp.ExpectExitCode(0) + + cp = ts.Spawn("config", "get", constants.SecurityPromptLevelConfig) + cp.Expect(vulnModel.SeverityLow) + cp.ExpectExitCode(0) +} + func (suite *ConfigIntegrationTestSuite) TestJSON() { suite.OnlyRunForTags(tagsuite.Config, tagsuite.JSON) ts := e2e.New(suite.T(), false) @@ -59,6 +88,33 @@ func (suite *ConfigIntegrationTestSuite) TestJSON() { AssertValidJSON(suite.T(), cp) } +func (suite *ConfigIntegrationTestSuite) TestList() { + suite.OnlyRunForTags(tagsuite.Config) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + cp := ts.Spawn("config") + cp.Expect("Key") + cp.Expect("Value") + cp.Expect("Default") + cp.Expect("optin.buildscripts") + cp.Expect("false") + cp.ExpectExitCode(0) + + cp = ts.Spawn("config", "set", "optin.buildscripts", "true") + cp.Expect("Successfully") + cp.ExpectExitCode(0) + + cp = ts.Spawn("config") + cp.Expect("Key") + cp.Expect("Value") + cp.Expect("Default") + cp.Expect("optin.buildscripts") + cp.Expect("true*") + cp.ExpectExitCode(0) + + suite.Require().NotContains(cp.Snapshot(), constants.AsyncRuntimeConfig) +} func TestConfigIntegrationTestSuite(t *testing.T) { suite.Run(t, new(ConfigIntegrationTestSuite)) } diff --git a/test/integration/cve_int_test.go b/test/integration/cve_int_test.go index 5dfbea97cf..2ba993b974 100644 --- a/test/integration/cve_int_test.go +++ b/test/integration/cve_int_test.go @@ -80,16 +80,13 @@ func (suite *CveIntegrationTestSuite) TestJSON() { ts.LoginAsPersistentUser() - cp := ts.Spawn("checkout", "ActiveState-CLI/Perl", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() - cp = ts.Spawn("cve", "-o", "editor") + cp := ts.Spawn("cve", "-o", "editor") cp.Expect(`"project":`) cp.Expect(`"commitID":`) cp.ExpectExitCode(0) - // AssertValidJSON(suite.T(), cp) // report is too large to fit in terminal snapshot + AssertValidJSON(suite.T(), cp) } func TestCveIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/deploy_int_test.go b/test/integration/deploy_int_test.go index 49b08bdf4a..f51e686baa 100644 --- a/test/integration/deploy_int_test.go +++ b/test/integration/deploy_int_test.go @@ -8,9 +8,10 @@ import ( "runtime" "testing" - "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/google/uuid" + "github.com/ActiveState/cli/internal/testhelpers/suite" + "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" @@ -35,28 +36,23 @@ func (suite *DeployIntegrationTestSuite) deploy(ts *e2e.Session, prj string, tar var cp *e2e.SpawnedCmd switch runtime.GOOS { case "windows": - cp = ts.SpawnWithOpts( - e2e.OptArgs("deploy", prj, "--path", targetPath), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("deploy", prj, "--path", targetPath) case "darwin": // On MacOS the command is the same as Linux, however some binaries // already exist at /usr/local/bin so we use the --force flag cp = ts.SpawnWithOpts( e2e.OptArgs("deploy", prj, "--path", targetPath, "--force"), e2e.OptAppendEnv("SHELL=bash"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) default: cp = ts.SpawnWithOpts( e2e.OptArgs("deploy", prj, "--path", targetPath), e2e.OptAppendEnv("SHELL=bash"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) } cp.Expect("Installing", e2e.RuntimeSourcingTimeoutOpt) - cp.Expect("Configuring") + cp.Expect("Configuring", e2e.RuntimeSourcingTimeoutOpt) if runtime.GOOS != "windows" { cp.Expect("Symlinking") } @@ -98,13 +94,11 @@ func (suite *DeployIntegrationTestSuite) TestDeployPerl() { "cmd.exe", e2e.OptArgs("/k", filepath.Join(targetPath, "bin", "shell.bat")), e2e.OptAppendEnv("PATHEXT=.COM;.EXE;.BAT;.LNK", "SHELL="), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) } else { cp = ts.SpawnCmdWithOpts( "/bin/bash", e2e.OptAppendEnv("PROMPT_COMMAND="), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.SendLine(fmt.Sprintf("source %s\n", filepath.Join(targetPath, "bin", "shell.sh"))) } @@ -174,13 +168,11 @@ func (suite *DeployIntegrationTestSuite) TestDeployPython() { "cmd.exe", e2e.OptArgs("/k", filepath.Join(targetPath, "bin", "shell.bat")), e2e.OptAppendEnv("PATHEXT=.COM;.EXE;.BAT;.LNK", "SHELL="), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) } else { cp = ts.SpawnCmdWithOpts( "/bin/bash", e2e.OptAppendEnv("PROMPT_COMMAND="), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.SendLine(fmt.Sprintf("source %s\n", filepath.Join(targetPath, "bin", "shell.sh"))) } @@ -241,10 +233,7 @@ func (suite *DeployIntegrationTestSuite) TestDeployInstall() { } func (suite *DeployIntegrationTestSuite) InstallAndAssert(ts *e2e.Session, targetPath string) { - cp := ts.SpawnWithOpts( - e2e.OptArgs("deploy", "install", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("deploy", "install", "ActiveState-CLI/Python3", "--path", targetPath) cp.Expect("Installing Runtime") cp.Expect("Installing", e2e.RuntimeSourcingTimeoutOpt) @@ -268,10 +257,7 @@ func (suite *DeployIntegrationTestSuite) TestDeployConfigure() { suite.Require().NoError(err) // Install step is required - cp := ts.SpawnWithOpts( - e2e.OptArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath) cp.Expect("need to run the install step") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -281,13 +267,9 @@ func (suite *DeployIntegrationTestSuite) TestDeployConfigure() { cp = ts.SpawnWithOpts( e2e.OptArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath), e2e.OptAppendEnv("SHELL=bash"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) } else { - cp = ts.SpawnWithOpts( - e2e.OptArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath) } cp.Expect("Configuring shell", e2e.RuntimeSourcingTimeoutOpt) @@ -295,10 +277,7 @@ func (suite *DeployIntegrationTestSuite) TestDeployConfigure() { suite.AssertConfig(ts, targetID.String()) if runtime.GOOS == "windows" { - cp = ts.SpawnWithOpts( - e2e.OptArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath, "--user"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath, "--user") cp.Expect("Configuring shell", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) @@ -345,25 +324,16 @@ func (suite *DeployIntegrationTestSuite) TestDeploySymlink() { suite.Require().NoError(err) // Install step is required - cp := ts.SpawnWithOpts( - e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath) cp.Expect("need to run the install step") cp.ExpectExitCode(1) ts.IgnoreLogErrors() suite.InstallAndAssert(ts, targetPath) if runtime.GOOS != "darwin" { - cp = ts.SpawnWithOpts( - e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath) } else { - cp = ts.SpawnWithOpts( - e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath, "--force"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath, "--force") } if runtime.GOOS != "windows" { @@ -387,19 +357,13 @@ func (suite *DeployIntegrationTestSuite) TestDeployReport() { suite.Require().NoError(err) // Install step is required - cp := ts.SpawnWithOpts( - e2e.OptArgs("deploy", "report", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("deploy", "report", "ActiveState-CLI/Python3", "--path", targetPath) cp.Expect("need to run the install step") cp.ExpectExitCode(1) ts.IgnoreLogErrors() suite.InstallAndAssert(ts, targetPath) - cp = ts.SpawnWithOpts( - e2e.OptArgs("deploy", "report", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("deploy", "report", "ActiveState-CLI/Python3", "--path", targetPath) cp.Expect("Deployment Information") cp.Expect(targetID.String()) // expect bin dir if runtime.GOOS == "windows" { @@ -429,7 +393,6 @@ func (suite *DeployIntegrationTestSuite) TestDeployTwice() { cp := ts.SpawnWithOpts( e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), e2e.OptAppendEnv(fmt.Sprintf("PATH=%s", pathDir)), // Avoid conflicts - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.ExpectExitCode(0) @@ -442,7 +405,6 @@ func (suite *DeployIntegrationTestSuite) TestDeployTwice() { cpx := ts.SpawnWithOpts( e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), e2e.OptAppendEnv(fmt.Sprintf("PATH=%s", pathDir)), // Avoid conflicts - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cpx.ExpectExitCode(0) } @@ -466,10 +428,7 @@ func (suite *DeployIntegrationTestSuite) TestDeployUninstall() { suite.InstallAndAssert(ts, targetDir) // Uninstall deployed runtime. - cp := ts.SpawnWithOpts( - e2e.OptArgs("deploy", "uninstall", "--path", filepath.Join(ts.Dirs.Work, "target")), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("deploy", "uninstall", "--path", filepath.Join(ts.Dirs.Work, "target")) cp.Expect("Uninstall Deployed Runtime") cp.Expect("Successful") cp.ExpectExitCode(0) @@ -477,29 +436,20 @@ func (suite *DeployIntegrationTestSuite) TestDeployUninstall() { suite.True(fileutils.IsDir(ts.Dirs.Work), "Work dir was unexpectedly deleted") // Trying to uninstall again should fail - cp = ts.SpawnWithOpts( - e2e.OptArgs("deploy", "uninstall", "--path", filepath.Join(ts.Dirs.Work, "target")), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("deploy", "uninstall", "--path", filepath.Join(ts.Dirs.Work, "target")) cp.Expect("no deployed runtime") cp.ExpectExitCode(1) ts.IgnoreLogErrors() suite.True(fileutils.IsDir(ts.Dirs.Work), "Work dir was unexpectedly deleted") // Trying to uninstall in a non-deployment directory should fail. - cp = ts.SpawnWithOpts( - e2e.OptArgs("deploy", "uninstall"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("deploy", "uninstall") cp.Expect("no deployed runtime") cp.ExpectExitCode(1) suite.True(fileutils.IsDir(ts.Dirs.Work), "Work dir was unexpectedly deleted") // Trying to uninstall in a non-deployment directory should not delete that directory. - cp = ts.SpawnWithOpts( - e2e.OptArgs("deploy", "uninstall", "--path", ts.Dirs.Work), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("deploy", "uninstall", "--path", ts.Dirs.Work) cp.Expect("no deployed runtime") cp.ExpectExitCode(1) suite.True(fileutils.IsDir(ts.Dirs.Work), "Work dir was unexpectedly deleted") diff --git a/test/integration/errors_int_test.go b/test/integration/errors_int_test.go index 0fa368d237..4c4e713988 100644 --- a/test/integration/errors_int_test.go +++ b/test/integration/errors_int_test.go @@ -26,12 +26,23 @@ func (suite *ErrorsIntegrationTestSuite) TestTips() { ts.IgnoreLogErrors() } -func (suite *ErrorsIntegrationTestSuite) TestMultiError() { +func (suite *ErrorsIntegrationTestSuite) TestMultiErrorWithInput() { suite.OnlyRunForTags(tagsuite.Errors, tagsuite.Critical) ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("__test", "multierror") + cp := ts.Spawn("__test", "multierror-input") + cp.ExpectRe(`\s+x error1.\s+\s+x error2.\s+x error3.\s+x error4.\s+█\s+Need More Help`) + cp.ExpectExitCode(1) + ts.IgnoreLogErrors() +} + +func (suite *ErrorsIntegrationTestSuite) TestMultiErrorWithoutInput() { + suite.OnlyRunForTags(tagsuite.Errors, tagsuite.Critical) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + cp := ts.Spawn("__test", "multierror-noinput") cp.ExpectRe(`\s+x error1.\s+\s+x error2.\s+x error3.\s+x error4.\s+█\s+Need More Help`) cp.ExpectExitCode(1) ts.IgnoreLogErrors() diff --git a/test/integration/events_int_test.go b/test/integration/events_int_test.go index 36d95dfa50..e128437e8c 100644 --- a/test/integration/events_int_test.go +++ b/test/integration/events_int_test.go @@ -15,13 +15,9 @@ type EventsIntegrationTestSuite struct { tagsuite.Suite } -func (suite *EventsIntegrationTestSuite) TestEvents() { - suite.OnlyRunForTags(tagsuite.Events) - ts := e2e.New(suite.T(), false) - defer ts.Close() - +func (suite *EventsIntegrationTestSuite) prepareASY(ts *e2e.Session) { ts.PrepareActiveStateYAML(strings.TrimSpace(` -project: https://platform.activestate.com/ActiveState-CLI/Python3 +project: https://platform.activestate.com/ActiveState-CLI/Empty scripts: - name: before language: bash @@ -43,7 +39,15 @@ events: scope: ["activate"] value: after `)) - ts.PrepareCommitIdFile("fbc613d6-b0b1-4f84-b26e-4aa5869c4e54") + ts.PrepareCommitIdFile("6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") +} + +func (suite *EventsIntegrationTestSuite) TestEvents() { + suite.OnlyRunForTags(tagsuite.Events) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + suite.prepareASY(ts) cp := ts.SpawnWithOpts( e2e.OptArgs("activate"), @@ -80,12 +84,9 @@ func (suite *EventsIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Python3", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + suite.prepareASY(ts) - cp = ts.Spawn("events", "-o", "json") + cp := ts.Spawn("events", "-o", "json") cp.Expect(`[{"event":`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) diff --git a/test/integration/exec_int_test.go b/test/integration/exec_int_test.go index d0e0446d51..6f4a3de868 100644 --- a/test/integration/exec_int_test.go +++ b/test/integration/exec_int_test.go @@ -8,9 +8,6 @@ import ( "runtime" "strings" "testing" - "time" - - "github.com/ActiveState/termtest" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/environment" @@ -24,16 +21,12 @@ type ExecIntegrationTestSuite struct { tagsuite.Suite } -func (suite *ExecIntegrationTestSuite) createProjectFile(ts *e2e.Session) { - ts.PrepareProject("ActiveState-CLI/Python3", "fbc613d6-b0b1-4f84-b26e-4aa5869c4e54") -} - func (suite *ExecIntegrationTestSuite) TestExec_Environment() { suite.OnlyRunForTags(tagsuite.Exec) ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts) + ts.PrepareEmptyProject() scriptBlock := `echo ${PATH:0:500}` filename := fmt.Sprintf("%s/%s.sh", ts.Dirs.Work, suite.T().Name()) @@ -49,8 +42,12 @@ func (suite *ExecIntegrationTestSuite) TestExec_Environment() { err = os.Chmod(testScript, 0777) suite.Require().NoError(err) + args := []string{"exec", "--", "bash", "-c", testScript} + if runtime.GOOS == "windows" { + args = []string{"exec", "--", "cmd", "/c", testScript} + } cp := ts.SpawnWithOpts( - e2e.OptArgs("exec", testScript), + e2e.OptArgs(args...), ) cp.ExpectExitCode(0) output := cp.Output() @@ -62,7 +59,7 @@ func (suite *ExecIntegrationTestSuite) TestExec_ExitCode() { ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts) + ts.PrepareEmptyProject() scriptBlock := `exit 42` filename := fmt.Sprintf("%s/%s.sh", ts.Dirs.Work, suite.T().Name()) @@ -78,59 +75,14 @@ func (suite *ExecIntegrationTestSuite) TestExec_ExitCode() { err = os.Chmod(testScript, 0777) suite.Require().NoError(err) - cp := ts.SpawnWithOpts( - e2e.OptArgs("exec", "--", testScript), - ) - cp.ExpectExitCode(42) -} - -func (suite *ExecIntegrationTestSuite) TestExec_Args() { - suite.OnlyRunForTags(tagsuite.Exec) - ts := e2e.New(suite.T(), false) - defer ts.Close() - - suite.createProjectFile(ts) - - scriptBlock := ` -for i; do - echo $i -done -echo "Number of arguments: $#" -` - - filename := fmt.Sprintf("%s/%s.sh", ts.Dirs.Work, suite.T().Name()) + args := []string{"exec", "--", "bash", "-c", testScript} if runtime.GOOS == "windows" { - scriptBlock = ` - set argCount=0 - for %%a in (%*) do ( - echo %%a - set /A argCount+=1 - ) - echo Number of arguments: %argCount%` - filename = fmt.Sprintf("%s/%s.bat", ts.Dirs.Work, suite.T().Name()) - } - - testScript := filepath.Join(filename) - err := fileutils.WriteFile(testScript, []byte(scriptBlock)) - suite.Require().NoError(err) - - err = os.Chmod(testScript, 0777) - suite.Require().NoError(err) - - args := []string{ - "firstArgument", - "secondArgument", - "thirdArgument", + args = []string{"exec", "--", "cmd", "/c", testScript} } - cp := ts.SpawnWithOpts( - e2e.OptArgs("exec", "--", testScript, args[0], args[1], args[2]), + e2e.OptArgs(args...), ) - cp.Expect(args[0]) - cp.Expect(args[1]) - cp.Expect(args[2]) - cp.Expect(fmt.Sprintf("Number of arguments: %d", len(args))) - cp.ExpectExitCode(0) + cp.ExpectExitCode(42) } func (suite *ExecIntegrationTestSuite) TestExec_Input() { @@ -138,7 +90,7 @@ func (suite *ExecIntegrationTestSuite) TestExec_Input() { ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts) + ts.PrepareEmptyProject() scriptBlock := ` echo "Enter your name: " @@ -160,8 +112,12 @@ echo "Hello $name!" err = os.Chmod(testScript, 0777) suite.Require().NoError(err) + args := []string{"exec", "--", "bash", "-c", testScript} + if runtime.GOOS == "windows" { + args = []string{"exec", "--", "cmd", "/c", testScript} + } cp := ts.SpawnWithOpts( - e2e.OptArgs("exec", "--", testScript), + e2e.OptArgs(args...), ) cp.SendLine("ActiveState") cp.Expect("Hello ActiveState!") @@ -179,23 +135,18 @@ func (suite *ExecIntegrationTestSuite) TestExecWithPath() { pythonDir := filepath.Join(ts.Dirs.Work, "MyPython3") - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9", pythonDir)) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + cp := ts.Spawn("checkout", "ActiveState-CLI/Python-3.9", pythonDir) + cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.OptArgs("exec", "--path", pythonDir, "which", "python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), + e2e.OptArgs("exec", "--path", pythonDir, "--", "bash", "-c", "which python3"), ) cp.Expect("Operating on project ActiveState-CLI/Python-3.9", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectRe(regexp.MustCompile("cache/[0-9A-Fa-f]+/usr/bin/python3").String()) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("exec", "echo", "python3", "--path", pythonDir, "--", "--path", "doesNotExist", "--", "extra"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("exec", "echo", "python3", "--path", pythonDir, "--", "--path", "doesNotExist", "--", "extra") cp.Expect("python3 --path doesNotExist -- extra") cp.ExpectExitCode(0) @@ -208,20 +159,50 @@ func (suite *ExecIntegrationTestSuite) TestExeBatArguments() { suite.T().Skip("This test is only for windows") } - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + root := environment.GetRootPathUnsafe() reportBat := filepath.Join(root, "test", "integration", "testdata", "batarguments", "report.bat") suite.Require().FileExists(reportBat) inputs := []string{"aa", "hello world", "&whoami", "imnot|apipe", "%NotAppData%", "^NotEscaped", "(NotAGroup)"} outputs := `"` + strings.Join(inputs, `" "`) + `"` - cp := ts.SpawnWithOpts(e2e.OptArgs(append([]string{"exec", reportBat, "--"}, inputs...)...)) - cp.Expect(outputs, termtest.OptExpectTimeout(5*time.Second)) + cp = ts.SpawnWithOpts(e2e.OptArgs(append([]string{"exec", reportBat, "--"}, inputs...)...)) + cp.Expect(outputs, e2e.RuntimeBuildSourcingTimeoutOpt) + cp.ExpectExitCode(0) +} + +func (suite *ExecIntegrationTestSuite) TestExec_PATH_and_Path_on_Windows() { + suite.OnlyRunForTags(tagsuite.Exec) + + if runtime.GOOS != "windows" { + suite.T().Skip("This test is only for windows") + } + + ts := e2e.New(suite.T(), false) + defer ts.Close() + + cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") + cp.Expect("Checked out", e2e.RuntimeSourcingTimeoutOpt) + cp.ExpectExitCode(0) + + cp = ts.Spawn("exec", "where", "python3") + cp.Expect(os.TempDir()) // from runtime's defined PATH cp.ExpectExitCode(0) + + cp = ts.Spawn("exec", "where", "notepad") + cp.Expect("notepad.exe") // from OS-defined default Path + cp.ExpectExitCode(0) + + cp = ts.Spawn("exec", "does-not-exist") + cp.Expect("not found") // neither on PATH nor Path + cp.ExpectNotExitCode(0) } func TestExecIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/executor_int_test.go b/test/integration/executor_int_test.go index 6c33c9943f..96a46a3dfe 100644 --- a/test/integration/executor_int_test.go +++ b/test/integration/executor_int_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/ActiveState/cli/pkg/executors" "github.com/ActiveState/termtest" "github.com/ActiveState/cli/internal/constants" @@ -18,8 +19,6 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/ActiveState/cli/pkg/platform/runtime/executors" - "github.com/ActiveState/cli/pkg/platform/runtime/target" ) type ExecutorIntegrationTestSuite struct { @@ -36,17 +35,12 @@ func (suite *ExecutorIntegrationTestSuite) TestExecutorForwards() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python3"), - ) - cp.Expect("Checked out project") + cp := ts.Spawn("checkout", "ActiveState-CLI/Python3") + cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("shell", "ActiveState-CLI/Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("shell", "ActiveState-CLI/Python3") + cp.Expect("Activated") cp.ExpectInput() cp.SendLine("python3 -c \"import sys; print(sys.copyright)\"") @@ -63,17 +57,12 @@ func (suite *ExecutorIntegrationTestSuite) TestExecutorExitCode() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python3"), - ) - cp.Expect("Checked out project") + cp := ts.Spawn("checkout", "ActiveState-CLI/Python3") + cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("shell", "ActiveState-CLI/Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("shell", "ActiveState-CLI/Python3") + cp.Expect("Activated") cp.ExpectInput() cp.SendLine("python3 -c \"exit(42)\"") @@ -107,7 +96,7 @@ func (suite *ExecutorIntegrationTestSuite) TestExecutorBatArguments() { suite.T().Skip("This test is only for windows") } - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() root := environment.GetRootPathUnsafe() @@ -115,7 +104,7 @@ func (suite *ExecutorIntegrationTestSuite) TestExecutorBatArguments() { srcExes := fileutils.ListFilesUnsafe(filepath.Join(root, "test", "integration", "testdata", "batarguments")) reportExe := filepath.Join(executorsPath, "report.exe") - t := target.NewCustomTarget("ActiveState-CLI", "test", constants.ValidZeroUUID, "", target.TriggerExecutor) + t := executors.NewTarget(constants.ValidZeroUUID, "ActiveState-CLI", "test", "") executors := executors.New(executorsPath) executors.SetExecutorSrc(ts.ExecutorExe) err := executors.Apply( diff --git a/test/integration/export_int_test.go b/test/integration/export_int_test.go index 010b78368c..2787a0e77a 100644 --- a/test/integration/export_int_test.go +++ b/test/integration/export_int_test.go @@ -1,11 +1,15 @@ package integration import ( + "bufio" + "encoding/json" + "os" "path/filepath" + "strconv" + "strings" "testing" "time" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -42,12 +46,9 @@ func (suite *ExportIntegrationTestSuite) TestExport_Env() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.PrepareProject("ActiveState-CLI/Export", "5397f645-da8a-4591-b106-9d7fa99545fe") - cp := ts.SpawnWithOpts( - e2e.OptArgs("export", "env"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect(`PATH: `, e2e.RuntimeSourcingTimeoutOpt) + ts.PrepareEmptyProject() + cp := ts.Spawn("export", "env") + cp.Expect(`PATH: `) cp.ExpectExitCode(0) suite.Assert().NotContains(cp.Output(), "ACTIVESTATE_ACTIVATED") @@ -58,7 +59,12 @@ func (suite *ExportIntegrationTestSuite) TestExport_Log() { ts := e2e.New(suite.T(), false) defer ts.ClearCache() - cp := ts.Spawn("export", "log") + // Populate the log file directory as the log file created by + // the export command will be ignored. + cp := ts.Spawn("--version") + cp.ExpectExitCode(0) + + cp = ts.Spawn("export", "log") cp.Expect(filepath.Join(ts.Dirs.Config, "logs")) cp.ExpectRe(`state-\d+`) cp.Expect(".log") @@ -71,20 +77,84 @@ func (suite *ExportIntegrationTestSuite) TestExport_Log() { cp.ExpectExitCode(0) } +func (suite *ExportIntegrationTestSuite) TestExport_LogIgnore() { + suite.OnlyRunForTags(tagsuite.Export) + ts := e2e.New(suite.T(), false) + defer ts.ClearCache() + + cp := ts.Spawn("config", "--help") + cp.ExpectExitCode(0) + + cp = ts.Spawn("config", "set", "--help") + cp.ExpectExitCode(0) + + cp = ts.Spawn("projects") + cp.ExpectExitCode(0) + + suite.verifyLogIndex(ts, 0, "projects") + suite.verifyLogIndex(ts, 1, "config", "set") + suite.verifyLogIndex(ts, 2, "config") +} + +func (suite *ExportIntegrationTestSuite) verifyLogIndex(ts *e2e.Session, index int, args ...string) { + cp := ts.Spawn("export", "log", "-i", strconv.Itoa(index), "--output", "json") + cp.ExpectExitCode(0) + data := cp.StrippedSnapshot() + + type log struct { + LogFile string `json:"logFile"` + } + + var l log + err := json.Unmarshal([]byte(data), &l) + suite.Require().NoError(err) + + suite.verifyLogFile(l.LogFile, args...) +} + +func (suite *ExportIntegrationTestSuite) verifyLogFile(logFile string, expectedArgs ...string) { + f, err := os.Open(logFile) + suite.Require().NoError(err) + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + if !strings.Contains(scanner.Text(), "Args: ") { + continue + } + + for _, arg := range expectedArgs { + if !strings.Contains(scanner.Text(), arg) { + suite.Fail("Log file does not contain expected command: %s", arg) + } + } + } +} + func (suite *ExportIntegrationTestSuite) TestExport_Runtime() { suite.OnlyRunForTags(tagsuite.Export) ts := e2e.New(suite.T(), false) - ts.PrepareProject("ActiveState-CLI/Export", "5397f645-da8a-4591-b106-9d7fa99545fe") - cp := ts.SpawnWithOpts( - e2e.OptArgs("export", "runtime"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + ts.PrepareEmptyProject() + cp := ts.Spawn("export", "runtime") cp.Expect("Project Path: ") cp.Expect("Runtime Path: ") cp.Expect("Executables Path: ") cp.Expect("Environment Variables:") // intentional lack of trailing space - cp.Expect(` - PATH: `, e2e.RuntimeSourcingTimeoutOpt) + cp.Expect(` - PATH: `) + cp.ExpectExitCode(0) +} + +func (suite *ExportIntegrationTestSuite) TestExport_BuildPlan() { + suite.OnlyRunForTags(tagsuite.Export) + ts := e2e.New(suite.T(), false) + + ts.PrepareEmptyProject() + cp := ts.Spawn("export", "buildplan") + cp.Expect("Resolving Dependencies") + cp.Expect(`{`) + cp.Expect(`"buildPlanID":`) + cp.Expect(`"terminals":`) + cp.Expect(`}`) cp.ExpectExitCode(0) } @@ -98,17 +168,10 @@ func (suite *ExportIntegrationTestSuite) TestJSON() { cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) - - cp = ts.SpawnWithOpts( - e2e.OptArgs("export", "env", "-o", "json"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) + ts.PrepareEmptyProject() + + cp = ts.Spawn("export", "env", "-o", "json") + cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) ts.LoginAsPersistentUser() @@ -123,13 +186,17 @@ func (suite *ExportIntegrationTestSuite) TestJSON() { cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) - cp = ts.SpawnWithOpts( - e2e.OptArgs("export", "runtime", "-o", "json"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false")) + cp = ts.Spawn("export", "runtime", "-o", "json") cp.Expect(`{"project":"`) cp.Expect(`"}}`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) + + cp = ts.Spawn("export", "buildplan", "-o", "json") + cp.Expect(`{"`) + cp.Expect(`}`) + cp.ExpectExitCode(0) + // The buildplan is too large for the snapshot to contain valid JSON. } func TestExportIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/fork_int_test.go b/test/integration/fork_int_test.go index ccaa231dd2..f26df5e682 100644 --- a/test/integration/fork_int_test.go +++ b/test/integration/fork_int_test.go @@ -16,7 +16,7 @@ type ForkIntegrationTestSuite struct { } func (suite *ForkIntegrationTestSuite) cleanup(ts *e2e.Session) { - cp := ts.Spawn(tagsuite.Auth, "logout") + cp := ts.Spawn("auth", "logout") cp.ExpectExitCode(0) ts.Close() } @@ -45,7 +45,7 @@ func (suite *ForkIntegrationTestSuite) TestFork_FailNameExists() { defer suite.cleanup(ts) ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts(e2e.OptArgs("fork", "ActiveState-CLI/Python3", "--org", e2e.PersistentUsername)) + cp := ts.Spawn("fork", "ActiveState-CLI/Python3", "--org", e2e.PersistentUsername) cp.Expect("You already have a project with the name 'Python3'", termtest.OptExpectTimeout(30*time.Second)) cp.ExpectNotExitCode(0) ts.IgnoreLogErrors() diff --git a/test/integration/hello_int_example_test.go b/test/integration/hello_int_example_test.go index 8b89de735a..921896935d 100644 --- a/test/integration/hello_int_example_test.go +++ b/test/integration/hello_int_example_test.go @@ -18,11 +18,9 @@ func (suite *HelloIntegrationTestSuite) TestHello() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() - cp = ts.Spawn("_hello", "Person") + cp := ts.Spawn("_hello", "Person") cp.Expect("Hello, Person!") cp.ExpectExitCode(0) @@ -32,7 +30,7 @@ func (suite *HelloIntegrationTestSuite) TestHello() { ts.IgnoreLogErrors() cp = ts.Spawn("_hello", "Person", "--extra") - cp.Expect("Project: ActiveState-CLI/small-python") + cp.Expect("Project: ActiveState-CLI/Empty") cp.Expect("Current commit message:") cp.ExpectExitCode(0) diff --git a/test/integration/history_int_test.go b/test/integration/history_int_test.go index 5610c6e239..da24d0cc48 100644 --- a/test/integration/history_int_test.go +++ b/test/integration/history_int_test.go @@ -1,7 +1,6 @@ package integration import ( - "path/filepath" "testing" "github.com/ActiveState/cli/internal/testhelpers/e2e" @@ -19,17 +18,9 @@ func (suite *HistoryIntegrationTestSuite) TestHistory_History() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.LoginAsPersistentUser() + ts.PrepareProject("ActiveState-CLI/History", "b5b327f8-468e-4999-a23e-8bee886e6b6d") - cp := ts.Spawn("checkout", "ActiveState-CLI/History") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) - - cp = ts.SpawnWithOpts( - e2e.OptArgs("history"), - e2e.OptWD(filepath.Join(ts.Dirs.Work, "History")), - ) + cp := ts.Spawn("history") cp.Expect("Operating on project") cp.Expect("ActiveState-CLI/History") cp.Expect("Commit") @@ -56,12 +47,9 @@ func (suite *HistoryIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/History", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareProject("ActiveState-CLI/History", "b5b327f8-468e-4999-a23e-8bee886e6b6d") - cp = ts.Spawn("history", "-o", "json") + cp := ts.Spawn("history", "-o", "json") cp.Expect(`[{"hash":`) cp.Expect(`"changes":[{`) cp.Expect(`"operation":"updated"`) diff --git a/test/integration/import_int_test.go b/test/integration/import_int_test.go index 1609c1584f..47c9c9cd7b 100644 --- a/test/integration/import_int_test.go +++ b/test/integration/import_int_test.go @@ -4,11 +4,15 @@ import ( "fmt" "os" "path/filepath" - "runtime" "strings" "testing" + "time" + "github.com/ActiveState/termtest" + + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/testhelpers/e2e" + "github.com/ActiveState/cli/internal/testhelpers/osutil" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" ) @@ -18,20 +22,12 @@ type ImportIntegrationTestSuite struct { } func (suite *ImportIntegrationTestSuite) TestImport_detached() { - suite.T().Skip("Skipping import test until DX-2444 is resolved: https://activestatef.atlassian.net/browse/DX-2444") suite.OnlyRunForTags(tagsuite.Import) - if runtime.GOOS == "darwin" { - suite.T().Skip("Skipping mac for now as the builds are still too unreliable") - return - } ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Python3-Import", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") contents := `requests urllib3` @@ -40,9 +36,16 @@ func (suite *ImportIntegrationTestSuite) TestImport_detached() { err := os.WriteFile(importPath, []byte(strings.TrimSpace(contents)), 0644) suite.Require().NoError(err) + ts.LoginAsPersistentUser() // for CVE reporting + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + cp = ts.Spawn("import", importPath) cp.Expect("Operating on project") - cp.Expect("ActiveState-CLI/Python3-Import") + cp.Expect("ActiveState-CLI/small-python") + cp.Expect("Resolving Dependencies") + cp.Expect("Import Finished") cp.ExpectExitCode(0) cp = ts.Spawn("packages") @@ -78,7 +81,6 @@ urllib3>=1.21.1,<=1.26.5 ) func (suite *ImportIntegrationTestSuite) TestImport() { - suite.T().Skip("Skipping import test until DX-2444 is resolved: https://activestatef.atlassian.net/browse/DX-2444") suite.OnlyRunForTags(tagsuite.Import) ts := e2e.New(suite.T(), false) defer ts.Close() @@ -87,7 +89,7 @@ func (suite *ImportIntegrationTestSuite) TestImport() { namespace := fmt.Sprintf("%s/%s", user.Username, "Python3") cp := ts.Spawn("init", "--language", "python", namespace, ts.Dirs.Work) - cp.Expect("successfully initialized") + cp.Expect("successfully initialized", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) reqsFilePath := filepath.Join(cp.WorkDirectory(), reqsFileName) @@ -96,7 +98,7 @@ func (suite *ImportIntegrationTestSuite) TestImport() { ts.SetT(suite.T()) ts.PrepareFile(reqsFilePath, badReqsData) - cp := ts.Spawn("import", "requirements.txt") + cp = ts.Spawn("import", "requirements.txt") cp.ExpectNotExitCode(0) }) @@ -104,14 +106,14 @@ func (suite *ImportIntegrationTestSuite) TestImport() { ts.SetT(suite.T()) ts.PrepareFile(reqsFilePath, reqsData) - cp := ts.Spawn("import", "requirements.txt") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) - cp = ts.Spawn("push") + cp = ts.Spawn("import", "requirements.txt") cp.ExpectExitCode(0) cp = ts.Spawn("import", "requirements.txt") - cp.Expect("No new changes") + cp.Expect("no changes") cp.ExpectNotExitCode(0) }) @@ -119,22 +121,120 @@ func (suite *ImportIntegrationTestSuite) TestImport() { ts.SetT(suite.T()) ts.PrepareFile(reqsFilePath, complexReqsData) - cp := ts.Spawn("import", "requirements.txt") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) + cp = ts.Spawn("import", "requirements.txt") + cp.ExpectExitCode(0, termtest.OptExpectTimeout(2*time.Minute)) // wait twice as long as a normal solve + cp = ts.Spawn("packages") cp.Expect("coverage") + cp.Expect("!3.5 → ") cp.Expect("docopt") + cp.Expect(">=0.6.1 →") cp.Expect("Mopidy-Dirble") cp.Expect("requests") - cp.Expect("Auto") // DX-2272 will change this to 2.30.0 + cp.Expect(">=2.2,<2.31.0 → 2.30.0") cp.Expect("urllib3") - cp.Expect("Auto") // DX-2272 will change this to 1.26.5 + cp.Expect(">=1.21.1,<=1.26.5 → 1.26.5") cp.ExpectExitCode(0) }) ts.IgnoreLogErrors() } +func (suite *ImportIntegrationTestSuite) TestImportCycloneDx() { + suite.OnlyRunForTags(tagsuite.Import) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.LoginAsPersistentUser() // needed to read orgs for private namespace + + ts.PrepareEmptyProject() + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + jsonSbom := filepath.Join(osutil.GetTestDataDir(), "import", "cyclonedx", "bom.json") + xmlSbom := filepath.Join(osutil.GetTestDataDir(), "import", "cyclonedx", "bom.xml") + + for _, sbom := range []string{jsonSbom, xmlSbom} { + suite.Run("import "+sbom, func() { + cp := ts.Spawn("import", sbom) + cp.Expect("Resolving Dependencies") + cp.Expect("Failed") + cp.Expect("unavailable") + cp.ExpectNotExitCode(0) // solve should fail due to private namespace + + cp = ts.Spawn("history") + cp.Expect("Import from requirements file") + cp.Expect("+ body-parser 1.19.0") + cp.Expect("namespace: private/") + cp.Expect("+ bytes 3.1.0") + cp.Expect("namespace: private/") + cp.ExpectExitCode(0) + + cp = ts.Spawn("reset", "-n") + cp.ExpectExitCode(0) + }) + } + + ts.IgnoreLogErrors() +} + +func (suite *ImportIntegrationTestSuite) TestImportSpdx() { + suite.OnlyRunForTags(tagsuite.Import) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.LoginAsPersistentUser() // needed to read orgs for private namespace + + ts.PrepareEmptyProject() + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + jsonSbom := filepath.Join(osutil.GetTestDataDir(), "import", "spdx", "appbomination.spdx.json") + + cp = ts.Spawn("import", jsonSbom) + cp.Expect("Resolving Dependencies") + cp.Expect("Failed") + cp.Expect("unavailable") + cp.ExpectNotExitCode(0) // solve should fail due to private namespace + + cp = ts.Spawn("history") + cp.Expect("Import from requirements file") + cp.Expect("+ App-BOM-ination 1.0") + cp.Expect("namespace: private/") + cp.Expect("+ commons-lang3 3.4") + cp.Expect("namespace: private/") + cp.Expect("+ hamcrest-core 1.3") + cp.Expect("namespace: private/") + cp.Expect("+ junit 4.12") + cp.Expect("namespace: private/") + cp.Expect("+ slf4j-api 1.7.21") + cp.Expect("namespace: private/") + cp.ExpectExitCode(0) + + cp = ts.Spawn("reset", "-n") + cp.ExpectExitCode(0) + + spdxSbom := filepath.Join(osutil.GetTestDataDir(), "import", "spdx", "example1.spdx") + + cp = ts.Spawn("import", spdxSbom) + cp.Expect("Resolving Dependencies") + cp.Expect("Failed") + cp.Expect("unavailable") + cp.ExpectNotExitCode(0) // solve should fail due to private namespace + + cp = ts.Spawn("history") + cp.Expect("Import from requirements file") + cp.Expect("+ hello 1.0.0") + cp.Expect("namespace: private/") + cp.ExpectExitCode(0) + + ts.IgnoreLogErrors() +} + func TestImportIntegrationTestSuite(t *testing.T) { suite.Run(t, new(ImportIntegrationTestSuite)) } diff --git a/test/integration/info_int_test.go b/test/integration/info_int_test.go index a57b0c2901..c63a40a822 100644 --- a/test/integration/info_int_test.go +++ b/test/integration/info_int_test.go @@ -57,7 +57,7 @@ func (suite *InfoIntegrationTestSuite) TestJSON() { cp.Expect(`"authors":`) cp.Expect(`"version":`) cp.ExpectExitCode(0) - //AssertValidJSON(suite.T(), cp) + //AssertValidJSON(suite.T(), cp) // currently too big to fit in terminal snapshot cp = ts.Spawn("info", "pylint@9.9.9", "--language", "python", "--output", "editor") cp.Expect(`"error":`) diff --git a/test/integration/init_int_test.go b/test/integration/init_int_test.go index 1abaa8f63f..cfbf5ae830 100644 --- a/test/integration/init_int_test.go +++ b/test/integration/init_int_test.go @@ -10,6 +10,7 @@ import ( "github.com/ActiveState/cli/internal/assets" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/hash" "github.com/ActiveState/cli/internal/language" "github.com/ActiveState/cli/internal/strutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" @@ -36,7 +37,10 @@ func (suite *InitIntegrationTestSuite) TestInit_DisambiguatePython() { suite.OnlyRunForTags(tagsuite.Init) suite.runInitTest(false, false, "python", "python3") suite.runInitTest(false, false, "python@3.10.0", "python3") - suite.runInitTest(false, false, "python@2.7.18", "python2") + if runtime.GOOS != "darwin" { + // Not supported on mac + suite.runInitTest(false, false, "python@2.7.18", "python2") + } } func (suite *InitIntegrationTestSuite) TestInit_PartialVersions() { @@ -60,19 +64,14 @@ func (suite *InitIntegrationTestSuite) runInitTest(addPath bool, sourceRuntime b computedArgs = append(computedArgs, ts.Dirs.Work) } - env := []string{} - if sourceRuntime { - env = append(env, constants.DisableRuntime+"=false") + if !sourceRuntime { + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) } + // Run `state init`, creating the project. - cp := ts.SpawnWithOpts( - e2e.OptArgs(computedArgs...), - e2e.OptAppendEnv(env...), - ) + cp := ts.SpawnWithOpts(e2e.OptArgs(computedArgs...)) cp.Expect("Initializing Project") - if !sourceRuntime { - cp.Expect("Skipping runtime setup") - } cp.Expect(fmt.Sprintf("Project '%s' has been successfully initialized", namespace), e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) ts.NotifyProjectCreated(e2e.PersistentUsername, pname.String()) @@ -121,22 +120,20 @@ func (suite *InitIntegrationTestSuite) TestInit_InferLanguageFromUse() { defer ts.Close() ts.LoginAsPersistentUser() - cp := ts.Spawn("checkout", "ActiveState-CLI/Python3") - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("checkout", "ActiveState-CLI/small-python") cp.Expect("Checked out project") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("use", "small-python") cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) pname := strutils.UUID() namespace := fmt.Sprintf("%s/%s", e2e.PersistentUsername, pname) cp = ts.Spawn("init", namespace) - cp.Expect("Skipping runtime setup") cp.Expect("successfully initialized") cp.ExpectExitCode(0) ts.NotifyProjectCreated(e2e.PersistentUsername, pname.String()) @@ -175,10 +172,7 @@ func (suite *InitIntegrationTestSuite) TestInit_Resolved() { namespace := fmt.Sprintf("%s/%s", e2e.PersistentUsername, pname) // Run `state init`, creating the project. - cp := ts.SpawnWithOpts( - e2e.OptArgs("init", namespace, "--language", "python@3.10"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("init", namespace, "--language", "python@3.10") cp.Expect(fmt.Sprintf("Project '%s' has been successfully initialized", namespace), e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) ts.NotifyProjectCreated(e2e.PersistentUsername, pname.String()) @@ -212,10 +206,12 @@ func (suite *InitIntegrationTestSuite) TestInit_InferredOrg() { projectName := fmt.Sprintf("test-project-%s", sysinfo.OS().String()) // First, checkout project to set last used org. - cp := ts.Spawn("checkout", fmt.Sprintf("%s/Python3", org)) - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("checkout", fmt.Sprintf("%s/Empty", org)) cp.Expect("Checked out project") + cp = ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + // Now, run `state init` without specifying the org. cp = ts.Spawn("init", projectName, "--language", "python@3") cp.Expect(fmt.Sprintf("%s/%s", org, projectName)) @@ -235,18 +231,18 @@ func (suite *InitIntegrationTestSuite) TestInit_ChangeSummary() { ts.LoginAsPersistentUser() - cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") - cp.Expect("Successfully set") + cp := ts.Spawn("config", "set", "optin.unstable.async_runtime", "true") cp.ExpectExitCode(0) - project := "test-init-change-summary-" + sysinfo.OS().String() - cp = ts.Spawn("init", "ActiveState-CLI/"+project, "--language", "python@3.10.10") + project := "test-init-change-summary-" + hash.ShortHash(strutils.UUID().String()) + cp = ts.SpawnWithOpts( + e2e.OptArgs("init", e2e.PersistentUsername+"/"+project, "--language", "python@3.10.10"), + ) cp.Expect("Resolving Dependencies") cp.Expect("Done") - ts.NotifyProjectCreated("ActiveState-CLI", project) + ts.NotifyProjectCreated(e2e.PersistentUsername, project) cp.Expect("Setting up the following dependencies:") - cp.Expect("└─ python@3.10.10") - suite.Assert().NotContains(cp.Snapshot(), "├─", "more than one dependency was printed") + cp.Expect("├─ python@3.10.10") cp.ExpectExitCode(0) } diff --git a/test/integration/install_int_test.go b/test/integration/install_int_test.go index 849f5717b8..4f50a4ced8 100644 --- a/test/integration/install_int_test.go +++ b/test/integration/install_int_test.go @@ -20,9 +20,30 @@ func (suite *InstallIntegrationTestSuite) TestInstall() { defer ts.Close() ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") - cp := ts.SpawnWithOpts(e2e.OptArgs("install", "trender"), e2e.OptAppendEnv(constants.DisableRuntime+"=false")) - cp.Expect("Package added", e2e.RuntimeSourcingTimeoutOpt) + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("install", "trender") + cp.Expect("project has been updated") + cp.ExpectExitCode(0) +} + +func (suite *InstallIntegrationTestSuite) TestInstallSuggest() { + suite.OnlyRunForTags(tagsuite.Install, tagsuite.Critical) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) + + cp = ts.Spawn("install", "djang") + cp.Expect("No results found", e2e.RuntimeSolvingTimeoutOpt) + cp.Expect("Did you mean") + cp.Expect("language/python/djang") + cp.ExpectExitCode(1) } func (suite *InstallIntegrationTestSuite) TestInstall_InvalidCommit() { @@ -31,7 +52,7 @@ func (suite *InstallIntegrationTestSuite) TestInstall_InvalidCommit() { defer ts.Close() ts.PrepareProject("ActiveState-CLI/small-python", "malformed-commit-id") - cp := ts.SpawnWithOpts(e2e.OptArgs("install", "trender")) + cp := ts.Spawn("install", "trender") cp.Expect("invalid commit ID") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -43,7 +64,7 @@ func (suite *InstallIntegrationTestSuite) TestInstall_NoMatches_NoAlternatives() defer ts.Close() ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") - cp := ts.SpawnWithOpts(e2e.OptArgs("install", "I-dont-exist")) + cp := ts.Spawn("install", "I-dont-exist") cp.Expect("No results found for search term") cp.Expect("find alternatives") // This verifies no alternatives were found cp.ExpectExitCode(1) @@ -55,14 +76,15 @@ func (suite *InstallIntegrationTestSuite) TestInstall_NoMatches_NoAlternatives() } func (suite *InstallIntegrationTestSuite) TestInstall_NoMatches_Alternatives() { + suite.T().Skip("Requires https://activestatef.atlassian.net/browse/DX-3074 to be resolved.") suite.OnlyRunForTags(tagsuite.Install) ts := e2e.New(suite.T(), false) defer ts.Close() ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") - cp := ts.SpawnWithOpts(e2e.OptArgs("install", "database")) + cp := ts.Spawn("install", "database") cp.Expect("No results found for search term") - cp.Expect("did you mean") // This verifies alternatives were found + cp.Expect("Did you mean") // This verifies alternatives were found cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -77,11 +99,9 @@ func (suite *InstallIntegrationTestSuite) TestInstall_BuildPlannerError() { defer ts.Close() ts.PrepareProject("ActiveState-CLI/small-python", "d8f26b91-899c-4d50-8310-2c338786aa0f") - cp := ts.SpawnWithOpts( - e2e.OptArgs("install", "trender@999.0"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Could not plan build, platform responded with", e2e.RuntimeSourcingTimeoutOpt) + + cp := ts.Spawn("install", "trender@999.0") + cp.Expect("Could not plan build. Platform responded with") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -96,11 +116,12 @@ func (suite *InstallIntegrationTestSuite) TestInstall_Resolved() { defer ts.Close() ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") - cp := ts.SpawnWithOpts( - e2e.OptArgs("install", "requests"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Package added", e2e.RuntimeSourcingTimeoutOpt) + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("install", "requests") + cp.Expect("project has been updated") cp.ExpectExitCode(0) // Run `state packages` to verify a full package version was resolved. diff --git a/test/integration/install_scripts_int_test.go b/test/integration/install_scripts_int_test.go index 8846c44353..87e8d5e424 100644 --- a/test/integration/install_scripts_int_test.go +++ b/test/integration/install_scripts_int_test.go @@ -7,6 +7,9 @@ import ( "runtime" "testing" + "github.com/ActiveState/cli/internal/config" + "github.com/ActiveState/cli/internal/rtutils/singlethread" + "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/stretchr/testify/require" "github.com/thoas/go-funk" @@ -104,7 +107,10 @@ func (suite *InstallScriptsIntegrationTestSuite) TestInstall() { } if runtime.GOOS == "windows" { cmd = "powershell.exe" - opts = append(opts, e2e.OptAppendEnv("SHELL=")) + opts = append(opts, + e2e.OptAppendEnv("SHELL="), + e2e.OptAppendEnv(constants.OverrideShellEnvVarName+"="), + ) } cp := ts.SpawnCmdWithOpts(cmd, opts...) cp.Expect("Preparing Installer for State Tool Package Manager") @@ -137,12 +143,19 @@ func (suite *InstallScriptsIntegrationTestSuite) TestInstall() { suite.assertAnalytics(ts) suite.DirExists(ts.Dirs.Config) + // Clear configured shell. + cfg, err := config.NewCustom(ts.Dirs.Config, singlethread.New(), true) + suite.Require().NoError(err) + err = cfg.Set(subshell.ConfigKeyShell, "") + suite.Require().NoError(err) + // Verify that can install overtop if runtime.GOOS != "windows" { cp = ts.SpawnCmdWithOpts("bash", e2e.OptArgs(argsPlain...)) } else { cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.OptArgs(argsPlain...), e2e.OptAppendEnv("SHELL="), + e2e.OptAppendEnv(constants.OverrideShellEnvVarName+"="), ) } cp.Expect("successfully installed") diff --git a/test/integration/invite_int_test.go b/test/integration/invite_int_test.go index f899a668ab..57b98b2b15 100644 --- a/test/integration/invite_int_test.go +++ b/test/integration/invite_int_test.go @@ -18,7 +18,7 @@ func (suite *InviteIntegrationTestSuite) TestInvite_NotAuthenticated() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.PrepareProject("ActiveState-CLI/Invite-Test", e2e.CommitIDNotChecked) + ts.PrepareEmptyProject() cp := ts.Spawn("invite", "test-user@test.com") cp.Expect("You need to authenticate") diff --git a/test/integration/languages_int_test.go b/test/integration/languages_int_test.go index bd7a819baa..c9238e7834 100644 --- a/test/integration/languages_int_test.go +++ b/test/integration/languages_int_test.go @@ -3,11 +3,9 @@ package integration import ( "regexp" "testing" - "time" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/testhelpers/suite" - "github.com/ActiveState/termtest" goversion "github.com/hashicorp/go-version" "github.com/ActiveState/cli/internal/testhelpers/e2e" @@ -51,17 +49,18 @@ func (suite *LanguagesIntegrationTestSuite) TestLanguages_install() { ts.PrepareProject("ActiveState-CLI/Languages", "1eb82b25-a564-42ee-a7d4-d51d2ea73cd5") - ts.LoginAsPersistentUser() - cp := ts.Spawn("languages") - cp.Expect("Name") + cp.Expect("Name", e2e.RuntimeSolvingTimeoutOpt) // Cached solves are often slow too cp.Expect("python") cp.ExpectExitCode(0) + cp = ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + cp = ts.Spawn("languages", "install", "python@3.9.16") - cp.Expect("Language updated: python@3.9.16") + cp.Expect("project has been updated") // This can take a little while - cp.ExpectExitCode(0, termtest.OptExpectTimeout(60*time.Second)) + cp.ExpectExitCode(0, e2e.RuntimeSolvingTimeoutOpt) cp = ts.Spawn("languages") cp.Expect("Name") @@ -84,12 +83,9 @@ func (suite *LanguagesIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Python3", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareProject("ActiveState-CLI/Python3", "971e48e4-7f9b-44e6-ad48-86cd03ffc12d") - cp = ts.Spawn("languages", "-o", "json") + cp := ts.Spawn("languages", "-o", "json") cp.Expect(`[{"name":"python","version":`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) @@ -120,14 +116,14 @@ func (suite *LanguagesIntegrationTestSuite) TestWildcards() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) // Test explicit wildcard. cp = ts.Spawn("languages", "install", "python@3.9.x") - cp.Expect("Language updated: python@3.9.x") + cp.Expect("Updated: language/python@3.9.x") cp.ExpectExitCode(0) cp = ts.Spawn("history") cp.Expect("→ >=3.9,<3.10") @@ -139,7 +135,7 @@ func (suite *LanguagesIntegrationTestSuite) TestWildcards() { // Test implicit wildcard. cp = ts.Spawn("languages", "install", "python@3.9") - cp.Expect("Language updated: python@3.9") + cp.Expect("Updated: language/python@3.9.x") cp.ExpectExitCode(0) cp = ts.Spawn("history") cp.Expect("→ >=3.9,<3.10") @@ -147,10 +143,7 @@ func (suite *LanguagesIntegrationTestSuite) TestWildcards() { // Test non-matching version. // Enable the runtime to actually solve the build and invalidate the version. - cp = ts.SpawnWithOpts( - e2e.OptArgs("languages", "install", "python@100"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("languages", "install", "python@100") cp.Expect("Failed") cp.ExpectNotExitCode(0) } diff --git a/test/integration/manifest_int_test.go b/test/integration/manifest_int_test.go index cea7403f6e..c567d83ae6 100644 --- a/test/integration/manifest_int_test.go +++ b/test/integration/manifest_int_test.go @@ -1,9 +1,14 @@ package integration import ( + "fmt" + "path/filepath" + "regexp" + "strings" "testing" "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -14,23 +19,17 @@ type ManifestIntegrationTestSuite struct { } func (suite *ManifestIntegrationTestSuite) TestManifest() { - suite.OnlyRunForTags(tagsuite.Manifest) + suite.OnlyRunForTags(tagsuite.Manifest, tagsuite.Critical) ts := e2e.New(suite.T(), false) defer ts.Close() ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState/cli#9eee7512-b2ab-4600-b78b-ab0cf2e817d8", "."), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState/cli#9eee7512-b2ab-4600-b78b-ab0cf2e817d8", ".") cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) - cp = ts.SpawnWithOpts( - e2e.OptArgs("manifest"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Operating on project: ActiveState/cli", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("manifest") + cp.Expect("Operating on project: ActiveState/cli") cp.Expect("Name") cp.Expect("python") cp.Expect("3.9.13") @@ -39,6 +38,19 @@ func (suite *ManifestIntegrationTestSuite) TestManifest() { cp.Expect("auto → 5.9.0") cp.Expect("None detected") cp.ExpectExitCode(0) + + // Ensure that `state manifest` utilized the cache (checkout should've warmed it) + logFile := ts.LogFiles()[0] + log := string(fileutils.ReadFileUnsafe(logFile)) + matched := false + for _, line := range strings.Split(log, "\n") { + if strings.Contains(line, "GetCache FetchCommit-") { + suite.Require().Regexp(regexp.MustCompile(`FetchCommit-.*result size: [1-9]`), line) + matched = true + break + } + } + suite.Require().True(matched, "log file should contain a line with the FetchCommit call", log) } func (suite *ManifestIntegrationTestSuite) TestManifest_JSON() { @@ -48,17 +60,66 @@ func (suite *ManifestIntegrationTestSuite) TestManifest_JSON() { ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState/cli#9eee7512-b2ab-4600-b78b-ab0cf2e817d8", "."), - ) + cp := ts.Spawn("checkout", "ActiveState/cli#9eee7512-b2ab-4600-b78b-ab0cf2e817d8", ".") cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("manifest", "--output", "json") + cp.ExpectExitCode(0) + AssertValidJSON(suite.T(), cp) + cp.Expect(`"requirements":`) +} + +func (suite *ManifestIntegrationTestSuite) TestManifest_Advanced_Reqs() { + suite.OnlyRunForTags(tagsuite.Manifest, tagsuite.BuildScripts) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.LoginAsPersistentUser() + + cp := ts.Spawn("config", "set", constants.OptinBuildscriptsConfig, "true") + cp.ExpectExitCode(0) + + ts.PrepareActiveStateYAML(`project: https://platform.activestate.com/ActiveState-CLI-Testing/Python-With-Custom-Reqs?branch=main&commitID=92ac7df2-0b0c-42f5-9b25-75b0cb4063f7 +config_version: 1`) // need config_version to be 1 or more so the migrator does not wipe out our build script + bsf := filepath.Join(ts.Dirs.Work, constants.BuildScriptFileName) + err := fileutils.WriteFile(bsf, []byte(fmt.Sprintf( + "```\n"+ + "Project: https://platform.activestate.com/ActiveState-CLI-Testing/Python-With-Custom-Reqs?branch=main&commitID=92ac7df2-0b0c-42f5-9b25-75b0cb4063f7\n"+ + "Time: 2022-07-07T19:51:01.140Z\n"+ + "```\n"+` +runtime = state_tool_artifacts_v1(src = sources) +sources = solve( + at_time = TIME, + requirements = [ + Req(name = "python", namespace = "language", version = Eq(value = "3.9.13")), + Revision(name = "IngWithRevision", revision_id = "%s"), + Unrecognized(name = "SomeOpt", value = "SomeValue") + ] +) +main = runtime +`, e2e.CommitIDNotChecked))) + suite.Require().NoError(err) + + cp = ts.SpawnWithOpts( + e2e.OptArgs("manifest"), + e2e.OptAppendEnv(constants.DisableBuildscriptDirtyCheck+"=true"), // Don't want to commit buildscript + ) + cp.ExpectRe(`IngWithRevision\s+` + e2e.CommitIDNotChecked[0:8] + " ") + cp.Expect("WARNING") + cp.Expect("project has additional build criteria") + cp.Expect("Unrecognized") + cp.Expect(`name = "SomeOpt", value = "SomeValue"`) + cp.ExpectExitCode(0) + cp = ts.SpawnWithOpts( e2e.OptArgs("manifest", "--output", "json"), + e2e.OptAppendEnv(constants.DisableBuildscriptDirtyCheck+"=true"), // Don't want to commit buildscript ) cp.ExpectExitCode(0) - AssertValidJSON(suite.T(), cp) - cp.Expect(`"requirements":`) + out := cp.Output() + out = strings.Replace(out, "\n", "", -1) // Work around words being wrapped on Windows + suite.Require().Contains(out, `{"name":"IngWithRevision","version":{"requested":"00000000-0000-0000-0000-000000000000","resolved":"00000000-0000-0000-0000-000000000000"}}`) + suite.Require().Contains(out, `"unknown_requirements":[{"name":"Unrecognized","value":"name = \"SomeOpt\", value = \"SomeValue\""}]`) } func TestManifestIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/migrator_int_test.go b/test/integration/migrator_int_test.go index 7ace0d64a7..76221c70ea 100644 --- a/test/integration/migrator_int_test.go +++ b/test/integration/migrator_int_test.go @@ -22,9 +22,9 @@ func (suite *MigratorIntegrationTestSuite) TestMigrator() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + ts.PrepareEmptyProject() - cp := ts.SpawnWithOpts(e2e.OptArgs("refresh")) + cp := ts.Spawn("refresh") cp.ExpectExitCode(0) suite.Require().Contains(string(fileutils.ReadFileUnsafe(filepath.Join(ts.Dirs.Work, constants.ConfigFileName))), @@ -39,11 +39,11 @@ func (suite *MigratorIntegrationTestSuite) TestMigrator_Buildscripts() { cp := ts.Spawn("config", "set", constants.OptinBuildscriptsConfig, "true") cp.ExpectExitCode(0) - ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + ts.PrepareEmptyProject() suite.Require().NoFileExists(filepath.Join(ts.Dirs.Work, constants.BuildScriptFileName)) - cp = ts.SpawnWithOpts(e2e.OptArgs("refresh"), e2e.OptAppendEnv(constants.DisableRuntime+"=false")) + cp = ts.Spawn("refresh") cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) suite.Require().FileExists(filepath.Join(ts.Dirs.Work, constants.BuildScriptFileName), ts.DebugMessage("")) diff --git a/test/integration/msg_int_test.go b/test/integration/msg_int_test.go index 7564a2bf38..0224d3ad3d 100644 --- a/test/integration/msg_int_test.go +++ b/test/integration/msg_int_test.go @@ -22,10 +22,8 @@ func (suite *MsgIntegrationTestSuite) TestMessage_None() { ts := e2e.New(suite.T(), false) defer ts.Close() - // We test on config as it just dumps help and has minimal output - // The base state command would also work, but it's output is more verbose and termtest likes to cut off content if it's too long - cp := ts.SpawnWithOpts(e2e.OptArgs("config")) - cp.Expect("Usage:") + cp := ts.Spawn("--version") + cp.Expect("ActiveState CLI by ActiveState Software Inc.") cp.ExpectExitCode(0) // Note: since message failures should fail silently without impacting the user we need to check @@ -74,11 +72,9 @@ func (suite *MsgIntegrationTestSuite) TestMessage_Basic() { msgFile, err := fileutils.WriteTempFileToDir(ts.Dirs.Work, "messages.json", []byte(tt.MessageJson), 0755) suite.Require().NoError(err) - // We test on config as it just dumps help and has minimal output - // The base state command would also work, but it's output is more verbose and termtest likes to cut off content if it's too long - cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) + cp := ts.SpawnWithOpts(e2e.OptArgs("--version"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) cp.Expect(`This is a simple message`) - cp.Expect("Usage:") + cp.Expect("ActiveState CLI by ActiveState Software Inc.") cp.ExpectExitCode(0) // Ensure message doesn't stick around when we run another command @@ -108,10 +104,8 @@ func (suite *MsgIntegrationTestSuite) TestMessage_Basic_PlacementAfter() { ]`, graph.MessagePlacementTypeAfterCmd)), 0755) suite.Require().NoError(err) - // We test on config as it just dumps help and has minimal output - // The base state command would also work, but it's output is more verbose and termtest likes to cut off content if it's too long - cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) - cp.Expect("Usage:") + cp := ts.SpawnWithOpts(e2e.OptArgs("--version"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) + cp.Expect("ActiveState CLI by ActiveState Software Inc.") cp.Expect(`This is a simple message`) cp.ExpectExitCode(0) } @@ -131,19 +125,19 @@ func (suite *MsgIntegrationTestSuite) TestMessage_Basic_InterruptPrompt() { ]`, graph.MessageInterruptTypePrompt)), 0755) suite.Require().NoError(err) - cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) + cp := ts.SpawnWithOpts(e2e.OptArgs("--version"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) cp.Expect(`This is a simple message`) cp.Expect("Press ENTER to continue") time.Sleep(time.Millisecond * 100) - suite.Require().NotContains(cp.Output(), "Usage:") + suite.Require().NotContains(cp.Output(), "ActiveState CLI by ActiveState Software Inc.") cp.SendEnter() - cp.Expect("Usage:") + cp.Expect("ActiveState CLI by ActiveState Software Inc.") cp.ExpectExitCode(0) // Test that non-interactive does not prompt - cp = ts.SpawnWithOpts(e2e.OptArgs("config", "-n"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) + cp = ts.SpawnCmdWithOpts("state", e2e.OptArgs("--version", "-n"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) cp.Expect(`This is a simple message`) - cp.Expect("Usage:") + cp.Expect("ActiveState CLI by ActiveState Software Inc.") cp.ExpectExitCode(0) suite.Require().NotContains(cp.Output(), "Press ENTER to continue") } @@ -162,10 +156,10 @@ func (suite *MsgIntegrationTestSuite) TestMessage_Basic_InterruptExit() { ]`, graph.MessageInterruptTypeExit)), 0755) suite.Require().NoError(err) - cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) + cp := ts.SpawnWithOpts(e2e.OptArgs("--version"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) cp.ExpectExitCode(1) suite.Require().Contains(cp.Snapshot(), "This is a simple message") - suite.Require().NotContains(cp.Output(), "Usage:") + suite.Require().NotContains(cp.Output(), "ActiveState CLI by ActiveState Software Inc.") ts.IgnoreLogErrors() } diff --git a/test/integration/package_int_test.go b/test/integration/package_int_test.go index 95425ef639..8ac91a19f2 100644 --- a/test/integration/package_int_test.go +++ b/test/integration/package_int_test.go @@ -1,20 +1,15 @@ package integration import ( - "fmt" - "path/filepath" - "runtime" "strings" "testing" "time" - "github.com/ActiveState/cli/internal/testhelpers/suite" - "github.com/ActiveState/termtest" - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" + "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" + "github.com/ActiveState/termtest" ) type PackageIntegrationTestSuite struct { @@ -267,128 +262,36 @@ func (suite *PackageIntegrationTestSuite) TestPackage_info() { cp.ExpectExitCode(0) } -func (suite *PackageIntegrationTestSuite) TestPackage_detached_operation() { - suite.OnlyRunForTags(tagsuite.Package) - ts := e2e.New(suite.T(), false) - defer ts.Close() - - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - - suite.Run("install non-existing", func() { - cp := ts.Spawn("install", "json") - cp.Expect("No results found for search term") - cp.Expect("json2") - cp.Wait() - }) - - suite.Run("install", func() { - cp := ts.Spawn("install", "dateparser@0.7.2") - cp.ExpectRe("(?:Package added|being built)", termtest.OptExpectTimeout(30*time.Second)) - cp.Wait() - }) - - suite.Run("install (update)", func() { - cp := ts.Spawn("install", "dateparser@0.7.6") - cp.ExpectRe("(?:Package updated|being built)", termtest.OptExpectTimeout(50*time.Second)) - cp.Wait() - }) - - suite.Run("uninstall", func() { - cp := ts.Spawn("uninstall", "dateparser") - cp.ExpectRe("(?:Package uninstalled|being built)", termtest.OptExpectTimeout(30*time.Second)) - cp.Wait() - }) -} - -func (suite *PackageIntegrationTestSuite) TestPackage_operation() { - suite.OnlyRunForTags(tagsuite.Package) - if runtime.GOOS == "darwin" { - suite.T().Skip("Skipping mac for now as the builds are still too unreliable") - return - } - ts := e2e.New(suite.T(), false) - defer ts.Close() - - user := ts.CreateNewUser() - namespace := fmt.Sprintf("%s/%s", user.Username, "python3-pkgtest") - - cp := ts.Spawn("fork", "ActiveState-CLI/Packages", "--org", user.Username, "--name", "python3-pkgtest") - cp.ExpectExitCode(0) - - cp = ts.Spawn("checkout", namespace, ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - - cp = ts.Spawn("history", "--output=json") - cp.ExpectExitCode(0) - - suite.Run("install", func() { - cp := ts.Spawn("install", "urllib3@1.25.6") - cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username)) - cp.ExpectRe("(?:Package added|being built)", termtest.OptExpectTimeout(30*time.Second)) - cp.Wait() - }) - - suite.Run("install (update)", func() { - cp := ts.Spawn("install", "urllib3@1.25.8") - cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username)) - cp.ExpectRe("(?:Package updated|being built)", termtest.OptExpectTimeout(30*time.Second)) - cp.Wait() - }) - - suite.Run("uninstall", func() { - cp := ts.Spawn("uninstall", "urllib3") - cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username)) - cp.ExpectRe("(?:Package uninstalled|being built)", termtest.OptExpectTimeout(30*time.Second)) - cp.Wait() - }) -} - func (suite *PackageIntegrationTestSuite) TestPackage_operation_multiple() { suite.OnlyRunForTags(tagsuite.Package) - if runtime.GOOS == "darwin" { - suite.T().Skip("Skipping mac for now as the builds are still too unreliable") - return - } ts := e2e.New(suite.T(), false) defer ts.Close() - user := ts.CreateNewUser() - namespace := fmt.Sprintf("%s/%s", user.Username, "python3-pkgtest") - - cp := ts.Spawn("fork", "ActiveState-CLI/Packages", "--org", user.Username, "--name", "python3-pkgtest") - cp.ExpectExitCode(0) + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") - cp = ts.Spawn("checkout", namespace, ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - - cp = ts.Spawn("history", "--output=json") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) suite.Run("install", func() { cp := ts.Spawn("install", "requests", "urllib3@1.25.6") - cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username)) - cp.ExpectRe("(?:Package added|being built)", termtest.OptExpectTimeout(30*time.Second)) + cp.Expect("Operating on project ActiveState-CLI/small-python") + cp.Expect("Added: language/python/requests", termtest.OptExpectTimeout(2*time.Minute)) // Extra time because 2 packages + cp.Expect("Added: language/python/urllib3") cp.Wait() }) suite.Run("install (update)", func() { cp := ts.Spawn("install", "urllib3@1.25.8") - cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username)) - cp.ExpectRe("(?:Package updated|being built)", termtest.OptExpectTimeout(30*time.Second)) + cp.Expect("Operating on project ActiveState-CLI/small-python") + cp.Expect("Updated: language/python/urllib3", e2e.RuntimeSolvingTimeoutOpt) cp.Wait() }) suite.Run("uninstall", func() { cp := ts.Spawn("uninstall", "requests", "urllib3") - cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username)) - cp.ExpectRe("(?:Package uninstalled|being built)", termtest.OptExpectTimeout(30*time.Second)) + cp.Expect("Operating on project ActiveState-CLI/small-python") + cp.Expect("Removed: language/python/requests", e2e.RuntimeSolvingTimeoutOpt) + cp.Expect("Removed: language/python/urllib3") cp.Wait() }) } @@ -399,16 +302,13 @@ func (suite *PackageIntegrationTestSuite) TestPackage_Duplicate() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() - cp = ts.Spawn("install", "requests") // install + cp := ts.Spawn("install", "shared/zlib") // install cp.ExpectExitCode(0) - cp = ts.Spawn("install", "requests") // install again - cp.Expect("already installed") + cp = ts.Spawn("install", "shared/zlib") // install again + cp.Expect(" no changes") cp.ExpectNotExitCode(0) ts.IgnoreLogErrors() @@ -430,6 +330,36 @@ scripts: ts.PrepareCommitIdFile("a9d0bc88-585a-49cf-89c1-6c07af781cff") } +func (suite *PackageIntegrationTestSuite) TestPackage_Install() { + suite.OnlyRunForTags(tagsuite.Package) + + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("install", "requests") + cp.Expect("project has been updated") + cp.ExpectExitCode(0) +} + +func (suite *PackageIntegrationTestSuite) TestPackage_Uninstall() { + suite.OnlyRunForTags(tagsuite.Package) + + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.PrepareProject("ActiveState-CLI-Testing/small-python-with-pkg", "a2115792-2620-4217-89ed-b596c8c11ce3") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("uninstall", "requests") + cp.Expect("project has been updated") + cp.ExpectExitCode(0) +} + func (suite *PackageIntegrationTestSuite) TestPackage_UninstallDoesNotExist() { suite.OnlyRunForTags(tagsuite.Package) @@ -439,7 +369,7 @@ func (suite *PackageIntegrationTestSuite) TestPackage_UninstallDoesNotExist() { suite.PrepareActiveStateYAML(ts) cp := ts.Spawn("uninstall", "doesNotExist") - cp.Expect("does not exist") + cp.Expect("could not be found") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -448,6 +378,30 @@ func (suite *PackageIntegrationTestSuite) TestPackage_UninstallDoesNotExist() { } } +func (suite *PackageIntegrationTestSuite) TestPackage_UninstallDupeMatch() { + suite.OnlyRunForTags(tagsuite.Package) + + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.PrepareProject("ActiveState-CLI-Testing/duplicate-pkg-name", "e5a15d59-9192-446a-a133-9f4c2ebe0898") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("uninstall", "oauth") + cp.Expect("match multiple requirements") + cp.ExpectExitCode(1) + ts.IgnoreLogErrors() + + if strings.Count(cp.Snapshot(), " x ") != 2 { // 2 because "Creating commit x Failed" is also printed + suite.Fail("Expected exactly ONE error message, got: ", cp.Snapshot()) + } + + cp = ts.Spawn("uninstall", "language/python/oauth") + cp.Expect("project has been updated") + cp.ExpectExitCode(0) +} + func (suite *PackageIntegrationTestSuite) TestJSON() { suite.OnlyRunForTags(tagsuite.Package, tagsuite.JSON) ts := e2e.New(suite.T(), false) @@ -458,16 +412,12 @@ func (suite *PackageIntegrationTestSuite) TestJSON() { cp.ExpectExitCode(0) // AssertValidJSON(suite.T(), cp) // currently too large to fit terminal window to validate - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Packages-Perl", "."), - e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), - ) - cp.Expect("Checked out project") + ts.PrepareProject("ActiveState-CLI/Packages-Perl", "b2feab96-f700-47a3-85ef-2ec44c390c6b") + + cp = ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "Text-CSV", "-o", "json"), - ) + cp = ts.Spawn("install", "Text-CSV", "-o", "json") cp.Expect(`{"name":"Text-CSV"`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) @@ -477,79 +427,23 @@ func (suite *PackageIntegrationTestSuite) TestJSON() { cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) - cp = ts.SpawnWithOpts( - e2e.OptArgs("uninstall", "Text-CSV", "-o", "json"), - ) + cp = ts.Spawn("uninstall", "Text-CSV", "-o", "json") cp.Expect(`{"name":"Text-CSV"`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) } -func (suite *PackageIntegrationTestSuite) TestNormalize() { - suite.OnlyRunForTags(tagsuite.Package) - if runtime.GOOS == "darwin" { - suite.T().Skip("Skipping mac for now as the builds are still too unreliable") - return - } - ts := e2e.New(suite.T(), false) - defer ts.Close() - - dir := filepath.Join(ts.Dirs.Work, "normalized") - suite.Require().NoError(fileutils.Mkdir(dir)) - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."), - e2e.OptWD(dir), - ) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "Charset_normalizer"), - e2e.OptWD(dir), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - // Even though we are not sourcing a runtime it can still take time to resolve - // the dependencies and create the commit - cp.Expect("charset-normalizer", e2e.RuntimeSourcingTimeoutOpt) - cp.Expect("is different") - cp.Expect("Charset_normalizer") - cp.ExpectExitCode(0) - - anotherDir := filepath.Join(ts.Dirs.Work, "not-normalized") - suite.Require().NoError(fileutils.Mkdir(anotherDir)) - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."), - e2e.OptWD(anotherDir), - ) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "charset-normalizer"), - e2e.OptWD(anotherDir), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("charset-normalizer", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) - suite.NotContains(cp.Output(), "is different") -} - func (suite *PackageIntegrationTestSuite) TestInstall_InvalidVersion() { suite.OnlyRunForTags(tagsuite.Package) ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "pytest@999.9999.9999"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("install", "pytest@999.9999.9999") // User facing error from build planner // We only assert the state tool curated part of the error as the underlying build planner error may change cp.Expect("Could not plan build") @@ -562,18 +456,15 @@ func (suite *PackageIntegrationTestSuite) TestUpdate_InvalidVersion() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) cp = ts.Spawn("install", "pytest") // install cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "pytest@999.9999.9999"), // update - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), // We DO want to test the runtime part, just not for every step - ) + cp = ts.Spawn("install", "pytest@999.9999.9999") // update // User facing error from build planner // We only assert the state tool curated part of the error as the underlying build planner error may change cp.Expect("Could not plan build") @@ -586,9 +477,9 @@ func (suite *PackageIntegrationTestSuite) TestUpdate() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) cp = ts.Spawn("install", "pytest@7.3.2") // install @@ -604,11 +495,8 @@ func (suite *PackageIntegrationTestSuite) TestUpdate() { cp.Expect("7.3.2") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "pytest@7.4.0"), // update - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), // We DO want to test the runtime part, just not for every step - ) - cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("install", "pytest@7.4.0") // update + cp.ExpectExitCode(0) cp = ts.Spawn("history") cp.Expect("pytest") @@ -626,22 +514,12 @@ func (suite *PackageIntegrationTestSuite) TestRuby() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI-Testing/Ruby", "."), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) + ts.PrepareProject("ActiveState-CLI-Testing/Ruby", "72fadc10-ed8c-4be6-810b-b3de6e017c57") - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "rake"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("install", "rake") cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) - cp = ts.SpawnWithOpts( - e2e.OptArgs("exec", "rake", "--", "--version"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("exec", "rake", "--", "--version") cp.ExpectRe(`rake, version \d+\.\d+\.\d+`) cp.ExpectExitCode(0) } @@ -656,8 +534,7 @@ func (suite *PackageIntegrationTestSuite) TestProjectWithOfflineInstallerAndDock ts.LoginAsPersistentUser() // needed for Enterprise-tier features cp := ts.Spawn("checkout", "ActiveState-CLI/Python-OfflineInstaller-Docker", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) } @@ -666,17 +543,14 @@ func (suite *PackageIntegrationTestSuite) TestResolved() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "requests"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) + cp = ts.Spawn("install", "requests") + cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("packages") cp.Expect("Auto →") cp.ExpectExitCode(0) @@ -689,16 +563,15 @@ func (suite *PackageIntegrationTestSuite) TestCVE_NoPrompt() { ts.LoginAsPersistentUser() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "urllib3@2.0.2"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Warning: Dependency has 2 known vulnerabilities") + // Note: this version has 2 direct vulnerabilities, and 3 indirect vulnerabilities, but since + // we're not prompting, we're only showing a single count. + cp = ts.Spawn("install", "urllib3@2.0.2") + cp.ExpectRe(`Warning: Dependency has .* vulnerabilities`, e2e.RuntimeSolvingTimeoutOpt) cp.ExpectExitCode(0) } @@ -709,28 +582,22 @@ func (suite *PackageIntegrationTestSuite) TestCVE_Prompt() { ts.LoginAsPersistentUser() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + ts.PrepareProject("ActiveState-CLi/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) cp = ts.Spawn("config", "set", "security.prompt.level", "high") cp.ExpectExitCode(0) - cp = ts.Spawn("config", "set", "security.prompt.enabled", "true") + cp = ts.Spawn("config", "set", constants.SecurityPromptConfig, "true") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "urllib3@2.0.2"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Warning: Dependency has 2 known vulnerabilities") + cp = ts.Spawn("install", "urllib3@2.0.2", "--ts=2024-09-10T16:36:34.393Z") + cp.ExpectRe(`Warning: Dependency has .* vulnerabilities`, e2e.RuntimeSolvingTimeoutOpt) cp.Expect("Do you want to continue") cp.SendLine("y") cp.ExpectExitCode(0) - - cp = ts.Spawn("config", "set", "security.prompt.enabled", "false") - cp.ExpectExitCode(0) } func (suite *PackageIntegrationTestSuite) TestCVE_Indirect() { @@ -740,16 +607,16 @@ func (suite *PackageIntegrationTestSuite) TestCVE_Indirect() { ts.LoginAsPersistentUser() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "private/ActiveState-CLI-Testing/language/python/django_dep", "--ts=now"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.ExpectRe(`Warning: Dependency has \d indirect known vulnerabilities`, e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("config", "set", constants.SecurityPromptConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("install", "private/ActiveState-CLI-Testing/language/python/django_dep", "--ts=2024-09-10T16:36:34.393Z") + cp.ExpectRe(`Warning: Dependency has \d+ indirect known vulnerabilities`, e2e.RuntimeSolvingTimeoutOpt) cp.Expect("Do you want to continue") cp.SendLine("n") cp.ExpectExitCode(1) @@ -764,14 +631,9 @@ func (suite *PackageIntegrationTestSuite) TestChangeSummary() { cp.Expect("Successfully set") cp.ExpectExitCode(0) - cp = ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "requests@2.31.0"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("install", "requests@2.31.0") cp.Expect("Resolving Dependencies") cp.Expect("Done") cp.Expect("Installing requests@2.31.0 includes 4 direct dependencies") @@ -779,7 +641,31 @@ func (suite *PackageIntegrationTestSuite) TestChangeSummary() { cp.Expect("├─ ") cp.Expect("├─ ") cp.Expect("└─ ") - cp.Expect("Package added: requests", e2e.RuntimeSourcingTimeoutOpt) + cp.Expect("Added: language/python/requests", e2e.RuntimeSolvingTimeoutOpt) + cp.ExpectExitCode(0) +} + +func (suite *PackageIntegrationTestSuite) TestChangeSummaryShowsAddedForUpdate() { + suite.OnlyRunForTags(tagsuite.Package) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.Expect("Successfully set") + cp.ExpectExitCode(0) + + ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b") + + timestamp := "--ts=2024-08-15T20:07:00.000Z" + + cp = ts.Spawn("install", "jinja2@2.0", timestamp) + cp.Expect("Added: language/python/jinja2") + cp.ExpectExitCode(0) + + cp = ts.Spawn("install", "jinja2@3.1.4", timestamp) + cp.Expect("Installing jinja2@3.1.4 includes 1 direct dep") + cp.Expect("└─ markupsafe@2.1.5") + cp.Expect("Updated: language/python/jinja2") cp.ExpectExitCode(0) } diff --git a/test/integration/performance_expansion_int_test.go b/test/integration/performance_expansion_int_test.go index 91fdd7a84a..27139093d2 100644 --- a/test/integration/performance_expansion_int_test.go +++ b/test/integration/performance_expansion_int_test.go @@ -353,7 +353,7 @@ type scriptPerformanceOptions struct { func (suite *PerformanceExpansionIntegrationTestSuite) testScriptPerformance(opts scriptPerformanceOptions) time.Duration { suite.OnlyRunForTags(tagsuite.Performance) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() suite.startSvc(ts) diff --git a/test/integration/performance_int_test.go b/test/integration/performance_int_test.go index fd74db7bad..be6ca4abfa 100644 --- a/test/integration/performance_int_test.go +++ b/test/integration/performance_int_test.go @@ -55,7 +55,10 @@ func performanceTest(commands []string, expect string, samples int, maxTime time for x := 0; x < samples+1; x++ { opts := []e2e.SpawnOptSetter{ e2e.OptArgs(commands...), - e2e.OptAppendEnv(constants.DisableUpdates+"=true", constants.ProfileEnvVarName+"=true"), + e2e.OptAppendEnv( + constants.DisableUpdates+"=true", + constants.ProfileEnvVarName+"=true", + ), } termtestLogs := &bytes.Buffer{} if verbose { diff --git a/test/integration/pjfile_int_test.go b/test/integration/pjfile_int_test.go index 0ce55c0cf5..6df047d03d 100644 --- a/test/integration/pjfile_int_test.go +++ b/test/integration/pjfile_int_test.go @@ -29,9 +29,7 @@ languages: platform: Windows10Label,Linux64Label `)) - cp := ts.SpawnWithOpts( - e2e.OptArgs("scripts"), - ) + cp := ts.Spawn("scripts") cp.ExpectExitCode(1) ts.IgnoreLogErrors() } diff --git a/test/integration/platforms_int_test.go b/test/integration/platforms_int_test.go index 6f8b5eb587..cf87bf57ad 100644 --- a/test/integration/platforms_int_test.go +++ b/test/integration/platforms_int_test.go @@ -2,9 +2,9 @@ package integration import ( "fmt" - "strings" "testing" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -19,16 +19,13 @@ func (suite *PlatformsIntegrationTestSuite) TestPlatforms_searchSimple() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.PrepareProject("cli-integration-tests/ExercisePlatforms", e2e.CommitIDNotChecked) + ts.PrepareEmptyProject() cp := ts.Spawn("platforms", "search") expectations := []string{ "Darwin", - "Darwin", - "Linux", "Linux", "Windows", - "Windows", } for _, expectation := range expectations { cp.Expect(expectation) @@ -41,7 +38,7 @@ func (suite *PlatformsIntegrationTestSuite) TestPlatforms_listSimple() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.PrepareProject("cli-integration-tests/ExercisePlatforms", "f5a2494d-1b76-4a77-bafa-97b3562c5304") + ts.PrepareEmptyProject() cmds := [][]string{ {"platforms"}, @@ -51,7 +48,7 @@ func (suite *PlatformsIntegrationTestSuite) TestPlatforms_listSimple() { cp := ts.Spawn(cmd...) expectations := []string{ "Linux", - "4.15.0", + "4.18.0", "64", } for _, expectation := range expectations { @@ -66,14 +63,23 @@ func (suite *PlatformsIntegrationTestSuite) TestPlatforms_addRemove() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.LoginAsPersistentUser() - - ts.PrepareProject("ActiveState-CLI/Platforms", "e685d3d8-98bc-4703-927f-e1d7225c6457") + ts.PrepareEmptyProject() platform := "Windows" version := "10.0.17134.1" - cp := ts.Spawn("platforms", "add", fmt.Sprintf("%s@%s", platform, version)) + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("platforms", "remove", fmt.Sprintf("%s@%s", platform, version)) + cp.ExpectExitCode(0) + + cp = ts.Spawn("platforms") + cp.ExpectExitCode(0) + output := cp.Output() + suite.Require().NotContains(output, "Windows", "Windows platform should not be present after removal") + + cp = ts.Spawn("platforms", "add", fmt.Sprintf("%s@%s", platform, version)) cp.ExpectExitCode(0) cp = ts.Spawn("platforms") @@ -85,16 +91,6 @@ func (suite *PlatformsIntegrationTestSuite) TestPlatforms_addRemove() { for _, expectation := range expectations { cp.Expect(expectation) } - - cp = ts.Spawn("platforms", "remove", fmt.Sprintf("%s@%s", platform, version)) - cp.ExpectExitCode(0) - - cp = ts.Spawn("platforms") - cp.ExpectExitCode(0) - output := cp.Output() - if strings.Contains(output, "Windows") { - suite.T().Fatal("Windows platform should not be present after removal") - } } func (suite *PlatformsIntegrationTestSuite) TestPlatforms_addRemoveLatest() { @@ -102,35 +98,53 @@ func (suite *PlatformsIntegrationTestSuite) TestPlatforms_addRemoveLatest() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.LoginAsPersistentUser() - - ts.PrepareProject("ActiveState-CLI/Platforms", "e685d3d8-98bc-4703-927f-e1d7225c6457") + ts.PrepareEmptyProject() platform := "Windows" version := "10.0.17134.1" - cp := ts.Spawn("platforms", "add", "windows") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) - cp = ts.Spawn("platforms") - expectations := []string{ - platform, - version, - "64", - } - for _, expectation := range expectations { - cp.Expect(expectation) - } - cp = ts.Spawn("platforms", "remove", fmt.Sprintf("%s@%s", platform, version)) cp.ExpectExitCode(0) cp = ts.Spawn("platforms") cp.ExpectExitCode(0) output := cp.Output() - if strings.Contains(output, "Windows") { - suite.T().Fatal("Windows platform should not be present after removal") - } + suite.Require().NotContains(output, "Windows", "Windows platform should not be present after removal") + + cp = ts.Spawn("platforms", "add", "windows") + cp.ExpectExitCode(0) + + cp = ts.Spawn("platforms") + cp.Expect(platform) + cp.Expect(version) + cp.Expect("64") + cp.ExpectExitCode(0) +} + +func (suite *PlatformsIntegrationTestSuite) TestPlatforms_addNotFound() { + suite.OnlyRunForTags(tagsuite.Platforms) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.PrepareEmptyProject() + + // OS name doesn't match + cp := ts.Spawn("platforms", "add", "bunnies") + cp.Expect("Could not find") + cp.ExpectExitCode(1) + + // OS version doesn't match + cp = ts.Spawn("platforms", "add", "windows@99.99.99") + cp.Expect("Could not find") + cp.ExpectExitCode(1) + + // bitwidth version doesn't match + cp = ts.Spawn("platforms", "add", "windows", "--bit-width=999") + cp.Expect("Could not find") + cp.ExpectExitCode(1) } func (suite *PlatformsIntegrationTestSuite) TestJSON() { @@ -138,12 +152,9 @@ func (suite *PlatformsIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Python3", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() - cp = ts.Spawn("platforms", "-o", "json") + cp := ts.Spawn("platforms", "-o", "json") cp.Expect(`[{"name":`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) diff --git a/test/integration/prepare_int_test.go b/test/integration/prepare_int_test.go index 3771911647..e639f5d5d6 100644 --- a/test/integration/prepare_int_test.go +++ b/test/integration/prepare_int_test.go @@ -8,22 +8,21 @@ import ( "runtime" "testing" - "github.com/ActiveState/cli/internal/testhelpers/suite" - - svcApp "github.com/ActiveState/cli/cmd/state-svc/app" svcAutostart "github.com/ActiveState/cli/cmd/state-svc/autostart" "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/installation/storage" "github.com/ActiveState/cli/internal/osutils" "github.com/ActiveState/cli/internal/osutils/autostart" "github.com/ActiveState/cli/internal/osutils/user" "github.com/ActiveState/cli/internal/rtutils/singlethread" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/testhelpers/e2e" + "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - rt "github.com/ActiveState/cli/pkg/platform/runtime/target" + rt "github.com/ActiveState/cli/pkg/runtime" + "github.com/ActiveState/cli/pkg/runtime_helpers" ) type PrepareIntegrationTestSuite struct { @@ -31,10 +30,6 @@ type PrepareIntegrationTestSuite struct { } func (suite *PrepareIntegrationTestSuite) TestPrepare() { - // Disable test for v0.36: https://activestatef.atlassian.net/browse/DX-1501. - // This test should be re-enabled by https://activestatef.atlassian.net/browse/DX-1435. - suite.T().SkipNow() - suite.OnlyRunForTags(tagsuite.Prepare) if !e2e.RunningOnCI() { suite.T().Skipf("Skipping TestPrepare when not running on CI or on MacOS, as it modifies PATH") @@ -50,7 +45,6 @@ func (suite *PrepareIntegrationTestSuite) TestPrepare() { cp := ts.SpawnWithOpts( e2e.OptArgs("_prepare"), e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AutostartPathOverrideEnvVarName, autostartDir)), - // e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.ConfigEnvVarName, ts.Dirs.Work)), ) cp.ExpectExitCode(0) @@ -60,12 +54,10 @@ func (suite *PrepareIntegrationTestSuite) TestPrepare() { if isAdmin { return } - suite.AssertConfig(filepath.Join(ts.Dirs.Cache, "bin")) + suite.AssertConfig(storage.CachePath()) // Verify autostart was enabled. - app, err := svcApp.New() - suite.Require().NoError(err) - enabled, err := autostart.IsEnabled(app.Path(), svcAutostart.Options) + enabled, err := autostart.IsEnabled(constants.StateSvcCmd, svcAutostart.Options) suite.Require().NoError(err) suite.Assert().True(enabled, "autostart is not enabled") @@ -75,13 +67,13 @@ func (suite *PrepareIntegrationTestSuite) TestPrepare() { suite.Require().NoError(err) profile := filepath.Join(homeDir, ".profile") profileContents := string(fileutils.ReadFileUnsafe(profile)) - suite.Contains(profileContents, app.Path(), "autostart should be configured for Linux server environment") + suite.Contains(profileContents, constants.StateSvcCmd, "autostart should be configured for Linux server environment") } // Verify autostart can be disabled. - err = autostart.Disable(app.Path(), svcAutostart.Options) + err = autostart.Disable(constants.StateSvcCmd, svcAutostart.Options) suite.Require().NoError(err) - enabled, err = autostart.IsEnabled(app.Path(), svcAutostart.Options) + enabled, err = autostart.IsEnabled(constants.StateSvcCmd, svcAutostart.Options) suite.Require().NoError(err) suite.Assert().False(enabled, "autostart is still enabled") @@ -91,7 +83,13 @@ func (suite *PrepareIntegrationTestSuite) TestPrepare() { suite.Require().NoError(err) profile := filepath.Join(homeDir, ".profile") profileContents := fileutils.ReadFileUnsafe(profile) - suite.NotContains(profileContents, app.Exec, "autostart should not be configured for Linux server environment anymore") + suite.NotContains(profileContents, constants.StateSvcCmd, "autostart should not be configured for Linux server environment anymore") + } + + // Verify the Windows shortcuts were installed. + if runtime.GOOS == "windows" { + shortcutDir := filepath.Join(ts.Dirs.HomeDir, "AppData", "Roaming", "Microsoft", "Windows", "Start Menu", "Programs", "ActiveState") + suite.DirExists(shortcutDir, "shortcut dir should exist after prepare") } } @@ -119,18 +117,16 @@ func (suite *PrepareIntegrationTestSuite) AssertConfig(target string) { func (suite *PrepareIntegrationTestSuite) TestResetExecutors() { suite.OnlyRunForTags(tagsuite.Prepare) - ts := e2e.New(suite.T(), true, constants.DisableRuntime+"=false") + ts := e2e.New(suite.T(), false) err := ts.ClearCache() suite.Require().NoError(err) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work, "--default"), - ) + cp := ts.Spawn("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work, "--default") cp.Expect("This project will always be available for use") cp.Expect("Downloading") - cp.Expect("Installing") - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) + cp.Expect("Installing", e2e.RuntimeSourcingTimeoutOpt) + cp.Expect("Activated") cp.SendLine("exit") cp.ExpectExitCode(0) @@ -146,26 +142,26 @@ func (suite *PrepareIntegrationTestSuite) TestResetExecutors() { suite.Assert().NoError(err, "should have removed executor directory, to ensure that it gets re-created") // check existens of exec dir - targetDir := rt.ProjectDirToTargetDir(ts.Dirs.Work, ts.Dirs.Cache) - projectExecDir := setup.ExecDir(targetDir) + targetDir := filepath.Join(ts.Dirs.Cache, runtime_helpers.DirNameFromProjectDir(ts.Dirs.Work)) + projectExecDir := rt.ExecutorsPath(targetDir) suite.DirExists(projectExecDir) - // remove complete marker to force re-creation of executors - err = os.Remove(filepath.Join(targetDir, constants.LocalRuntimeEnvironmentDirectory, constants.RuntimeInstallationCompleteMarker)) - suite.Assert().NoError(err, "removal of complete marker should have worked") + // Invalidate hash + hashPath := filepath.Join(targetDir, ".activestate", "hash.txt") + suite.Require().NoError(fileutils.WriteFile(hashPath, []byte("bogus"))) cp = ts.Spawn("_prepare") cp.ExpectExitCode(0) - suite.FileExists(filepath.Join(globalExecDir, "python3"+osutils.ExeExtension)) - err = os.RemoveAll(projectExecDir) - suite.Assert().NoError(err, "should have removed executor directory, to ensure that it gets re-created") + suite.Require().FileExists(filepath.Join(globalExecDir, "python3"+osutils.ExeExtension), ts.DebugMessage("")) + suite.Require().NoError(os.RemoveAll(projectExecDir), "should have removed executor directory, to ensure that it gets re-created") cp = ts.Spawn("activate") cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) cp.SendLine("which python3") - cp.SendLine("python3 --version") + cp.SendLine("python3") cp.Expect("ActiveState") + cp.SendLine("exit()") // exit from Python interpreter cp.SendLine("exit") cp.ExpectExitCode(0) diff --git a/test/integration/progress_int_test.go b/test/integration/progress_int_test.go index 3799cba1b2..f8102edc38 100644 --- a/test/integration/progress_int_test.go +++ b/test/integration/progress_int_test.go @@ -3,7 +3,6 @@ package integration import ( "testing" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" @@ -19,24 +18,18 @@ func (suite *ProgressIntegrationTestSuite) TestProgress() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/small-python"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") + cp.Expect("Resolving Dependencies") + cp.ExpectRe(`[^.]+?✔ Done`, e2e.RuntimeSolvingTimeoutOpt) cp.Expect(locale.T("install_runtime")) cp.Expect("Checked out", e2e.RuntimeSourcingTimeoutOpt) - suite.Assert().NotContains(cp.Output(), "...") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "small-python2", "--non-interactive"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect(locale.T("setup_runtime")) - cp.Expect("...") + cp = ts.Spawn("checkout", "ActiveState-CLI/Empty", "Empty2", "--non-interactive") + cp.Expect("Resolving Dependencies") + cp.ExpectRe(`\.+ ✔ Done`, e2e.RuntimeSolvingTimeoutOpt) cp.Expect("Checked out", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) - } func TestProgressIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/projects_int_test.go b/test/integration/projects_int_test.go index 8ede089da0..d60c8f335a 100644 --- a/test/integration/projects_int_test.go +++ b/test/integration/projects_int_test.go @@ -21,25 +21,12 @@ func (suite *ProjectsIntegrationTestSuite) TestProjects() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python")) - cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") cp.ExpectExitCode(0) // Verify local checkouts and executables are grouped together under projects. - cp = ts.SpawnWithOpts(e2e.OptArgs("projects")) - cp.Expect("Python3") - cp.Expect("Local Checkout") - if runtime.GOOS != "windows" { - cp.Expect(ts.Dirs.Work) - } else { - // Windows uses the long path here. - longPath, _ := fileutils.GetLongPathName(ts.Dirs.Work) - cp.Expect(longPath) - } - cp.Expect("Executables") - cp.Expect(ts.Dirs.Cache) - cp.Expect("small-python") + cp = ts.Spawn("projects") + cp.Expect("Empty") cp.Expect("Local Checkout") if runtime.GOOS != "windows" { cp.Expect(ts.Dirs.Work) @@ -58,9 +45,7 @@ func (suite *ProjectsIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python") - cp.ExpectExitCode(0) - cp = ts.Spawn("checkout", "ActiveState-CLI/Python3") + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") cp.ExpectExitCode(0) cp = ts.Spawn("projects", "-o", "json") cp.Expect(`[{"name":`) @@ -87,8 +72,8 @@ func (suite *ProjectsIntegrationTestSuite) TestEdit_Name() { // What we expect the project name to be and what we want to change it to. // This can change if the test failed previously. var ( - originalName = fmt.Sprintf("Edit-Test-%s", runtime.GOOS) - newName = fmt.Sprintf("Edit-Rename-%s", runtime.GOOS) + originalName = fmt.Sprintf("Edit-Test2-%s", runtime.GOOS) + newName = fmt.Sprintf("Edit-Rename2-%s", runtime.GOOS) ) cp := ts.Spawn("checkout", fmt.Sprintf("ActiveState-CLI/%s", originalName)) @@ -169,9 +154,9 @@ func (suite *ProjectsIntegrationTestSuite) TestMove() { ts.LoginAsPersistentUser() // Just test interactivity, since we only have one integration test org. - cp := ts.Spawn("projects", "move", "ActiveState-CLI/small-python", "ActiveState-CLI") + cp := ts.Spawn("projects", "move", "ActiveState-CLI/Empty", "ActiveState-CLI") cp.Expect("You are about to move") - cp.Expect("ActiveState-CLI/small-python") + cp.Expect("ActiveState-CLI/Empty") cp.Expect("ActiveState-CLI") cp.Expect("Continue? (y/N)") cp.SendLine("n") diff --git a/test/integration/publish_int_test.go b/test/integration/publish_int_test.go index 709cde17ab..5e1caf8def 100644 --- a/test/integration/publish_int_test.go +++ b/test/integration/publish_int_test.go @@ -52,10 +52,10 @@ func (suite *PublishIntegrationTestSuite) TestPublish() { expect expect } - tempFile := fileutils.TempFilePathUnsafe("", "*.zip") + tempFile := fileutils.TempFilePath("", "*.zip") defer os.Remove(tempFile) - tempFileInvalid := fileutils.TempFilePathUnsafe("", "*.notzip") + tempFileInvalid := fileutils.TempFilePath("", "*.notzip") defer os.Remove(tempFileInvalid) ts := e2e.New(suite.T(), false) diff --git a/test/integration/pull_int_test.go b/test/integration/pull_int_test.go index a5c3a329a4..e2a7eea4a8 100644 --- a/test/integration/pull_int_test.go +++ b/test/integration/pull_int_test.go @@ -28,11 +28,11 @@ func (suite *PullIntegrationTestSuite) TestPull() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.PrepareProject("ActiveState-CLI/Python3", "59404293-e5a9-4fd0-8843-77cd4761b5b5") + ts.PrepareProject("ActiveState-CLI/Empty", "265f9914-ad4d-4e0a-a128-9d4e8c5db820") cp := ts.Spawn("pull") cp.Expect("Operating on project") - cp.Expect("ActiveState-CLI/Python3") + cp.Expect("ActiveState-CLI/Empty") cp.Expect("activestate.yaml has been updated") cp.ExpectExitCode(0) @@ -45,21 +45,21 @@ func (suite *PullIntegrationTestSuite) TestPull() { func (suite *PullIntegrationTestSuite) TestPull_Merge() { suite.OnlyRunForTags(tagsuite.Pull) - unPulledCommit := "882ae76e-fbb7-4989-acc9-9a8b87d49388" + unPulledCommit := "8c2537cc-0f49-4fdf-86d4-f7ed8df6a0ae" ts := e2e.New(suite.T(), false) defer ts.Close() - ts.PrepareProject("ActiveState-CLI/cli", unPulledCommit) + ts.PrepareProject("ActiveState-CLI/Empty", unPulledCommit) ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts(e2e.OptArgs("push")) + cp := ts.Spawn("push") cp.Expect("Your project has new changes available") cp.ExpectExitCode(1) ts.IgnoreLogErrors() - cp = ts.SpawnWithOpts(e2e.OptArgs("pull")) + cp = ts.Spawn("pull") cp.Expect("Merging history") cp.ExpectExitCode(0) @@ -82,16 +82,15 @@ func (suite *PullIntegrationTestSuite) TestMergeBuildScript() { cp := ts.Spawn("config", "set", constants.OptinBuildscriptsConfig, "true") cp.ExpectExitCode(0) - cp = ts.Spawn("checkout", "ActiveState-CLI/Merge#447b8363-024c-4143-bf4e-c96989314fdf", ".") - cp.Expect("Skipping runtime setup") + cp = ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("checkout", "ActiveState-CLI/Merge2#6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8", ".") cp.Expect("Checked out") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "requests"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Package added", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("install", "shared/zlib") + cp.Expect("Added", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) proj, err := project.FromPath(ts.Dirs.Work) @@ -102,7 +101,7 @@ func (suite *PullIntegrationTestSuite) TestMergeBuildScript() { cp = ts.Spawn("pull") cp.Expect("The following changes will be merged") - cp.Expect("requests (2.30.0 → Auto)") + cp.Expect("zlib (1.3.1 → Auto)") cp.Expect("Unable to automatically merge build scripts") cp.ExpectNotExitCode(0) ts.IgnoreLogErrors() @@ -118,7 +117,7 @@ func (suite *PullIntegrationTestSuite) TestMergeBuildScript() { // Note: even though the buildscript merge failed, a merge commit was still created (we just // ignore it). After resolving buildscript conflicts, `state commit` should always have something // new to commit. - remoteHeadCommit := "d908a758-6a81-40d4-b0eb-87069cd7f07d" + remoteHeadCommit := "2c461e7c-43d2-4e43-b169-a255c305becd" commit, err := localcommit.Get(ts.Dirs.Work) suite.Require().NoError(err) suite.Assert().Equal(remoteHeadCommit, commit.String(), "localcommit should have been updated to remote commit") diff --git a/test/integration/push_int_test.go b/test/integration/push_int_test.go index be3b95b52c..a19dd5323b 100644 --- a/test/integration/push_int_test.go +++ b/test/integration/push_int_test.go @@ -50,15 +50,22 @@ func (suite *PushIntegrationTestSuite) TestInitAndPush() { suite.OnlyRunForTags(tagsuite.Push) ts := e2e.New(suite.T(), false) defer ts.Close() + ts.LoginAsPersistentUser() + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + pname := strutils.UUID() namespace := fmt.Sprintf("%s/%s", suite.username, pname) - cp := ts.Spawn( - "init", - "--language", - suite.languageFull, - namespace, - ".", + cp = ts.SpawnWithOpts( + e2e.OptArgs( + "init", + "--language", + suite.languageFull, + namespace, + ".", + ), ) cp.Expect("successfully initialized") cp.ExpectExitCode(0) @@ -74,16 +81,16 @@ func (suite *PushIntegrationTestSuite) TestInitAndPush() { suite.Require().NotEmpty(pj.BranchName(), "branch was not set after running push for project creation") // ensure that we are logged out - cp = ts.Spawn(tagsuite.Auth, "logout") + cp = ts.Spawn("auth", "logout") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.OptArgs("install", suite.extraPackage)) + cp = ts.Spawn("install", suite.extraPackage) switch runtime.GOOS { case "darwin": - cp.ExpectRe("added|being built", termtest.OptExpectTimeout(60*time.Second)) // while cold storage is off + cp.ExpectRe("Added|being built", e2e.RuntimeSolvingTimeoutOpt) // while cold storage is off cp.Wait() default: - cp.Expect("added", termtest.OptExpectTimeout(60*time.Second)) + cp.Expect("Added", e2e.RuntimeSolvingTimeoutOpt) cp.ExpectExitCode(0) } @@ -95,7 +102,7 @@ func (suite *PushIntegrationTestSuite) TestInitAndPush() { ts.LoginAsPersistentUser() - cp = ts.SpawnWithOpts(e2e.OptArgs("push", namespace)) + cp = ts.Spawn("push", namespace) cp.Expect("Pushing to project") cp.ExpectExitCode(0) } @@ -112,19 +119,20 @@ func (suite *PushIntegrationTestSuite) TestPush_NoPermission_NewProject() { user := ts.CreateNewUser() pname := strutils.UUID() - cp := ts.SpawnWithOpts(e2e.OptArgs("activate", suite.baseProject, "--path", ts.Dirs.Work)) - cp.Expect("Activated", termtest.OptExpectTimeout(40*time.Second)) - cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) - cp.SendLine("exit") + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") + cp.ExpectExitCode(0) + + cp = ts.Spawn("checkout", suite.baseProject, ".") + cp.Expect("Checked out project") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.OptArgs("install", suite.extraPackage)) + cp = ts.Spawn("install", suite.extraPackage) switch runtime.GOOS { case "darwin": - cp.ExpectRe("added|being built", termtest.OptExpectTimeout(60*time.Second)) // while cold storage is off + cp.ExpectRe("Added|being built", e2e.RuntimeSolvingTimeoutOpt) // while cold storage is off cp.Wait() default: - cp.Expect("added", termtest.OptExpectTimeout(60*time.Second)) + cp.Expect("Added", e2e.RuntimeSolvingTimeoutOpt) cp.ExpectExitCode(0) } @@ -133,7 +141,7 @@ func (suite *PushIntegrationTestSuite) TestPush_NoPermission_NewProject() { suite.Require().NoError(err) suite.Require().Contains(pjfile.Project, suite.baseProject) - cp = ts.SpawnWithOpts(e2e.OptArgs("push")) + cp = ts.Spawn("push") cp.Expect("not authorized") cp.Expect("(Y/n)") cp.SendLine("y") @@ -164,33 +172,30 @@ func (suite *PushIntegrationTestSuite) TestCarlisle() { namespace := fmt.Sprintf("%s/%s", suite.username, pname) wd := filepath.Join(ts.Dirs.Work, namespace) - cp := ts.SpawnWithOpts( - e2e.OptArgs( - "activate", suite.baseProject, - "--path", wd), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("activate", suite.baseProject, "--path", wd) // The activestate.yaml on Windows runs custom activation to set shortcuts and file associations. cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) cp.SendLine("exit") cp.ExpectExitCode(0) // ensure that we are logged out - cp = ts.Spawn(tagsuite.Auth, "logout") + cp = ts.Spawn("auth", "logout") + cp.ExpectExitCode(0) + + cp = ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) // anonymous commit - cp = ts.SpawnWithOpts(e2e.OptArgs( - "install", suite.extraPackage), + cp = ts.SpawnWithOpts( + e2e.OptArgs("install", suite.extraPackage), e2e.OptWD(wd), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) switch runtime.GOOS { case "darwin": - cp.ExpectRe("added|being built", e2e.RuntimeSourcingTimeoutOpt) // while cold storage is off + cp.ExpectRe("Added|being built", e2e.RuntimeSourcingTimeoutOpt) // while cold storage is off cp.Wait() default: - cp.Expect("added", e2e.RuntimeSourcingTimeoutOpt) + cp.Expect("Added", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) } @@ -201,7 +206,7 @@ func (suite *PushIntegrationTestSuite) TestCarlisle() { ts.LoginAsPersistentUser() cp = ts.SpawnWithOpts(e2e.OptArgs("push", namespace), e2e.OptWD(wd)) - cp.Expect("continue? (Y/n)") + cp.Expect("Continue? (Y/n)") cp.SendLine("y") cp.Expect("Project created") cp.ExpectExitCode(0) @@ -215,7 +220,7 @@ func (suite *PushIntegrationTestSuite) TestPush_NoProject() { defer ts.Close() ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts(e2e.OptArgs("push")) + cp := ts.Spawn("push") cp.Expect("No project found") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -231,9 +236,9 @@ func (suite *PushIntegrationTestSuite) TestPush_NoAuth() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.PrepareProject("ActiveState-CLI/cli", "882ae76e-fbb7-4989-acc9-9a8b87d49388") + ts.PrepareEmptyProject() - cp := ts.SpawnWithOpts(e2e.OptArgs("push")) + cp := ts.Spawn("push") cp.Expect("you need to be authenticated") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -249,11 +254,10 @@ func (suite *PushIntegrationTestSuite) TestPush_NoChanges() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python", ".")) - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() ts.LoginAsPersistentUser() - cp = ts.SpawnWithOpts(e2e.OptArgs("push")) + cp := ts.Spawn("push") cp.Expect("no local changes to push") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -274,7 +278,7 @@ func (suite *PushIntegrationTestSuite) TestPush_NameInUse() { ts.LoginAsPersistentUser() // Target project already exists - cp := ts.SpawnWithOpts(e2e.OptArgs("push", "-n", "ActiveState-CLI/push-error-test")) + cp := ts.Spawn("push", "-n", "ActiveState-CLI/push-error-test") cp.Expect("already in use") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -290,7 +294,7 @@ func (suite *PushIntegrationTestSuite) TestPush_Aborted() { suite.OnlyRunForTags(tagsuite.Push) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() // Source project we do not have access to @@ -298,7 +302,7 @@ func (suite *PushIntegrationTestSuite) TestPush_Aborted() { ts.LoginAsPersistentUser() // Target project already exists - cp := ts.SpawnWithOpts(e2e.OptArgs("push")) + cp := ts.Spawn("push") cp.Expect("Would you like to create a new project") cp.SendLine("n") cp.Expect("Project creation aborted by user", termtest.OptExpectTimeout(5*time.Second)) @@ -313,7 +317,7 @@ func (suite *PushIntegrationTestSuite) TestPush_Aborted() { func (suite *PushIntegrationTestSuite) TestPush_InvalidHistory() { suite.OnlyRunForTags(tagsuite.Push) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() // Note the commit we're using here is for another project, in order to repro the error @@ -321,7 +325,7 @@ func (suite *PushIntegrationTestSuite) TestPush_InvalidHistory() { ts.LoginAsPersistentUser() // Target project already exists - cp := ts.SpawnWithOpts(e2e.OptArgs("push", "ActiveState-CLI/push-error-test")) + cp := ts.Spawn("push", "ActiveState-CLI/push-error-test") cp.Expect("commit history does not match") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -334,14 +338,14 @@ func (suite *PushIntegrationTestSuite) TestPush_InvalidHistory() { func (suite *PushIntegrationTestSuite) TestPush_PullNeeded() { suite.OnlyRunForTags(tagsuite.Push) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() ts.PrepareProject("ActiveState-CLI/push-error-test", "899c9b4c-d28d-441a-9c28-c84819ba8b1a") ts.LoginAsPersistentUser() // Target project already exists - cp := ts.SpawnWithOpts(e2e.OptArgs("push")) + cp := ts.Spawn("push") cp.Expect("changes available that need to be merged") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -361,7 +365,7 @@ func (suite *PushIntegrationTestSuite) TestPush_Outdated() { ts.PrepareProject("ActiveState-CLI/cli", unPushedCommit) ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts(e2e.OptArgs("push")) + cp := ts.Spawn("push") cp.Expect("Your project has new changes available") cp.ExpectExitCode(1) ts.IgnoreLogErrors() diff --git a/test/integration/refresh_int_test.go b/test/integration/refresh_int_test.go index 213b78cef8..d71dfd1c0b 100644 --- a/test/integration/refresh_int_test.go +++ b/test/integration/refresh_int_test.go @@ -4,7 +4,6 @@ import ( "fmt" "testing" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -21,40 +20,25 @@ func (suite *RefreshIntegrationTestSuite) TestRefresh() { suite.PrepareActiveStateYAML(ts, "ActiveState-CLI/Branches", "main", "35af7414-b44b-4fd7-aa93-2ecad337ed2b") - cp := ts.SpawnWithOpts( - e2e.OptArgs("refresh"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Setting Up Runtime") + cp := ts.Spawn("refresh") cp.Expect("Runtime updated", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("exec", "--", "python3", "-c", "import requests"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("exec", "--", "python3", "-c", "import requests") cp.Expect("ModuleNotFoundError") cp.ExpectExitCode(1) ts.IgnoreLogErrors() suite.PrepareActiveStateYAML(ts, "ActiveState-CLI/Branches", "secondbranch", "46c83477-d580-43e2-a0c6-f5d3677517f1") - cp = ts.SpawnWithOpts( - e2e.OptArgs("refresh"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Setting Up Runtime") + cp = ts.Spawn("refresh") cp.Expect("Runtime updated", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("exec", "--", "python3", "-c", "import requests"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("exec", "--", "python3", "-c", "import requests") cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt) cp = ts.Spawn("refresh") - suite.Assert().NotContains(cp.Output(), "Setting Up Runtime", "Unchanged runtime should not refresh") - cp.Expect("Runtime updated") + cp.Expect("already up to date") cp.ExpectExitCode(0) } @@ -63,14 +47,14 @@ func (suite *RefreshIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - suite.PrepareActiveStateYAML(ts, "ActiveState-CLI/Branches", "main", "35af7414-b44b-4fd7-aa93-2ecad337ed2b") + ts.PrepareEmptyProject() cp := ts.Spawn("refresh", "-o", "json") cp.Expect(`"namespace":`) cp.Expect(`"path":`) cp.Expect(`"executables":`) cp.ExpectExitCode(0) - // AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice + AssertValidJSON(suite.T(), cp) } func (suite *RefreshIntegrationTestSuite) PrepareActiveStateYAML(ts *e2e.Session, namespace, branch, commitID string) { diff --git a/test/integration/remote_installer_int_test.go b/test/integration/remote_installer_int_test.go index 94f885da4c..65949c3fb4 100644 --- a/test/integration/remote_installer_int_test.go +++ b/test/integration/remote_installer_int_test.go @@ -2,14 +2,19 @@ package integration import ( "fmt" + "os/exec" "path/filepath" + "runtime" + "strings" "testing" + svcAutostart "github.com/ActiveState/cli/cmd/state-svc/autostart" anaConst "github.com/ActiveState/cli/internal/analytics/constants" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/environment" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/osutils" + "github.com/ActiveState/cli/internal/osutils/autostart" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -22,9 +27,31 @@ type RemoteInstallIntegrationTestSuite struct { func (suite *RemoteInstallIntegrationTestSuite) TestInstall() { suite.OnlyRunForTags(tagsuite.RemoteInstaller, tagsuite.Critical) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() + // Setup running the remote installer in restricted powershell mode. + if runtime.GOOS == "windows" { + getPolicy := func() string { + policy, err := exec.Command("powershell.exe", "Get-ExecutionPolicy").CombinedOutput() + suite.Require().NoError(err, "error getting policy: "+string(policy)) + return strings.TrimSpace(string(policy)) + } + setPolicy := func(policy string) { + output, err := exec.Command("powershell.exe", "Set-ExecutionPolicy", "-ExecutionPolicy", policy).CombinedOutput() + suite.Require().NoError(err, "error setting policy: "+string(output)) + } + + policy := getPolicy() + defer func() { + setPolicy(policy) + suite.Assert().Equal(policy, getPolicy(), "execution policy was not reset to '"+policy+"'; subsequent test results may be invalid") + }() + + setPolicy("Restricted") + suite.Assert().Equal("Restricted", getPolicy(), "should have set powershell policy to 'Restricted'") + } + tests := []struct { Name string Version string @@ -103,6 +130,13 @@ func (suite *RemoteInstallIntegrationTestSuite) TestInstall() { } } suite.Assert().True(sessionTokenFound, "sessionToken was not found in analytics") + + // Verify a startup shortcut was created (we use powershell to create it). + if runtime.GOOS == "windows" { + shortcut, err := autostart.AutostartPath("", svcAutostart.Options) + suite.Require().NoError(err) + suite.Assert().FileExists(shortcut) + } }) } } @@ -112,7 +146,7 @@ func (s *RemoteInstallIntegrationTestSuite) setupTest(ts *e2e.Session) { buildDir := fileutils.Join(root, "build") installerExe := filepath.Join(buildDir, constants.StateRemoteInstallerCmd+osutils.ExeExtension) if !fileutils.FileExists(installerExe) { - s.T().Fatal("E2E tests require a state-remote-installer binary. Run `state run build-installer`.") + s.T().Fatal("E2E tests require a state-remote-installer binary. Run `state run build-remote-installer`.") } s.remoteInstallerExe = ts.CopyExeToDir(installerExe, filepath.Join(ts.Dirs.Base, "installer")) } diff --git a/test/integration/reset_int_test.go b/test/integration/reset_int_test.go index a8f080af99..e7cc862ea9 100644 --- a/test/integration/reset_int_test.go +++ b/test/integration/reset_int_test.go @@ -10,6 +10,7 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" + "github.com/ActiveState/cli/pkg/localcommit" ) type ResetIntegrationTestSuite struct { @@ -21,30 +22,32 @@ func (suite *ResetIntegrationTestSuite) TestReset() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Reset#3a2d095d-efd6-4be0-b824-21de94fc4ad6", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") + ts.PrepareEmptyProject() + commitID, err := localcommit.Get(ts.Dirs.Work) + suite.Require().NoError(err) + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) - cp = ts.Spawn("install", "requests") - cp.Expect("Package added") + cp = ts.Spawn("install", "shared/zlib") + cp.Expect("Added") cp.ExpectExitCode(0) cp = ts.Spawn("history") - cp.Expect("requests") + cp.Expect("zlib") cp.ExpectExitCode(0) cp = ts.Spawn("reset") - cp.Expect("Your project will be reset to 3a2d095d-efd6-4be0-b824-21de94fc4ad6") + cp.Expect("Your project will be reset to " + commitID.String()) cp.Expect("Are you sure") cp.Expect("(y/N)") cp.SendLine("y") - cp.Expect("Successfully reset to commit: 3a2d095d-efd6-4be0-b824-21de94fc4ad6") + cp.Expect("Successfully reset to commit: " + commitID.String()) cp.ExpectExitCode(0) cp = ts.Spawn("history") cp.ExpectExitCode(0) - suite.Assert().NotContains(cp.Snapshot(), "requests") + suite.Assert().NotContains(cp.Snapshot(), "zlib") cp = ts.Spawn("reset") cp.Expect("You are already on the latest commit") @@ -60,13 +63,10 @@ func (suite *ResetIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Branches#46c83477-d580-43e2-a0c6-f5d3677517f1", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() - cp = ts.Spawn("reset", "35af7414-b44b-4fd7-aa93-2ecad337ed2b", "-o", "json") - cp.Expect(`{"commitID":"35af7414-b44b-4fd7-aa93-2ecad337ed2b"}`) + cp := ts.Spawn("reset", "265f9914-ad4d-4e0a-a128-9d4e8c5db820", "-o", "json") + cp.Expect(`{"commitID":"265f9914-ad4d-4e0a-a128-9d4e8c5db820"}`) cp.ExpectExitCode(0) } @@ -75,25 +75,22 @@ func (suite *ResetIntegrationTestSuite) TestRevertInvalidURL() { ts := e2e.New(suite.T(), false) defer ts.Close() - commitID := "3a2d095d-efd6-4be0-b824-21de94fc4ad6" - - cp := ts.Spawn("checkout", "ActiveState-CLI/Reset#"+commitID, ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() + commitID, err := localcommit.Get(ts.Dirs.Work) + suite.Require().NoError(err) contents := fileutils.ReadFileUnsafe(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)) - contents = bytes.Replace(contents, []byte("3a2d095d-efd6-4be0-b824-21de94fc4ad6"), []byte(""), 1) - err := fileutils.WriteFile(filepath.Join(ts.Dirs.Work, constants.ConfigFileName), contents) + contents = bytes.Replace(contents, []byte(commitID.String()), []byte(""), 1) + err = fileutils.WriteFile(filepath.Join(ts.Dirs.Work, constants.ConfigFileName), contents) suite.Require().NoError(err) - cp = ts.Spawn("install", "requests") + cp := ts.Spawn("install", "language/python/requests") cp.Expect("invalid commit ID") cp.Expect("Please run 'state reset' to fix it.") cp.ExpectNotExitCode(0) cp = ts.Spawn("reset", "-n") - cp.Expect("Successfully reset to commit: " + commitID) + cp.Expect("Successfully reset to commit: " + commitID.String()) cp.ExpectExitCode(0) } diff --git a/test/integration/revert_int_test.go b/test/integration/revert_int_test.go index 1dfdddfddb..15bc46617d 100644 --- a/test/integration/revert_int_test.go +++ b/test/integration/revert_int_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "path/filepath" "testing" "github.com/ActiveState/cli/internal/constants" @@ -19,30 +18,22 @@ func (suite *RevertIntegrationTestSuite) TestRevert() { suite.OnlyRunForTags(tagsuite.Revert) ts := e2e.New(suite.T(), false) defer ts.Close() - ts.LoginAsPersistentUser() namespace := "ActiveState-CLI/Revert" - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", namespace)) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - wd := filepath.Join(ts.Dirs.Work, "Revert") + ts.PrepareProject(namespace, "903bf49a-6719-47f0-ae70-450d69532ece") // Revert the commit that added urllib3. commitID := "1f4f4f7d-7883-400e-b2ad-a5803c018ecd" - cp = ts.SpawnWithOpts(e2e.OptArgs("revert", commitID), e2e.OptWD(wd)) + cp := ts.Spawn("revert", commitID) cp.Expect(fmt.Sprintf("Operating on project %s", namespace)) cp.Expect("You are about to revert the following commit:") cp.Expect(commitID) cp.SendLine("y") - cp.Expect("Successfully reverted commit:") + cp.Expect("Successfully reverted commit:", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) // Verify the commit history has both the new revert commit and all prior history. - cp = ts.SpawnWithOpts( - e2e.OptArgs("history"), - e2e.OptWD(wd), - ) + cp = ts.Spawn("history") cp.Expect("Reverted commit for commit " + commitID) cp.Expect("- urllib3") cp.Expect("+ argparse") // parent commit @@ -50,10 +41,7 @@ func (suite *RevertIntegrationTestSuite) TestRevert() { cp.Expect("+ python") // initial commit // Verify that argparse still exists (it was not reverted along with urllib3). - cp = ts.SpawnWithOpts( - e2e.OptArgs("shell", "Revert"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("shell", "Revert") cp.ExpectInput(e2e.RuntimeSourcingTimeoutOpt) cp.SendLine("python3") cp.Expect("3.9.15") @@ -71,13 +59,13 @@ func (suite *RevertIntegrationTestSuite) TestRevertRemote() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Revert", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + ts.PrepareProject("ActiveState-CLI/Revert", "75ae9c67-df55-4a95-be6f-b7975e5bb523") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) cp = ts.Spawn("install", "requests") - cp.Expect("Package added") + cp.Expect("Added: language/python/requests") cp.ExpectExitCode(0) cp = ts.Spawn("revert", "REMOTE", "--non-interactive") @@ -95,17 +83,12 @@ func (suite *RevertIntegrationTestSuite) TestRevert_failsOnCommitNotInHistory() ts := e2e.New(suite.T(), false) defer ts.Close() - namespace := "ActiveState-CLI/small-python" - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", namespace)) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - wd := filepath.Join(ts.Dirs.Work, "small-python") + ts.PrepareEmptyProject() // valid commit id not from project commitID := "cb9b1aab-8e40-4a1d-8ad6-5ea112da40f1" // from Perl-5.32 - cp = ts.SpawnWithOpts(e2e.OptArgs("revert", commitID), e2e.OptWD(wd)) - cp.Expect(fmt.Sprintf("Operating on project %s", namespace)) + cp := ts.Spawn("revert", commitID) + cp.Expect("Operating on project ActiveState-CLI/Empty") cp.SendLine("Y") cp.Expect(commitID) cp.Expect("not found") @@ -117,30 +100,25 @@ func (suite *RevertIntegrationTestSuite) TestRevertTo() { suite.OnlyRunForTags(tagsuite.Revert) ts := e2e.New(suite.T(), false) defer ts.Close() - ts.LoginAsPersistentUser() namespace := "ActiveState-CLI/Revert" - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", namespace)) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + ts.PrepareProject(namespace, "903bf49a-6719-47f0-ae70-450d69532ece") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) - wd := filepath.Join(ts.Dirs.Work, "Revert") // Revert the commit that added urllib3. commitID := "1f4f4f7d-7883-400e-b2ad-a5803c018ecd" - cp = ts.SpawnWithOpts(e2e.OptArgs("revert", "--to", commitID), e2e.OptWD(wd)) + cp = ts.Spawn("revert", "--to", commitID) cp.Expect(fmt.Sprintf("Operating on project %s", namespace)) - cp.SendLine("Y") cp.Expect("You are about to revert to the following commit:") cp.Expect(commitID) + cp.SendLine("Y") cp.Expect("Successfully reverted to commit:") cp.ExpectExitCode(0) // Verify the commit history has both the new revert commit and all prior history. - cp = ts.SpawnWithOpts( - e2e.OptArgs("history"), - e2e.OptWD(wd), - ) + cp = ts.Spawn("history") cp.Expect("Revert to commit " + commitID) cp.Expect("- argparse") // effectively reverting previous commit cp.Expect("+ argparse") // commit being effectively reverted @@ -153,17 +131,12 @@ func (suite *RevertIntegrationTestSuite) TestRevertTo_failsOnCommitNotInHistory( ts := e2e.New(suite.T(), false) defer ts.Close() - namespace := "ActiveState-CLI/small-python" - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", namespace)) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - wd := filepath.Join(ts.Dirs.Work, "small-python") + ts.PrepareEmptyProject() // valid commit id not from project commitID := "cb9b1aab-8e40-4a1d-8ad6-5ea112da40f1" // from Perl-5.32 - cp = ts.SpawnWithOpts(e2e.OptArgs("revert", "--to", commitID), e2e.OptWD(wd)) - cp.Expect(fmt.Sprintf("Operating on project %s", namespace)) + cp := ts.Spawn("revert", "--to", commitID) + cp.Expect("Operating on project ActiveState-CLI/Empty") cp.SendLine("Y") cp.Expect(commitID) cp.Expect("not found") @@ -176,15 +149,15 @@ func (suite *RevertIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Revert", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + ts.PrepareProject("ActiveState-CLI/Revert", "903bf49a-6719-47f0-ae70-450d69532ece") + + cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true") cp.ExpectExitCode(0) cp = ts.Spawn("revert", "--to", "1f4f4f7d-7883-400e-b2ad-a5803c018ecd", "-o", "json") - cp.Expect(`{"current_commit_id":`) + cp.Expect(`{"current_commit_id":`, e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) - // AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice + AssertValidJSON(suite.T(), cp) } func TestRevertIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/run_int_test.go b/test/integration/run_int_test.go index e2e6f81615..f7ce434f1f 100644 --- a/test/integration/run_int_test.go +++ b/test/integration/run_int_test.go @@ -10,14 +10,12 @@ import ( "testing" "time" - "github.com/ActiveState/cli/internal/testhelpers/suite" - "github.com/ActiveState/termtest" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/environment" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" + "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/ActiveState/cli/pkg/project" ) @@ -26,15 +24,14 @@ type RunIntegrationTestSuite struct { tagsuite.Suite } -func (suite *RunIntegrationTestSuite) createProjectFile(ts *e2e.Session, pythonVersion int) { +func (suite *RunIntegrationTestSuite) createProjectFile(ts *e2e.Session, name, commitID string) { root := environment.GetRootPathUnsafe() interruptScript := filepath.Join(root, "test", "integration", "assets", "run", "interrupt.go") err := fileutils.CopyFile(interruptScript, filepath.Join(ts.Dirs.Work, "interrupt.go")) suite.Require().NoError(err) - // ActiveState-CLI/Python3 is just a place-holder that is never used configFileContent := strings.TrimPrefix(fmt.Sprintf(` -project: https://platform.activestate.com/ActiveState-CLI/Python%d +project: https://platform.activestate.com/%s scripts: - name: test-interrupt description: A script that sleeps for a very long time. It should be interrupted. The first interrupt does not terminate. @@ -70,10 +67,10 @@ scripts: exit 123 standalone: true language: bash -`, pythonVersion), "\n") +`, name), "\n") ts.PrepareActiveStateYAML(configFileContent) - ts.PrepareCommitIdFile("fbc613d6-b0b1-4f84-b26e-4aa5869c4e54") + ts.PrepareCommitIdFile(commitID) } func (suite *RunIntegrationTestSuite) SetupTest() { @@ -105,15 +102,17 @@ func (suite *RunIntegrationTestSuite) TestInActivatedEnv() { ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 3) + suite.createProjectFile(ts, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") cp := ts.Spawn("activate") - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) + cp.Expect("Activated") + cp.ExpectInput() + // We're on Linux CI, so it's okay to use the OS's installed Python for this test. + // It's costly to source our own for this test. cp.SendLine(fmt.Sprintf("%s run testMultipleLanguages", ts.Exe)) cp.Expect("Operating on project") - cp.Expect("ActiveState-CLI/Python3") + cp.Expect("ActiveState-CLI/Empty") cp.Expect("3") cp.SendLine(fmt.Sprintf("%s run test-interrupt", cp.Executable())) @@ -142,11 +141,11 @@ func (suite *RunIntegrationTestSuite) TestScriptBashSubshell() { ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 3) + suite.createProjectFile(ts, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") cp := ts.SpawnWithOpts(e2e.OptArgs("activate"), e2e.OptAppendEnv("SHELL=bash")) - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) + cp.Expect("Activated") + cp.ExpectInput() cp.SendLine("helloWorld") cp.Expect("Hello World!") @@ -163,7 +162,7 @@ func (suite *RunIntegrationTestSuite) TestOneInterrupt() { } ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 3) + suite.createProjectFile(ts, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") cp := ts.Spawn("run", "test-interrupt") cp.Expect("Start of script") @@ -184,9 +183,7 @@ func (suite *RunIntegrationTestSuite) TestTwoInterrupts() { } ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 3) - - ts.LoginAsPersistentUser() + suite.createProjectFile(ts, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") cp := ts.Spawn("run", "test-interrupt") cp.Expect("Start of script") @@ -206,7 +203,7 @@ func (suite *RunIntegrationTestSuite) TestRun_Help() { suite.OnlyRunForTags(tagsuite.Run) ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 3) + suite.createProjectFile(ts, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") cp := ts.Spawn("run", "-h") cp.Expect("Usage") @@ -218,7 +215,7 @@ func (suite *RunIntegrationTestSuite) TestRun_ExitCode() { suite.OnlyRunForTags(tagsuite.Run, tagsuite.ExitCode) ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 3) + suite.createProjectFile(ts, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") cp := ts.Spawn("run", "nonZeroExit") cp.ExpectExitCode(123) @@ -229,14 +226,11 @@ func (suite *RunIntegrationTestSuite) TestRun_Unauthenticated() { ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 2) + suite.createProjectFile(ts, "ActiveState-CLI/Python2", "fbc613d6-b0b1-4f84-b26e-4aa5869c4e54") - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("activate") cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) + cp.ExpectInput() cp.SendLine(fmt.Sprintf("%s run testMultipleLanguages", cp.Executable())) cp.Expect("2") @@ -251,7 +245,7 @@ func (suite *RunIntegrationTestSuite) TestRun_DeprecatedLackingLanguage() { ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 3) + suite.createProjectFile(ts, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") cp := ts.Spawn("run", "helloWorld") cp.Expect("Deprecation Warning", termtest.OptExpectTimeout(5*time.Second)) @@ -263,7 +257,7 @@ func (suite *RunIntegrationTestSuite) TestRun_BadLanguage() { ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 3) + suite.createProjectFile(ts, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") asyFilename := filepath.Join(ts.Dirs.Work, "activestate.yaml") asyFile, err := os.OpenFile(asyFilename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) @@ -294,13 +288,10 @@ func (suite *RunIntegrationTestSuite) TestRun_Perl_Variable() { cp := ts.SpawnWithOpts( e2e.OptArgs("activate"), - e2e.OptAppendEnv( - constants.DisableRuntime+"=false", - "PERL_VERSION=does_not_exist", - ), + e2e.OptAppendEnv("PERL_VERSION=does_not_exist"), ) cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) + cp.ExpectInput() cp.SendLine("perl -MEnglish -e 'print $PERL_VERSION'") cp.Expect("v5.32.0") @@ -313,7 +304,7 @@ func (suite *RunIntegrationTestSuite) TestRun_Args() { ts := e2e.New(suite.T(), false) defer ts.Close() - suite.createProjectFile(ts, 3) + suite.createProjectFile(ts, "ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") asyFilename := filepath.Join(ts.Dirs.Work, "activestate.yaml") asyFile, err := os.OpenFile(asyFilename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) @@ -324,7 +315,7 @@ func (suite *RunIntegrationTestSuite) TestRun_Args() { cmd := `if [ "$1" = "<3" ]; then echo heart; fi` if runtime.GOOS == "windows" { cmd = `@echo off - if "%1"=="<3" (echo heart)` // need to match indent of YAML below + if %1=="<3" (echo heart)` // need to match indent of YAML below } _, err = asyFile.WriteString(strings.TrimPrefix(fmt.Sprintf(` - name: args @@ -335,12 +326,6 @@ func (suite *RunIntegrationTestSuite) TestRun_Args() { suite.Require().NoError(err, "extra config is appended") arg := "<3" - if runtime.GOOS == "windows" { - // The '<' needs to be escaped with '^', and I don't know why. There is no way around it. - // The other exec and shell integration tests that test arg passing do not need this escape. - // Only this batch test does. - arg = "^<3" - } cp := ts.Spawn("run", "args", arg) cp.Expect("heart", termtest.OptExpectTimeout(5*time.Second)) } diff --git a/test/integration/runtime_int_test.go b/test/integration/runtime_int_test.go index 9dcc94aa6f..55b440c199 100644 --- a/test/integration/runtime_int_test.go +++ b/test/integration/runtime_int_test.go @@ -12,8 +12,9 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/osutil" "github.com/ActiveState/cli/internal/testhelpers/suite" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/ActiveState/cli/pkg/platform/runtime/setup" - "github.com/ActiveState/cli/pkg/platform/runtime/target" + "github.com/ActiveState/cli/pkg/project" + rt "github.com/ActiveState/cli/pkg/runtime" + "github.com/ActiveState/cli/pkg/runtime_helpers" ) // Disabled due to DX-1514 @@ -50,11 +51,6 @@ import ( suite.Require().NoError(err) eventHandler := events.NewRuntimeEventHandler(mockProgress, nil, logfile) - if value, set := os.LookupEnv(constants.DisableRuntime); set { - os.Setenv(constants.DisableRuntime, "false") - defer os.Setenv(constants.DisableRuntime, value) - } - rt, err := runtime.New(offlineTarget, analytics, nil, nil) suite.Require().Error(err) err = rt.Update(eventHandler) @@ -83,29 +79,32 @@ type RuntimeIntegrationTestSuite struct { } func (suite *RuntimeIntegrationTestSuite) TestInterruptSetup() { + if runtime.GOOS == "windows" { + // https://activestatef.atlassian.net/browse/DX-2926 + suite.T().Skip("interrupting on windows is currently broken when ran via CI") + } + suite.OnlyRunForTags(tagsuite.Interrupt) ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/test-interrupt-small-python#863c45e2-3626-49b6-893c-c15e85a17241", "."), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/test-interrupt-small-python#863c45e2-3626-49b6-893c-c15e85a17241", ".") cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) - targetDir := target.ProjectDirToTargetDir(ts.Dirs.Work, ts.Dirs.Cache) - pythonExe := filepath.Join(setup.ExecDir(targetDir), "python3"+osutils.ExeExtension) + proj, err := project.FromPath(ts.Dirs.Work) + suite.Require().NoError(err) + + execPath := rt.ExecutorsPath(filepath.Join(ts.Dirs.Cache, runtime_helpers.DirNameFromProjectDir(proj.Dir()))) + pythonExe := filepath.Join(execPath, "python3"+osutils.ExeExtension) + cp = ts.SpawnCmd(pythonExe, "-c", `print(__import__('sys').version)`) cp.Expect("3.8.8") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("pull"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false", - constants.RuntimeSetupWaitEnvVarName+"=true"), - ) - time.Sleep(30 * time.Second) + cp = ts.Spawn("pull") + cp.Expect("Downloading") cp.SendCtrlC() // cancel pull/update + cp.ExpectExitCode(1) cp = ts.SpawnCmd(pythonExe, "-c", `print(__import__('sys').version)`) cp.Expect("3.8.8") // current runtime still works @@ -121,22 +120,14 @@ func (suite *RuntimeIntegrationTestSuite) TestInUse() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Perl-5.36", ".") - cp.Expect("Skipping runtime setup") - cp.ExpectExitCode(0) + ts.PrepareProject("ActiveState-CLI/Empty", "b55d0e63-db48-43c4-8341-e2b7a1cc134c") - cp = ts.SpawnWithOpts( - e2e.OptArgs("shell"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("shell") cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) cp.SendLine("perl") time.Sleep(1 * time.Second) // allow time for perl to start up - cp2 := ts.SpawnWithOpts( - e2e.OptArgs("install", "DateTime"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp2 := ts.Spawn("install", "DateTime") cp2.Expect("currently in use", e2e.RuntimeSourcingTimeoutOpt) cp2.Expect("perl") cp2.ExpectNotExitCode(0) @@ -175,25 +166,45 @@ func (suite *RuntimeIntegrationTestSuite) TestBuildInProgress() { cp.Expect("Successfully published") cp.ExpectExitCode(0) - cp = ts.Spawn("checkout", "ActiveState-CLI/Perl-5.36", ".") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() - cp = ts.SpawnWithOpts( - e2e.OptArgs("install", "private/"+e2e.PersistentUsername+"/hello-world", "--ts", "now"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("install", "private/"+e2e.PersistentUsername+"/hello-world", "--ts", "now") cp.Expect("Build Log") cp.Expect("Building") cp.Expect("All dependencies have been installed and verified", e2e.RuntimeBuildSourcingTimeoutOpt) - cp.Expect("Package added: hello-world") + cp.Expect("Added: private/" + e2e.PersistentUsername + "/hello-world") + cp.ExpectExitCode(0) + + cp = ts.Spawn("exec", "main") + cp.Expect("Hello world!") + cp.ExpectExitCode(0) +} + +func (suite *RuntimeIntegrationTestSuite) TestIgnoreEnvironmentVars() { + suite.OnlyRunForTags(tagsuite.Environment) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") + cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) + pythonPath := "my/path" + cp = ts.SpawnWithOpts( - e2e.OptArgs("exec", "main"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), + e2e.OptArgs("exec", "python3", "--", "-c", `print(__import__("os").environ["PYTHONPATH"])`), + e2e.OptAppendEnv("PYTHONPATH="+pythonPath), ) - cp.Expect("Hello world!") + cp.ExpectExitCode(0) + suite.Assert().NotContains(cp.Snapshot(), pythonPath) + + cp = ts.SpawnWithOpts( + e2e.OptArgs("exec", "python3", "--", "-c", `print(__import__("os").environ["PYTHONPATH"])`), + e2e.OptAppendEnv( + "PYTHONPATH="+pythonPath, + constants.IgnoreEnvEnvVarName+"=PYTHONPATH", + )) + cp.Expect(pythonPath) cp.ExpectExitCode(0) } diff --git a/test/integration/scripts_int_test.go b/test/integration/scripts_int_test.go index 4c56c45566..b1196d535a 100644 --- a/test/integration/scripts_int_test.go +++ b/test/integration/scripts_int_test.go @@ -15,7 +15,7 @@ type ScriptsIntegrationTestSuite struct { func (suite *ScriptsIntegrationTestSuite) setupConfigFile(ts *e2e.Session) { configFileContent := strings.TrimSpace(` -project: "https://platform.activestate.com/ScriptOrg/ScriptProject" +project: "https://platform.activestate.com/ActiveState-CLI/Empty?branch=main&commitID=6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8" scripts: - name: first-script value: echo "first script" diff --git a/test/integration/shared_int_test.go b/test/integration/shared_int_test.go index 71f4331f1d..60b3e89385 100644 --- a/test/integration/shared_int_test.go +++ b/test/integration/shared_int_test.go @@ -9,7 +9,6 @@ import ( "github.com/stretchr/testify/assert" - "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/testhelpers/e2e" ) @@ -23,20 +22,25 @@ func init() { // AssertValidJSON asserts that the previous command emitted valid JSON and did not attempt to emit // any non-JSON/structured output. // This should only be called after a command has executed and all output is available. -func AssertValidJSON(t *testing.T, cp *e2e.SpawnedCmd) { +func AssertValidJSON(t *testing.T, cp *e2e.SpawnedCmd) []byte { output := cp.StrippedSnapshot() - output = strings.TrimPrefix(output, locale.T("notice_runtime_disabled")) + if strings.Contains(output, `"errors":[`) { + assert.NotContains(t, output, `output not supported`, "The command attempted to emit non-JSON/structured output:\n"+output) + } if runtime.GOOS != "windows" { assert.True(t, json.Valid([]byte(output)), "The command produced invalid JSON/structured output:\n"+output) + return []byte(output) } else { - // Windows can trim the last byte for some reason. - assert.True( - t, - json.Valid([]byte(output)) || json.Valid([]byte(output+"}")) || json.Valid([]byte(output+"]")), - "The command produced invalid JSON/structured output:\n"+output, - ) - } - if strings.Contains(output, `"errors":[`) { - assert.NotContains(t, output, `output not supported`, "The command attempted to emit non-JSON/structured output:\n"+output) + switch { + case json.Valid([]byte(output)): + return []byte(output) + case json.Valid([]byte(output + "}")): + return []byte(output + "}") + case json.Valid([]byte(output + "]")): + return []byte(output + "]") + } + t.Fatal("The command produced invalid JSON/structured output:\n" + output) } + t.Fatal("Unreachable") + return nil } diff --git a/test/integration/shell_int_test.go b/test/integration/shell_int_test.go index 8938de8631..286257008b 100644 --- a/test/integration/shell_int_test.go +++ b/test/integration/shell_int_test.go @@ -14,6 +14,7 @@ import ( "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" + "github.com/ActiveState/cli/internal/rtutils/singlethread" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/subshell/bash" "github.com/ActiveState/cli/internal/subshell/sscommon" @@ -33,20 +34,14 @@ func (suite *ShellIntegrationTestSuite) TestShell() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/small-python"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/small-python") cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) args := []string{"small-python", "ActiveState-CLI/small-python"} for _, arg := range args { - cp := ts.SpawnWithOpts( - e2e.OptArgs("shell", arg), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) + cp := ts.Spawn("shell", arg) + cp.Expect("Activated") cp.ExpectInput() cp.SendLine("python3 --version") @@ -72,9 +67,7 @@ func (suite *ShellIntegrationTestSuite) TestShell() { // Check for project not checked out. args = []string{"Python-3.9", "ActiveState-CLI/Python-3.9"} for _, arg := range args { - cp := ts.SpawnWithOpts( - e2e.OptArgs("shell", arg), - ) + cp := ts.Spawn("shell", arg) cp.Expect("Cannot find the Python-3.9 project") cp.ExpectExitCode(1) } @@ -87,22 +80,16 @@ func (suite *ShellIntegrationTestSuite) TestDefaultShell() { defer ts.Close() // Checkout. - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python")) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") + cp.Expect("Checked out") cp.ExpectExitCode(0) // Use. - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "ActiveState-CLI/small-python"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("use", "ActiveState-CLI/Empty") + cp.Expect("Switched to project") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("shell"), - ) + cp = ts.Spawn("shell") cp.Expect("Activated") cp.ExpectInput() cp.SendLine("exit") @@ -115,9 +102,7 @@ func (suite *ShellIntegrationTestSuite) TestCwdShell() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", "ActiveState-CLI/small-python"), - ) + cp := ts.Spawn("activate", "ActiveState-CLI/Empty") cp.Expect("Activated") cp.ExpectInput() cp.SendLine("exit") @@ -125,7 +110,7 @@ func (suite *ShellIntegrationTestSuite) TestCwdShell() { cp = ts.SpawnWithOpts( e2e.OptArgs("shell"), - e2e.OptWD(filepath.Join(ts.Dirs.Work, "small-python")), + e2e.OptWD(filepath.Join(ts.Dirs.Work, "Empty")), ) cp.Expect("Activated") cp.ExpectInput() @@ -139,9 +124,7 @@ func (suite *ShellIntegrationTestSuite) TestCd() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate", "ActiveState-CLI/small-python"), - ) + cp := ts.Spawn("activate", "ActiveState-CLI/Empty") cp.Expect("Activated") cp.ExpectInput() cp.SendLine("exit") @@ -152,7 +135,7 @@ func (suite *ShellIntegrationTestSuite) TestCd() { suite.Require().NoError(err) cp = ts.SpawnWithOpts( - e2e.OptArgs("shell", "ActiveState-CLI/small-python"), + e2e.OptArgs("shell", "ActiveState-CLI/Empty"), e2e.OptWD(subdir), ) cp.Expect("Activated") @@ -166,7 +149,7 @@ func (suite *ShellIntegrationTestSuite) TestCd() { cp.SendLine("exit") cp = ts.SpawnWithOpts( - e2e.OptArgs("shell", "ActiveState-CLI/small-python", "--cd"), + e2e.OptArgs("shell", "ActiveState-CLI/Empty", "--cd"), e2e.OptWD(subdir), ) cp.Expect("Activated") @@ -188,22 +171,18 @@ func (suite *ShellIntegrationTestSuite) TestDefaultNoLongerExists() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") cp.Expect("Checked out project") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "ActiveState-CLI/Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("use", "ActiveState-CLI/Empty") cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) - err := os.RemoveAll(filepath.Join(ts.Dirs.Work, "Python3")) + err := os.RemoveAll(filepath.Join(ts.Dirs.Work, "Empty")) suite.Require().NoError(err) - cp = ts.SpawnWithOpts(e2e.OptArgs("shell")) + cp = ts.Spawn("shell") cp.Expect("Cannot find your project") cp.ExpectExitCode(1) } @@ -216,7 +195,7 @@ func (suite *ShellIntegrationTestSuite) TestUseShellUpdates() { suite.SetupRCFile(ts) - cp := ts.Spawn("checkout", "ActiveState-CLI/Python3") + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") cp.Expect("Checked out project") cp.ExpectExitCode(0) @@ -230,9 +209,8 @@ func (suite *ShellIntegrationTestSuite) TestUseShellUpdates() { } cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "ActiveState-CLI/Python3"), + e2e.OptArgs("use", "ActiveState-CLI/Empty"), e2e.OptAppendEnv("SHELL=bash"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) @@ -273,14 +251,9 @@ func (suite *ShellIntegrationTestSuite) TestRuby() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI-Testing/Ruby", ".") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) + ts.PrepareProject("ActiveState-CLI-Testing/Ruby", "72fadc10-ed8c-4be6-810b-b3de6e017c57") - cp = ts.SpawnWithOpts( - e2e.OptArgs("shell"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("shell") cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectInput() cp.SendLine("ruby -v") @@ -297,7 +270,7 @@ func (suite *ShellIntegrationTestSuite) TestNestedShellNotification() { var ss subshell.SubShell var rcFile string - env := []string{"ACTIVESTATE_CLI_DISABLE_RUNTIME=false"} + env := []string{} switch runtime.GOOS { case "darwin": ss = &zsh.SubShell{} @@ -316,78 +289,45 @@ func (suite *ShellIntegrationTestSuite) TestNestedShellNotification() { suite.Require().Equal(filepath.Dir(rcFile), ts.Dirs.HomeDir, "rc file not in test suite homedir") suite.Require().Contains(string(fileutils.ReadFileUnsafe(rcFile)), "State Tool is operating on project") - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python") + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.OptArgs("shell", "small-python"), + e2e.OptArgs("shell", "Empty"), e2e.OptAppendEnv(env...)) cp.Expect("Activated") suite.Assert().NotContains(cp.Snapshot(), "State Tool is operating on project") cp.SendLine(fmt.Sprintf(`export HOME="%s"`, ts.Dirs.HomeDir)) // some shells do not forward this cp.SendLine(ss.Binary()) // platform-specific shell (zsh on macOS, bash on Linux, etc.) - cp.Expect("State Tool is operating on project ActiveState-CLI/small-python") + cp.Expect("State Tool is operating on project ActiveState-CLI/Empty") cp.SendLine("exit") // subshell within a subshell cp.SendLine("exit") cp.ExpectExitCode(0) } -func (suite *ShellIntegrationTestSuite) TestPs1() { - if runtime.GOOS == "windows" { - return // cmd.exe does not have a PS1 to modify - } - suite.OnlyRunForTags(tagsuite.Shell) - ts := e2e.New(suite.T(), false) - defer ts.Close() - - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python") - cp.Expect("Checked out project") - cp.ExpectExitCode(0) - - cp = ts.SpawnWithOpts( - e2e.OptArgs("shell", "small-python"), - ) - cp.Expect("Activated") - cp.Expect("[ActiveState-CLI/small-python]") - cp.SendLine("exit") - cp.ExpectExitCode(0) - - cp = ts.Spawn("config", "set", constants.PreservePs1ConfigKey, "true") - cp.ExpectExitCode(0) - - cp = ts.Spawn("shell", "small-python") - cp.Expect("Activated") - suite.Assert().NotContains(cp.Snapshot(), "[ActiveState-CLI/small-python]") - cp.SendLine("exit") - cp.ExpectExitCode(0) -} - func (suite *ShellIntegrationTestSuite) TestProjectOrder() { suite.OnlyRunForTags(tagsuite.Critical, tagsuite.Shell) ts := e2e.New(suite.T(), false) defer ts.Close() // First, set up a new project with a subproject. - cp := ts.Spawn("checkout", "ActiveState-CLI/Perl-5.32", "project") - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty", "project") cp.Expect("Checked out project") cp.ExpectExitCode(0) projectDir := filepath.Join(ts.Dirs.Work, "project") cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Perl-5.32", "subproject"), + e2e.OptArgs("checkout", "ActiveState-CLI/Empty", "subproject"), e2e.OptWD(projectDir), ) - cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) subprojectDir := filepath.Join(projectDir, "subproject") // Then set up a separate project and make it the default. - cp = ts.Spawn("checkout", "ActiveState-CLI/Perl-5.32", "default") - cp.Expect("Skipping runtime setup") + cp = ts.Spawn("checkout", "ActiveState-CLI/Empty", "default") cp.Expect("Checked out project") cp.ExpectExitCode(0) defaultDir := filepath.Join(ts.Dirs.Work, "default") @@ -395,9 +335,7 @@ func (suite *ShellIntegrationTestSuite) TestProjectOrder() { cp = ts.SpawnWithOpts( e2e.OptArgs("use"), e2e.OptWD(defaultDir), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) - cp.Expect("Setting Up Runtime", e2e.RuntimeSourcingTimeoutOpt) cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) cp.Expect(defaultDir) cp.ExpectExitCode(0) @@ -413,14 +351,13 @@ func (suite *ShellIntegrationTestSuite) TestProjectOrder() { e2e.OptWD(projectDir), ) cp.Expect(projectDir) - cp.ExpectExitCode(0) + cp.ExpectExit() // Run `state shell` in this project, change to the subproject directory, and assert the parent // project is used instead of the subproject. cp = ts.SpawnWithOpts( e2e.OptArgs("shell"), e2e.OptWD(projectDir), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.Expect("Opening shell", e2e.RuntimeSourcingTimeoutOpt) cp.Expect(projectDir) @@ -428,7 +365,7 @@ func (suite *ShellIntegrationTestSuite) TestProjectOrder() { cp.SendLine("state refresh") cp.Expect(projectDir) // not subprojectDir cp.SendLine("exit") - cp.Expect("Deactivated") + // cp.Expect("Deactivated") // Disabled for now due to https://activestatef.atlassian.net/browse/DX-2901 cp.ExpectExit() // exit code varies depending on shell; just assert the shell exited // After exiting the shell, assert the subproject is used instead of the parent project. @@ -437,7 +374,7 @@ func (suite *ShellIntegrationTestSuite) TestProjectOrder() { e2e.OptWD(subprojectDir), ) cp.Expect(subprojectDir) - cp.ExpectExitCode(0) + cp.ExpectExit() // If a project subdirectory does not contain an activestate.yaml file, assert the project that // owns the subdirectory will be used. @@ -448,7 +385,7 @@ func (suite *ShellIntegrationTestSuite) TestProjectOrder() { e2e.OptWD(nestedDir), ) cp.Expect(subprojectDir) - cp.ExpectExitCode(0) + cp.ExpectExit() // Change to an empty directory and assert the default project is used. cp = ts.SpawnWithOpts( @@ -456,7 +393,7 @@ func (suite *ShellIntegrationTestSuite) TestProjectOrder() { e2e.OptWD(emptyDir), ) cp.Expect(defaultDir) - cp.ExpectExitCode(0) + cp.ExpectExit() // If none of the above, assert an error. cp = ts.Spawn("use", "reset", "-n") @@ -466,7 +403,7 @@ func (suite *ShellIntegrationTestSuite) TestProjectOrder() { e2e.OptArgs("refresh"), e2e.OptWD(emptyDir), ) - cp.ExpectNotExitCode(0) + cp.ExpectExit() } func (suite *ShellIntegrationTestSuite) TestScriptAlias() { @@ -475,8 +412,7 @@ func (suite *ShellIntegrationTestSuite) TestScriptAlias() { defer ts.Close() cp := ts.Spawn("checkout", "ActiveState-CLI/Perl-5.32", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) suite.NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "testargs.pl"), []byte(` @@ -501,10 +437,7 @@ events:`, lang, splat), 1) suite.Require().NoError(fileutils.WriteFile(asyFilename, []byte(contents))) // Verify that running a script as a command with an argument containing special characters works. - cp = ts.SpawnWithOpts( - e2e.OptArgs("shell"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("shell") cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectInput() cp.SendLine(`args "<3"`) @@ -514,6 +447,48 @@ events:`, lang, splat), 1) cp.ExpectExit() // exit code varies depending on shell; just assert the shell exited } +func (suite *ShellIntegrationTestSuite) TestWindowsShells() { + if runtime.GOOS != "windows" { + suite.T().Skip("Windows only test") + } + + suite.OnlyRunForTags(tagsuite.Critical, tagsuite.Shell) + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.PrepareProject("ActiveState-CLI/Empty", "6d79f2ae-f8b5-46bd-917a-d4b2558ec7b8") + + hostname, err := os.Hostname() + suite.Require().NoError(err) + cp := ts.SpawnCmdWithOpts( + "cmd", + e2e.OptArgs("/C", "state", "shell"), + e2e.OptAppendEnv(constants.OverrideShellEnvVarName+"="), + ) + cp.ExpectInput() + cp.SendLine("hostname") + cp.Expect(hostname) // cmd.exe shows the actual hostname + cp.SendLine("exit") + cp.ExpectExitCode(0) + + // Clear configured shell. + cfg, err := config.NewCustom(ts.Dirs.Config, singlethread.New(), true) + suite.Require().NoError(err) + err = cfg.Set(subshell.ConfigKeyShell, "") + suite.Require().NoError(err) + + cp = ts.SpawnCmdWithOpts( + "powershell", + e2e.OptArgs("-Command", "state", "shell"), + e2e.OptAppendEnv(constants.OverrideShellEnvVarName+"="), + ) + cp.ExpectInput() + cp.SendLine("$host.name") + cp.Expect("ConsoleHost") // powershell always shows ConsoleHost, go figure + cp.SendLine("exit") + cp.ExpectExitCode(0) +} + func TestShellIntegrationTestSuite(t *testing.T) { suite.Run(t, new(ShellIntegrationTestSuite)) } diff --git a/test/integration/shells_int_test.go b/test/integration/shells_int_test.go index fc6e61f95e..45ee8d0942 100644 --- a/test/integration/shells_int_test.go +++ b/test/integration/shells_int_test.go @@ -6,9 +6,12 @@ import ( "runtime" "testing" + "github.com/ActiveState/cli/internal/config" + "github.com/ActiveState/cli/internal/constants" + "github.com/ActiveState/cli/internal/rtutils/singlethread" + "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/testhelpers/suite" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" @@ -35,10 +38,7 @@ func (suite *ShellsIntegrationTestSuite) TestShells() { } // Checkout the first instance. It doesn't matter which shell is used. - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/small-python"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/small-python") cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) @@ -51,8 +51,17 @@ func (suite *ShellsIntegrationTestSuite) TestShells() { suite.Require().NoError(err) } + // Clear configured shell. + cfg, err := config.NewCustom(ts.Dirs.Config, singlethread.New(), true) + suite.Require().NoError(err) + err = cfg.Set(subshell.ConfigKeyShell, "") + suite.Require().NoError(err) + // Run the checkout in a particular shell. - cp = ts.SpawnShellWithOpts(shell) + cp = ts.SpawnShellWithOpts( + shell, + e2e.OptAppendEnv(constants.OverrideShellEnvVarName+"="), + ) cp.SendLine(e2e.QuoteCommand(shell, ts.ExecutablePath(), "checkout", "ActiveState-CLI/small-python", string(shell))) cp.Expect("Checked out project") cp.SendLine("exit") @@ -62,7 +71,10 @@ func (suite *ShellsIntegrationTestSuite) TestShells() { // There are 2 or more instances checked out, so we should get a prompt in whichever shell we // use. - cp = ts.SpawnShellWithOpts(shell, e2e.OptAppendEnv(constants.DisableRuntime+"=false")) + cp = ts.SpawnShellWithOpts( + shell, + e2e.OptAppendEnv(constants.OverrideShellEnvVarName+"="), + ) cp.SendLine(e2e.QuoteCommand(shell, ts.ExecutablePath(), "shell", "small-python")) cp.Expect("Multiple project paths") @@ -70,12 +82,6 @@ func (suite *ShellsIntegrationTestSuite) TestShells() { cp.SendEnter() cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - // Verify that the command prompt contains the right info, except for tcsh, whose prompt does - // not behave like other shells'. - if shell != e2e.Tcsh { - cp.Expect("[ActiveState-CLI/small-python]") - } - // Verify the runtime is functioning properly. cp.SendLine("python3 --version") cp.Expect("Python 3.10") diff --git a/test/integration/show_int_test.go b/test/integration/show_int_test.go index 38ae0c5ada..5b9e045d37 100644 --- a/test/integration/show_int_test.go +++ b/test/integration/show_int_test.go @@ -24,13 +24,7 @@ func (suite *ShowIntegrationTestSuite) TestShow() { suite.PrepareProject(ts) - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.ExpectInput(e2e.RuntimeSourcingTimeoutOpt) - - cp = ts.Spawn("show") + cp := ts.Spawn("show") cp.Expect(`Name`) cp.Expect(`Show`) cp.Expect(`Organization`) @@ -65,7 +59,7 @@ func (suite *ShowIntegrationTestSuite) TestShowWithoutBranch() { ts.PrepareProject("cli-integration-tests/Show", "e8f3b07b-502f-4763-83c1-763b9b952e18") - cp := ts.SpawnWithOpts(e2e.OptArgs("show")) + cp := ts.Spawn("show") cp.ExpectExitCode(0) contents, err := fileutils.ReadFile(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)) @@ -105,12 +99,9 @@ func (suite *ShowIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + suite.PrepareProject(ts) - cp = ts.Spawn("show", "-o", "json") + cp := ts.Spawn("show", "-o", "json") cp.Expect(`"project_url":`) cp.Expect(`"name":`) cp.Expect(`"platforms":`) diff --git a/test/integration/switch_int_test.go b/test/integration/switch_int_test.go index 66d8b5282f..20c3cd43e1 100644 --- a/test/integration/switch_int_test.go +++ b/test/integration/switch_int_test.go @@ -24,7 +24,7 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_Branch() { err := ts.ClearCache() suite.Require().NoError(err) - ts.PrepareProject("ActiveState-CLI/Branches", "b5b327f8-468e-4999-a23e-8bee886e6b6d") + ts.PrepareEmptyProject() pjfilepath := filepath.Join(ts.Dirs.Work, constants.ConfigFileName) pj, err := project.FromPath(pjfilepath) @@ -33,9 +33,9 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_Branch() { mainBranchCommitID := ts.CommitID() suite.Require().NoError(err) - cp := ts.SpawnWithOpts(e2e.OptArgs("switch", "secondbranch")) + cp := ts.Spawn("switch", "mingw") cp.Expect("Operating on project") - cp.Expect("ActiveState-CLI/Branches") + cp.Expect("ActiveState-CLI/Empty") cp.Expect("Successfully switched to branch:") if runtime.GOOS != "windows" { cp.ExpectExitCode(0) @@ -46,7 +46,7 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_Branch() { suite.Require().NoError(err) suite.Require().NoError(err) suite.NotEqual(mainBranchCommitID, ts.CommitID(), "commitID was not updated after switching branches", pj.Dir()) - suite.Equal("secondbranch", pj.BranchName(), "branch was not updated after switching branches") + suite.Equal("mingw", pj.BranchName(), "branch was not updated after switching branches") } func (suite *SwitchIntegrationTestSuite) TestSwitch_CommitID() { @@ -57,7 +57,7 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_CommitID() { err := ts.ClearCache() suite.Require().NoError(err) - ts.PrepareProject("ActiveState-CLI/History", "b5b327f8-468e-4999-a23e-8bee886e6b6d") + ts.PrepareEmptyProject() pjfilepath := filepath.Join(ts.Dirs.Work, constants.ConfigFileName) pj, err := project.FromPath(pjfilepath) @@ -65,7 +65,7 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_CommitID() { suite.Require().Equal("main", pj.BranchName(), "branch was not set to 'main' after pull") originalCommitID := ts.CommitID() - cp := ts.SpawnWithOpts(e2e.OptArgs("switch", "efce7c7a-c61a-4b04-bb00-f8e7edfd247f")) + cp := ts.SpawnWithOpts(e2e.OptArgs("switch", "265f9914-ad4d-4e0a-a128-9d4e8c5db820")) cp.Expect("Successfully switched to commit:") if runtime.GOOS != "windows" { cp.ExpectExitCode(0) @@ -85,7 +85,7 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_CommitID_NotInHistory() { err := ts.ClearCache() suite.Require().NoError(err) - ts.PrepareProject("ActiveState-CLI/History", "b5b327f8-468e-4999-a23e-8bee886e6b6d") + ts.PrepareEmptyProject() pjfilepath := filepath.Join(ts.Dirs.Work, constants.ConfigFileName) pj, err := project.FromPath(pjfilepath) @@ -93,7 +93,7 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_CommitID_NotInHistory() { suite.Require().Equal("main", pj.BranchName(), "branch was not set to 'main' after pull") originalCommitID := ts.CommitID() - cp := ts.SpawnWithOpts(e2e.OptArgs("switch", "76dff77a-66b9-43e3-90be-dc75917dd661")) + cp := ts.Spawn("switch", "76dff77a-66b9-43e3-90be-dc75917dd661") cp.Expect("Commit does not belong") if runtime.GOOS != "windows" { cp.ExpectExitCode(1) @@ -111,15 +111,12 @@ func (suite *SwitchIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Branches", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() - cp = ts.Spawn("switch", "firstbranch", "--output", "json") + cp := ts.Spawn("switch", "mingw", "--output", "json") cp.Expect(`"branch":`) cp.ExpectExitCode(0) - // AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice + AssertValidJSON(suite.T(), cp) } func TestSwitchIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/testdata/checkout-from-archive/darwin/4cfa45d0-ec48-524f-9f46-90c60bfb51ac.tar.gz b/test/integration/testdata/checkout-from-archive/darwin/4cfa45d0-ec48-524f-9f46-90c60bfb51ac.tar.gz new file mode 100644 index 0000000000..ab9e4aa458 Binary files /dev/null and b/test/integration/testdata/checkout-from-archive/darwin/4cfa45d0-ec48-524f-9f46-90c60bfb51ac.tar.gz differ diff --git a/test/integration/testdata/checkout-from-archive/darwin/bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120.tar.gz b/test/integration/testdata/checkout-from-archive/darwin/bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120.tar.gz new file mode 100644 index 0000000000..ab9e4aa458 Binary files /dev/null and b/test/integration/testdata/checkout-from-archive/darwin/bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120.tar.gz differ diff --git a/test/integration/testdata/checkout-from-archive/darwin/buildexpression.json b/test/integration/testdata/checkout-from-archive/darwin/buildexpression.json new file mode 100644 index 0000000000..09b5f39d66 --- /dev/null +++ b/test/integration/testdata/checkout-from-archive/darwin/buildexpression.json @@ -0,0 +1,36 @@ +{ + "let": { + "in": "$runtime", + "runtime": { + "state_tool_artifacts_v1": { + "build_flags": [], + "src": "$sources" + } + }, + "sources": { + "solve": { + "at_time": "$at_time", + "platforms": [ + "46a5b48f-226a-4696-9746-ba4d50d661c2", + "78977bc8-0f32-519d-80f3-9043f059398c", + "7c998ec2-7491-4e75-be4d-8885800ef5f2" + ], + "requirements": [ + { + "name": "alternative-build-selector", + "namespace": "internal" + }, + { + "name": "mingw-build-selector", + "namespace": "internal" + }, + { + "name": "provides_hello", + "namespace": "private/ActiveState-CLI" + } + ], + "solver_version": null + } + } + } +} diff --git a/test/integration/testdata/checkout-from-archive/darwin/buildplan.json b/test/integration/testdata/checkout-from-archive/darwin/buildplan.json new file mode 100644 index 0000000000..e3623722a1 --- /dev/null +++ b/test/integration/testdata/checkout-from-archive/darwin/buildplan.json @@ -0,0 +1,515 @@ +{ + "__typename": "BuildCompleted", + "buildPlanID": "", + "status": "COMPLETED", + "terminals": [ + { + "tag": "platform:46a5b48f-226a-4696-9746-ba4d50d661c2", + "nodeIds": [ + "4cfa45d0-ec48-524f-9f46-90c60bfb51ac", + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "b6588d63-067d-501e-84d4-d9a7881c1119", + "bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120", + "dc78166b-9088-5f4b-9ea2-637feba4f51b" + ] + }, + { + "tag": "platform:78977bc8-0f32-519d-80f3-9043f059398c", + "nodeIds": [ + "242604ea-36aa-5ec4-a0c3-ee160b443ed8", + "24a59f2c-c3ec-5586-b389-07149b46ac90", + "2a2631ef-bcc2-5241-87e0-cbf9ee489bb9", + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + }, + { + "tag": "platform:7c998ec2-7491-4e75-be4d-8885800ef5f2", + "nodeIds": [ + "59ea89fb-1b02-5798-b925-00b6a6297fa7", + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "96e76974-81c5-5816-bff0-bd91840cf89c", + "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "b6588d63-067d-501e-84d4-d9a7881c1119", + "cd77e611-f70b-5aea-a2bb-35a2a21a612f" + ] + } + ], + "artifacts": [ + { + "__typename": "ArtifactSucceeded", + "nodeId": "09386295-a8d0-5f5f-a5dc-b22598b3b4c9", + "displayName": "noop-builder", + "mimeType": "application/x-activestate-builder", + "generatedBy": "e4921b27-35eb-5415-87d3-95fd3d5728e5", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"s3://platform-sources/builder/65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077/noop-builder.tar.gz", + "logURL": "", + "errors": null, + "checksum": "65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "242604ea-36aa-5ec4-a0c3-ee160b443ed8", + "displayName": "alternative-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "0b2a2ff3-2188-54c7-8447-99241326850c", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/242604ea-36aa-5ec4-a0c3-ee160b443ed8/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/242604ea-36aa-5ec4-a0c3-ee160b443ed8/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "24a59f2c-c3ec-5586-b389-07149b46ac90", + "displayName": "provides_hello.application/octet-stream", + "mimeType": "application/x.artifact", + "generatedBy": "9ec50008-ec06-5950-9212-42f187e5985f", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/24a59f2c-c3ec-5586-b389-07149b46ac90/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/24a59f2c-c3ec-5586-b389-07149b46ac90/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "2a2631ef-bcc2-5241-87e0-cbf9ee489bb9", + "displayName": "mingw-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "870f367a-c9f8-5096-9bc3-e0263bf7ca16", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/2a2631ef-bcc2-5241-87e0-cbf9ee489bb9/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/2a2631ef-bcc2-5241-87e0-cbf9ee489bb9/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "4cfa45d0-ec48-524f-9f46-90c60bfb51ac", + "displayName": "mingw-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "7b9048bb-0f78-5b33-bd9d-ebddb96c6ebb", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/4cfa45d0-ec48-524f-9f46-90c60bfb51ac/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/4cfa45d0-ec48-524f-9f46-90c60bfb51ac/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "59ea89fb-1b02-5798-b925-00b6a6297fa7", + "displayName": "provides_hello.application/octet-stream", + "mimeType": "application/x.artifact", + "generatedBy": "29ab23f6-8da0-5940-94f0-3b80b44959ec", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/59ea89fb-1b02-5798-b925-00b6a6297fa7/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/59ea89fb-1b02-5798-b925-00b6a6297fa7/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "96e76974-81c5-5816-bff0-bd91840cf89c", + "displayName": "alternative-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "e116aa52-e773-51cf-9b00-a5d8f5983663", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/96e76974-81c5-5816-bff0-bd91840cf89c/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/96e76974-81c5-5816-bff0-bd91840cf89c/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120", + "displayName": "provides_hello.application/octet-stream", + "mimeType": "application/x.artifact", + "generatedBy": "baf760f5-8ba1-5fba-9514-9e451389b021", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "cd77e611-f70b-5aea-a2bb-35a2a21a612f", + "displayName": "mingw-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "673345fb-f606-52eb-bc84-f5a88e448f18", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/cd77e611-f70b-5aea-a2bb-35a2a21a612f/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/cd77e611-f70b-5aea-a2bb-35a2a21a612f/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "dc78166b-9088-5f4b-9ea2-637feba4f51b", + "displayName": "alternative-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "3591500a-67a2-5492-8a16-de272287f804", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/dc78166b-9088-5f4b-9ea2-637feba4f51b/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/dc78166b-9088-5f4b-9ea2-637feba4f51b/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + } + ], + "steps": [ + { + "stepId": "0b2a2ff3-2188-54c7-8447-99241326850c", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "a0018800-f1fb-53dd-8e10-049ba0b9245b" + ] + } + ], + "outputs": [ + "242604ea-36aa-5ec4-a0c3-ee160b443ed8" + ] + }, + { + "stepId": "29ab23f6-8da0-5940-94f0-3b80b44959ec", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + ] + } + ], + "outputs": [ + "59ea89fb-1b02-5798-b925-00b6a6297fa7" + ] + }, + { + "stepId": "3591500a-67a2-5492-8a16-de272287f804", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "a0018800-f1fb-53dd-8e10-049ba0b9245b" + ] + } + ], + "outputs": [ + "dc78166b-9088-5f4b-9ea2-637feba4f51b" + ] + }, + { + "stepId": "673345fb-f606-52eb-bc84-f5a88e448f18", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + } + ], + "outputs": [ + "cd77e611-f70b-5aea-a2bb-35a2a21a612f" + ] + }, + { + "stepId": "7b9048bb-0f78-5b33-bd9d-ebddb96c6ebb", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + } + ], + "outputs": [ + "4cfa45d0-ec48-524f-9f46-90c60bfb51ac" + ] + }, + { + "stepId": "870f367a-c9f8-5096-9bc3-e0263bf7ca16", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + } + ], + "outputs": [ + "2a2631ef-bcc2-5241-87e0-cbf9ee489bb9" + ] + }, + { + "stepId": "9ec50008-ec06-5950-9212-42f187e5985f", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + ] + } + ], + "outputs": [ + "24a59f2c-c3ec-5586-b389-07149b46ac90" + ] + }, + { + "stepId": "baf760f5-8ba1-5fba-9514-9e451389b021", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + ] + } + ], + "outputs": [ + "bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120" + ] + }, + { + "stepId": "e116aa52-e773-51cf-9b00-a5d8f5983663", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "a0018800-f1fb-53dd-8e10-049ba0b9245b" + ] + } + ], + "outputs": [ + "96e76974-81c5-5816-bff0-bd91840cf89c" + ] + } + ], + "sources": [ + { + "nodeId": "0ad51906-049e-554f-be54-0b7d42c12bde", + "ingredientId": "00000000-0000-1000-8000-000000000000", + "ingredientVersionId": "00000000-0000-1000-8000-000000000000", + "revision": 21, + "name": "docker-registry.activestate.build/activestate/windows-mingw-builder", + "namespace": "image", + "version": "sha256:53b503ff3df26cfa40b562fc9c0b01423aa3480599bd16b235bb8093a56ee15c", + "licenses": [] + }, + { + "nodeId": "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "ingredientId": "af6d212c-71a1-5c3c-a335-75a7b22049b6", + "ingredientVersionId": "dbb62101-51ea-5f8d-ac4e-518026b2859f", + "revision": 1, + "name": "provides_hello", + "namespace": "private/ActiveState-CLI", + "version": "0.0.1", + "licenses": [ + "", + "" + ] + }, + { + "nodeId": "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "ingredientId": "99be954b-95b1-53a3-9b6d-eb0c2d75afc1", + "ingredientVersionId": "4442f8b7-8059-5d99-831b-5ae6d866ec97", + "revision": 2, + "name": "alternative-build-selector", + "namespace": "internal", + "version": "10.0.0", + "licenses": [] + }, + { + "nodeId": "b6588d63-067d-501e-84d4-d9a7881c1119", + "ingredientId": "dc83d7cd-50b3-5b7a-ace6-79a9aeba7254", + "ingredientVersionId": "9a824a18-3eff-5ba3-b71c-bfb950fca206", + "revision": 1, + "name": "mingw-build-selector", + "namespace": "internal", + "version": "11.0.0", + "licenses": [] + }, + { + "nodeId": "d4fdf221-c145-525c-9f98-93789680b138", + "ingredientId": "00000000-0000-1000-8000-000000000000", + "ingredientVersionId": "00000000-0000-1000-8000-000000000000", + "revision": 4, + "name": "monterey.12.4.x86_64-64gb-with-brew", + "namespace": "image", + "version": "a5b5ff1f9c614d584a99a0da918f52a459a088e043b2fb74f26bd48380b68c40", + "licenses": [] + }, + { + "nodeId": "e311344d-208f-5d1d-a744-32a2a82dbf12", + "ingredientId": "00000000-0000-1000-8000-000000000000", + "ingredientVersionId": "00000000-0000-1000-8000-000000000000", + "revision": 21, + "name": "docker-registry.activestate.build/activestate/centos-8-builder", + "namespace": "image", + "version": "sha256:6b227ed35fe1216bac0df1ea503a32bb27d7459f4a07d4d3a705405bfecdf665", + "licenses": [] + }, + { + "nodeId": "e4921b27-35eb-5415-87d3-95fd3d5728e5", + "ingredientId": "888f7a88-fdc8-58f7-8e34-1e28425f3c5a", + "ingredientVersionId": "fcfb451f-d86d-5977-ae48-f27610f7d5ab", + "revision": 3, + "name": "noop-builder", + "namespace": "builder", + "version": "1.0.0", + "licenses": [ + "(MIT-1.0)" + ] + } + ], + "buildLogIds": [ + { + "id": "5839ede4-a43e-54f7-84f9-6af8884e7f47", + "platformID": "" + } + ], + "resolvedRequirements": [ + { + "requirement": { + "name": "provides_hello", + "namespace": "private/ActiveState-CLI" + }, + "resolvedSource": "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + }, + { + "requirement": { + "name": "alternative-build-selector", + "namespace": "internal" + }, + "resolvedSource": "a0018800-f1fb-53dd-8e10-049ba0b9245b" + }, + { + "requirement": { + "name": "mingw-build-selector", + "namespace": "internal" + }, + "resolvedSource": "b6588d63-067d-501e-84d4-d9a7881c1119" + } + ] +} diff --git a/test/integration/testdata/checkout-from-archive/darwin/dc78166b-9088-5f4b-9ea2-637feba4f51b.tar.gz b/test/integration/testdata/checkout-from-archive/darwin/dc78166b-9088-5f4b-9ea2-637feba4f51b.tar.gz new file mode 100644 index 0000000000..ab9e4aa458 Binary files /dev/null and b/test/integration/testdata/checkout-from-archive/darwin/dc78166b-9088-5f4b-9ea2-637feba4f51b.tar.gz differ diff --git a/test/integration/testdata/checkout-from-archive/darwin/installer_config.json b/test/integration/testdata/checkout-from-archive/darwin/installer_config.json new file mode 100644 index 0000000000..558efceb6f --- /dev/null +++ b/test/integration/testdata/checkout-from-archive/darwin/installer_config.json @@ -0,0 +1,7 @@ +{ + "org_name": "ActiveState-CLI", + "project_name": "AlmostEmpty", + "commit_id": "6cd1cc1f-3886-439b-8373-c24ca06ab150", + "branch": "main", + "platform_id": "46a5b48f-226a-4696-9746-ba4d50d661c2" +} diff --git a/test/integration/testdata/checkout-from-archive/linux/59ea89fb-1b02-5798-b925-00b6a6297fa7.tar.gz b/test/integration/testdata/checkout-from-archive/linux/59ea89fb-1b02-5798-b925-00b6a6297fa7.tar.gz new file mode 100644 index 0000000000..ab9e4aa458 Binary files /dev/null and b/test/integration/testdata/checkout-from-archive/linux/59ea89fb-1b02-5798-b925-00b6a6297fa7.tar.gz differ diff --git a/test/integration/testdata/checkout-from-archive/linux/96e76974-81c5-5816-bff0-bd91840cf89c.tar.gz b/test/integration/testdata/checkout-from-archive/linux/96e76974-81c5-5816-bff0-bd91840cf89c.tar.gz new file mode 100644 index 0000000000..ab9e4aa458 Binary files /dev/null and b/test/integration/testdata/checkout-from-archive/linux/96e76974-81c5-5816-bff0-bd91840cf89c.tar.gz differ diff --git a/test/integration/testdata/checkout-from-archive/linux/buildexpression.json b/test/integration/testdata/checkout-from-archive/linux/buildexpression.json new file mode 100644 index 0000000000..09b5f39d66 --- /dev/null +++ b/test/integration/testdata/checkout-from-archive/linux/buildexpression.json @@ -0,0 +1,36 @@ +{ + "let": { + "in": "$runtime", + "runtime": { + "state_tool_artifacts_v1": { + "build_flags": [], + "src": "$sources" + } + }, + "sources": { + "solve": { + "at_time": "$at_time", + "platforms": [ + "46a5b48f-226a-4696-9746-ba4d50d661c2", + "78977bc8-0f32-519d-80f3-9043f059398c", + "7c998ec2-7491-4e75-be4d-8885800ef5f2" + ], + "requirements": [ + { + "name": "alternative-build-selector", + "namespace": "internal" + }, + { + "name": "mingw-build-selector", + "namespace": "internal" + }, + { + "name": "provides_hello", + "namespace": "private/ActiveState-CLI" + } + ], + "solver_version": null + } + } + } +} diff --git a/test/integration/testdata/checkout-from-archive/linux/buildplan.json b/test/integration/testdata/checkout-from-archive/linux/buildplan.json new file mode 100644 index 0000000000..e3623722a1 --- /dev/null +++ b/test/integration/testdata/checkout-from-archive/linux/buildplan.json @@ -0,0 +1,515 @@ +{ + "__typename": "BuildCompleted", + "buildPlanID": "", + "status": "COMPLETED", + "terminals": [ + { + "tag": "platform:46a5b48f-226a-4696-9746-ba4d50d661c2", + "nodeIds": [ + "4cfa45d0-ec48-524f-9f46-90c60bfb51ac", + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "b6588d63-067d-501e-84d4-d9a7881c1119", + "bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120", + "dc78166b-9088-5f4b-9ea2-637feba4f51b" + ] + }, + { + "tag": "platform:78977bc8-0f32-519d-80f3-9043f059398c", + "nodeIds": [ + "242604ea-36aa-5ec4-a0c3-ee160b443ed8", + "24a59f2c-c3ec-5586-b389-07149b46ac90", + "2a2631ef-bcc2-5241-87e0-cbf9ee489bb9", + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + }, + { + "tag": "platform:7c998ec2-7491-4e75-be4d-8885800ef5f2", + "nodeIds": [ + "59ea89fb-1b02-5798-b925-00b6a6297fa7", + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "96e76974-81c5-5816-bff0-bd91840cf89c", + "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "b6588d63-067d-501e-84d4-d9a7881c1119", + "cd77e611-f70b-5aea-a2bb-35a2a21a612f" + ] + } + ], + "artifacts": [ + { + "__typename": "ArtifactSucceeded", + "nodeId": "09386295-a8d0-5f5f-a5dc-b22598b3b4c9", + "displayName": "noop-builder", + "mimeType": "application/x-activestate-builder", + "generatedBy": "e4921b27-35eb-5415-87d3-95fd3d5728e5", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"s3://platform-sources/builder/65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077/noop-builder.tar.gz", + "logURL": "", + "errors": null, + "checksum": "65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "242604ea-36aa-5ec4-a0c3-ee160b443ed8", + "displayName": "alternative-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "0b2a2ff3-2188-54c7-8447-99241326850c", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/242604ea-36aa-5ec4-a0c3-ee160b443ed8/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/242604ea-36aa-5ec4-a0c3-ee160b443ed8/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "24a59f2c-c3ec-5586-b389-07149b46ac90", + "displayName": "provides_hello.application/octet-stream", + "mimeType": "application/x.artifact", + "generatedBy": "9ec50008-ec06-5950-9212-42f187e5985f", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/24a59f2c-c3ec-5586-b389-07149b46ac90/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/24a59f2c-c3ec-5586-b389-07149b46ac90/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "2a2631ef-bcc2-5241-87e0-cbf9ee489bb9", + "displayName": "mingw-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "870f367a-c9f8-5096-9bc3-e0263bf7ca16", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/2a2631ef-bcc2-5241-87e0-cbf9ee489bb9/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/2a2631ef-bcc2-5241-87e0-cbf9ee489bb9/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "4cfa45d0-ec48-524f-9f46-90c60bfb51ac", + "displayName": "mingw-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "7b9048bb-0f78-5b33-bd9d-ebddb96c6ebb", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/4cfa45d0-ec48-524f-9f46-90c60bfb51ac/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/4cfa45d0-ec48-524f-9f46-90c60bfb51ac/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "59ea89fb-1b02-5798-b925-00b6a6297fa7", + "displayName": "provides_hello.application/octet-stream", + "mimeType": "application/x.artifact", + "generatedBy": "29ab23f6-8da0-5940-94f0-3b80b44959ec", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/59ea89fb-1b02-5798-b925-00b6a6297fa7/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/59ea89fb-1b02-5798-b925-00b6a6297fa7/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "96e76974-81c5-5816-bff0-bd91840cf89c", + "displayName": "alternative-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "e116aa52-e773-51cf-9b00-a5d8f5983663", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/96e76974-81c5-5816-bff0-bd91840cf89c/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/96e76974-81c5-5816-bff0-bd91840cf89c/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120", + "displayName": "provides_hello.application/octet-stream", + "mimeType": "application/x.artifact", + "generatedBy": "baf760f5-8ba1-5fba-9514-9e451389b021", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "cd77e611-f70b-5aea-a2bb-35a2a21a612f", + "displayName": "mingw-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "673345fb-f606-52eb-bc84-f5a88e448f18", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/cd77e611-f70b-5aea-a2bb-35a2a21a612f/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/cd77e611-f70b-5aea-a2bb-35a2a21a612f/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "dc78166b-9088-5f4b-9ea2-637feba4f51b", + "displayName": "alternative-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "3591500a-67a2-5492-8a16-de272287f804", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/dc78166b-9088-5f4b-9ea2-637feba4f51b/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/dc78166b-9088-5f4b-9ea2-637feba4f51b/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + } + ], + "steps": [ + { + "stepId": "0b2a2ff3-2188-54c7-8447-99241326850c", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "a0018800-f1fb-53dd-8e10-049ba0b9245b" + ] + } + ], + "outputs": [ + "242604ea-36aa-5ec4-a0c3-ee160b443ed8" + ] + }, + { + "stepId": "29ab23f6-8da0-5940-94f0-3b80b44959ec", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + ] + } + ], + "outputs": [ + "59ea89fb-1b02-5798-b925-00b6a6297fa7" + ] + }, + { + "stepId": "3591500a-67a2-5492-8a16-de272287f804", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "a0018800-f1fb-53dd-8e10-049ba0b9245b" + ] + } + ], + "outputs": [ + "dc78166b-9088-5f4b-9ea2-637feba4f51b" + ] + }, + { + "stepId": "673345fb-f606-52eb-bc84-f5a88e448f18", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + } + ], + "outputs": [ + "cd77e611-f70b-5aea-a2bb-35a2a21a612f" + ] + }, + { + "stepId": "7b9048bb-0f78-5b33-bd9d-ebddb96c6ebb", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + } + ], + "outputs": [ + "4cfa45d0-ec48-524f-9f46-90c60bfb51ac" + ] + }, + { + "stepId": "870f367a-c9f8-5096-9bc3-e0263bf7ca16", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + } + ], + "outputs": [ + "2a2631ef-bcc2-5241-87e0-cbf9ee489bb9" + ] + }, + { + "stepId": "9ec50008-ec06-5950-9212-42f187e5985f", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + ] + } + ], + "outputs": [ + "24a59f2c-c3ec-5586-b389-07149b46ac90" + ] + }, + { + "stepId": "baf760f5-8ba1-5fba-9514-9e451389b021", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + ] + } + ], + "outputs": [ + "bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120" + ] + }, + { + "stepId": "e116aa52-e773-51cf-9b00-a5d8f5983663", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "a0018800-f1fb-53dd-8e10-049ba0b9245b" + ] + } + ], + "outputs": [ + "96e76974-81c5-5816-bff0-bd91840cf89c" + ] + } + ], + "sources": [ + { + "nodeId": "0ad51906-049e-554f-be54-0b7d42c12bde", + "ingredientId": "00000000-0000-1000-8000-000000000000", + "ingredientVersionId": "00000000-0000-1000-8000-000000000000", + "revision": 21, + "name": "docker-registry.activestate.build/activestate/windows-mingw-builder", + "namespace": "image", + "version": "sha256:53b503ff3df26cfa40b562fc9c0b01423aa3480599bd16b235bb8093a56ee15c", + "licenses": [] + }, + { + "nodeId": "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "ingredientId": "af6d212c-71a1-5c3c-a335-75a7b22049b6", + "ingredientVersionId": "dbb62101-51ea-5f8d-ac4e-518026b2859f", + "revision": 1, + "name": "provides_hello", + "namespace": "private/ActiveState-CLI", + "version": "0.0.1", + "licenses": [ + "", + "" + ] + }, + { + "nodeId": "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "ingredientId": "99be954b-95b1-53a3-9b6d-eb0c2d75afc1", + "ingredientVersionId": "4442f8b7-8059-5d99-831b-5ae6d866ec97", + "revision": 2, + "name": "alternative-build-selector", + "namespace": "internal", + "version": "10.0.0", + "licenses": [] + }, + { + "nodeId": "b6588d63-067d-501e-84d4-d9a7881c1119", + "ingredientId": "dc83d7cd-50b3-5b7a-ace6-79a9aeba7254", + "ingredientVersionId": "9a824a18-3eff-5ba3-b71c-bfb950fca206", + "revision": 1, + "name": "mingw-build-selector", + "namespace": "internal", + "version": "11.0.0", + "licenses": [] + }, + { + "nodeId": "d4fdf221-c145-525c-9f98-93789680b138", + "ingredientId": "00000000-0000-1000-8000-000000000000", + "ingredientVersionId": "00000000-0000-1000-8000-000000000000", + "revision": 4, + "name": "monterey.12.4.x86_64-64gb-with-brew", + "namespace": "image", + "version": "a5b5ff1f9c614d584a99a0da918f52a459a088e043b2fb74f26bd48380b68c40", + "licenses": [] + }, + { + "nodeId": "e311344d-208f-5d1d-a744-32a2a82dbf12", + "ingredientId": "00000000-0000-1000-8000-000000000000", + "ingredientVersionId": "00000000-0000-1000-8000-000000000000", + "revision": 21, + "name": "docker-registry.activestate.build/activestate/centos-8-builder", + "namespace": "image", + "version": "sha256:6b227ed35fe1216bac0df1ea503a32bb27d7459f4a07d4d3a705405bfecdf665", + "licenses": [] + }, + { + "nodeId": "e4921b27-35eb-5415-87d3-95fd3d5728e5", + "ingredientId": "888f7a88-fdc8-58f7-8e34-1e28425f3c5a", + "ingredientVersionId": "fcfb451f-d86d-5977-ae48-f27610f7d5ab", + "revision": 3, + "name": "noop-builder", + "namespace": "builder", + "version": "1.0.0", + "licenses": [ + "(MIT-1.0)" + ] + } + ], + "buildLogIds": [ + { + "id": "5839ede4-a43e-54f7-84f9-6af8884e7f47", + "platformID": "" + } + ], + "resolvedRequirements": [ + { + "requirement": { + "name": "provides_hello", + "namespace": "private/ActiveState-CLI" + }, + "resolvedSource": "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + }, + { + "requirement": { + "name": "alternative-build-selector", + "namespace": "internal" + }, + "resolvedSource": "a0018800-f1fb-53dd-8e10-049ba0b9245b" + }, + { + "requirement": { + "name": "mingw-build-selector", + "namespace": "internal" + }, + "resolvedSource": "b6588d63-067d-501e-84d4-d9a7881c1119" + } + ] +} diff --git a/test/integration/testdata/checkout-from-archive/linux/cd77e611-f70b-5aea-a2bb-35a2a21a612f.tar.gz b/test/integration/testdata/checkout-from-archive/linux/cd77e611-f70b-5aea-a2bb-35a2a21a612f.tar.gz new file mode 100644 index 0000000000..ab9e4aa458 Binary files /dev/null and b/test/integration/testdata/checkout-from-archive/linux/cd77e611-f70b-5aea-a2bb-35a2a21a612f.tar.gz differ diff --git a/test/integration/testdata/checkout-from-archive/linux/installer_config.json b/test/integration/testdata/checkout-from-archive/linux/installer_config.json new file mode 100644 index 0000000000..4ce83f80fb --- /dev/null +++ b/test/integration/testdata/checkout-from-archive/linux/installer_config.json @@ -0,0 +1,7 @@ +{ + "org_name": "ActiveState-CLI", + "project_name": "AlmostEmpty", + "commit_id": "6cd1cc1f-3886-439b-8373-c24ca06ab150", + "branch": "main", + "platform_id": "7c998ec2-7491-4e75-be4d-8885800ef5f2" +} \ No newline at end of file diff --git a/test/integration/testdata/checkout-from-archive/windows/242604ea-36aa-5ec4-a0c3-ee160b443ed8.tar.gz b/test/integration/testdata/checkout-from-archive/windows/242604ea-36aa-5ec4-a0c3-ee160b443ed8.tar.gz new file mode 100644 index 0000000000..ab9e4aa458 Binary files /dev/null and b/test/integration/testdata/checkout-from-archive/windows/242604ea-36aa-5ec4-a0c3-ee160b443ed8.tar.gz differ diff --git a/test/integration/testdata/checkout-from-archive/windows/24a59f2c-c3ec-5586-b389-07149b46ac90.tar.gz b/test/integration/testdata/checkout-from-archive/windows/24a59f2c-c3ec-5586-b389-07149b46ac90.tar.gz new file mode 100644 index 0000000000..ab9e4aa458 Binary files /dev/null and b/test/integration/testdata/checkout-from-archive/windows/24a59f2c-c3ec-5586-b389-07149b46ac90.tar.gz differ diff --git a/test/integration/testdata/checkout-from-archive/windows/2a2631ef-bcc2-5241-87e0-cbf9ee489bb9.tar.gz b/test/integration/testdata/checkout-from-archive/windows/2a2631ef-bcc2-5241-87e0-cbf9ee489bb9.tar.gz new file mode 100644 index 0000000000..ab9e4aa458 Binary files /dev/null and b/test/integration/testdata/checkout-from-archive/windows/2a2631ef-bcc2-5241-87e0-cbf9ee489bb9.tar.gz differ diff --git a/test/integration/testdata/checkout-from-archive/windows/buildexpression.json b/test/integration/testdata/checkout-from-archive/windows/buildexpression.json new file mode 100644 index 0000000000..09b5f39d66 --- /dev/null +++ b/test/integration/testdata/checkout-from-archive/windows/buildexpression.json @@ -0,0 +1,36 @@ +{ + "let": { + "in": "$runtime", + "runtime": { + "state_tool_artifacts_v1": { + "build_flags": [], + "src": "$sources" + } + }, + "sources": { + "solve": { + "at_time": "$at_time", + "platforms": [ + "46a5b48f-226a-4696-9746-ba4d50d661c2", + "78977bc8-0f32-519d-80f3-9043f059398c", + "7c998ec2-7491-4e75-be4d-8885800ef5f2" + ], + "requirements": [ + { + "name": "alternative-build-selector", + "namespace": "internal" + }, + { + "name": "mingw-build-selector", + "namespace": "internal" + }, + { + "name": "provides_hello", + "namespace": "private/ActiveState-CLI" + } + ], + "solver_version": null + } + } + } +} diff --git a/test/integration/testdata/checkout-from-archive/windows/buildplan.json b/test/integration/testdata/checkout-from-archive/windows/buildplan.json new file mode 100644 index 0000000000..e3623722a1 --- /dev/null +++ b/test/integration/testdata/checkout-from-archive/windows/buildplan.json @@ -0,0 +1,515 @@ +{ + "__typename": "BuildCompleted", + "buildPlanID": "", + "status": "COMPLETED", + "terminals": [ + { + "tag": "platform:46a5b48f-226a-4696-9746-ba4d50d661c2", + "nodeIds": [ + "4cfa45d0-ec48-524f-9f46-90c60bfb51ac", + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "b6588d63-067d-501e-84d4-d9a7881c1119", + "bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120", + "dc78166b-9088-5f4b-9ea2-637feba4f51b" + ] + }, + { + "tag": "platform:78977bc8-0f32-519d-80f3-9043f059398c", + "nodeIds": [ + "242604ea-36aa-5ec4-a0c3-ee160b443ed8", + "24a59f2c-c3ec-5586-b389-07149b46ac90", + "2a2631ef-bcc2-5241-87e0-cbf9ee489bb9", + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + }, + { + "tag": "platform:7c998ec2-7491-4e75-be4d-8885800ef5f2", + "nodeIds": [ + "59ea89fb-1b02-5798-b925-00b6a6297fa7", + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "96e76974-81c5-5816-bff0-bd91840cf89c", + "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "b6588d63-067d-501e-84d4-d9a7881c1119", + "cd77e611-f70b-5aea-a2bb-35a2a21a612f" + ] + } + ], + "artifacts": [ + { + "__typename": "ArtifactSucceeded", + "nodeId": "09386295-a8d0-5f5f-a5dc-b22598b3b4c9", + "displayName": "noop-builder", + "mimeType": "application/x-activestate-builder", + "generatedBy": "e4921b27-35eb-5415-87d3-95fd3d5728e5", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"s3://platform-sources/builder/65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077/noop-builder.tar.gz", + "logURL": "", + "errors": null, + "checksum": "65710b34592066ff70669c67ea0031b138f4249c768c429b74f6f2efe781e077" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "242604ea-36aa-5ec4-a0c3-ee160b443ed8", + "displayName": "alternative-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "0b2a2ff3-2188-54c7-8447-99241326850c", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/242604ea-36aa-5ec4-a0c3-ee160b443ed8/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/242604ea-36aa-5ec4-a0c3-ee160b443ed8/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "24a59f2c-c3ec-5586-b389-07149b46ac90", + "displayName": "provides_hello.application/octet-stream", + "mimeType": "application/x.artifact", + "generatedBy": "9ec50008-ec06-5950-9212-42f187e5985f", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/24a59f2c-c3ec-5586-b389-07149b46ac90/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/24a59f2c-c3ec-5586-b389-07149b46ac90/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "2a2631ef-bcc2-5241-87e0-cbf9ee489bb9", + "displayName": "mingw-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "870f367a-c9f8-5096-9bc3-e0263bf7ca16", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/2a2631ef-bcc2-5241-87e0-cbf9ee489bb9/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/2a2631ef-bcc2-5241-87e0-cbf9ee489bb9/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "4cfa45d0-ec48-524f-9f46-90c60bfb51ac", + "displayName": "mingw-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "7b9048bb-0f78-5b33-bd9d-ebddb96c6ebb", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/4cfa45d0-ec48-524f-9f46-90c60bfb51ac/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/4cfa45d0-ec48-524f-9f46-90c60bfb51ac/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "59ea89fb-1b02-5798-b925-00b6a6297fa7", + "displayName": "provides_hello.application/octet-stream", + "mimeType": "application/x.artifact", + "generatedBy": "29ab23f6-8da0-5940-94f0-3b80b44959ec", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/59ea89fb-1b02-5798-b925-00b6a6297fa7/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/59ea89fb-1b02-5798-b925-00b6a6297fa7/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "96e76974-81c5-5816-bff0-bd91840cf89c", + "displayName": "alternative-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "e116aa52-e773-51cf-9b00-a5d8f5983663", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/96e76974-81c5-5816-bff0-bd91840cf89c/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/96e76974-81c5-5816-bff0-bd91840cf89c/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120", + "displayName": "provides_hello.application/octet-stream", + "mimeType": "application/x.artifact", + "generatedBy": "baf760f5-8ba1-5fba-9514-9e451389b021", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "cd77e611-f70b-5aea-a2bb-35a2a21a612f", + "displayName": "mingw-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "673345fb-f606-52eb-bc84-f5a88e448f18", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/cd77e611-f70b-5aea-a2bb-35a2a21a612f/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/cd77e611-f70b-5aea-a2bb-35a2a21a612f/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + }, + { + "__typename": "ArtifactSucceeded", + "nodeId": "dc78166b-9088-5f4b-9ea2-637feba4f51b", + "displayName": "alternative-build-selector.application/gzip", + "mimeType": "application/x.artifact", + "generatedBy": "3591500a-67a2-5492-8a16-de272287f804", + "runtimeDependencies": [], + "status": "SUCCEEDED", + "url": +"https://dl.activestate.com/artifact/dc78166b-9088-5f4b-9ea2-637feba4f51b/artifact.tar.gz", + "logURL": +"https://dl.activestate.com/organization/9cc783d1-c065-4aea-8a55-3b0dbc77078b/project/c2bd9427-f888-4d53-82df-14c0d612f3bd/commit/4f46dee3-1f8f-475d-af06-9554aed2903e/artifact/dc78166b-9088-5f4b-9ea2-637feba4f51b/logs.jsonl", + "errors": null, + "checksum": "bbcf5b36ff31084f24c3748020768173b17967abcd2437bb93638b9dd6110440" + } + ], + "steps": [ + { + "stepId": "0b2a2ff3-2188-54c7-8447-99241326850c", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "a0018800-f1fb-53dd-8e10-049ba0b9245b" + ] + } + ], + "outputs": [ + "242604ea-36aa-5ec4-a0c3-ee160b443ed8" + ] + }, + { + "stepId": "29ab23f6-8da0-5940-94f0-3b80b44959ec", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + ] + } + ], + "outputs": [ + "59ea89fb-1b02-5798-b925-00b6a6297fa7" + ] + }, + { + "stepId": "3591500a-67a2-5492-8a16-de272287f804", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "a0018800-f1fb-53dd-8e10-049ba0b9245b" + ] + } + ], + "outputs": [ + "dc78166b-9088-5f4b-9ea2-637feba4f51b" + ] + }, + { + "stepId": "673345fb-f606-52eb-bc84-f5a88e448f18", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + } + ], + "outputs": [ + "cd77e611-f70b-5aea-a2bb-35a2a21a612f" + ] + }, + { + "stepId": "7b9048bb-0f78-5b33-bd9d-ebddb96c6ebb", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + } + ], + "outputs": [ + "4cfa45d0-ec48-524f-9f46-90c60bfb51ac" + ] + }, + { + "stepId": "870f367a-c9f8-5096-9bc3-e0263bf7ca16", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "b6588d63-067d-501e-84d4-d9a7881c1119" + ] + } + ], + "outputs": [ + "2a2631ef-bcc2-5241-87e0-cbf9ee489bb9" + ] + }, + { + "stepId": "9ec50008-ec06-5950-9212-42f187e5985f", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + ] + } + ], + "outputs": [ + "24a59f2c-c3ec-5586-b389-07149b46ac90" + ] + }, + { + "stepId": "baf760f5-8ba1-5fba-9514-9e451389b021", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + ] + } + ], + "outputs": [ + "bd3cdcd1-7b6c-5e5e-b144-6fa17dc28120" + ] + }, + { + "stepId": "e116aa52-e773-51cf-9b00-a5d8f5983663", + "inputs": [ + { + "tag": "builder", + "nodeIds": [ + "09386295-a8d0-5f5f-a5dc-b22598b3b4c9" + ] + }, + { + "tag": "deps", + "nodeIds": [] + }, + { + "tag": "src", + "nodeIds": [ + "a0018800-f1fb-53dd-8e10-049ba0b9245b" + ] + } + ], + "outputs": [ + "96e76974-81c5-5816-bff0-bd91840cf89c" + ] + } + ], + "sources": [ + { + "nodeId": "0ad51906-049e-554f-be54-0b7d42c12bde", + "ingredientId": "00000000-0000-1000-8000-000000000000", + "ingredientVersionId": "00000000-0000-1000-8000-000000000000", + "revision": 21, + "name": "docker-registry.activestate.build/activestate/windows-mingw-builder", + "namespace": "image", + "version": "sha256:53b503ff3df26cfa40b562fc9c0b01423aa3480599bd16b235bb8093a56ee15c", + "licenses": [] + }, + { + "nodeId": "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7", + "ingredientId": "af6d212c-71a1-5c3c-a335-75a7b22049b6", + "ingredientVersionId": "dbb62101-51ea-5f8d-ac4e-518026b2859f", + "revision": 1, + "name": "provides_hello", + "namespace": "private/ActiveState-CLI", + "version": "0.0.1", + "licenses": [ + "", + "" + ] + }, + { + "nodeId": "a0018800-f1fb-53dd-8e10-049ba0b9245b", + "ingredientId": "99be954b-95b1-53a3-9b6d-eb0c2d75afc1", + "ingredientVersionId": "4442f8b7-8059-5d99-831b-5ae6d866ec97", + "revision": 2, + "name": "alternative-build-selector", + "namespace": "internal", + "version": "10.0.0", + "licenses": [] + }, + { + "nodeId": "b6588d63-067d-501e-84d4-d9a7881c1119", + "ingredientId": "dc83d7cd-50b3-5b7a-ace6-79a9aeba7254", + "ingredientVersionId": "9a824a18-3eff-5ba3-b71c-bfb950fca206", + "revision": 1, + "name": "mingw-build-selector", + "namespace": "internal", + "version": "11.0.0", + "licenses": [] + }, + { + "nodeId": "d4fdf221-c145-525c-9f98-93789680b138", + "ingredientId": "00000000-0000-1000-8000-000000000000", + "ingredientVersionId": "00000000-0000-1000-8000-000000000000", + "revision": 4, + "name": "monterey.12.4.x86_64-64gb-with-brew", + "namespace": "image", + "version": "a5b5ff1f9c614d584a99a0da918f52a459a088e043b2fb74f26bd48380b68c40", + "licenses": [] + }, + { + "nodeId": "e311344d-208f-5d1d-a744-32a2a82dbf12", + "ingredientId": "00000000-0000-1000-8000-000000000000", + "ingredientVersionId": "00000000-0000-1000-8000-000000000000", + "revision": 21, + "name": "docker-registry.activestate.build/activestate/centos-8-builder", + "namespace": "image", + "version": "sha256:6b227ed35fe1216bac0df1ea503a32bb27d7459f4a07d4d3a705405bfecdf665", + "licenses": [] + }, + { + "nodeId": "e4921b27-35eb-5415-87d3-95fd3d5728e5", + "ingredientId": "888f7a88-fdc8-58f7-8e34-1e28425f3c5a", + "ingredientVersionId": "fcfb451f-d86d-5977-ae48-f27610f7d5ab", + "revision": 3, + "name": "noop-builder", + "namespace": "builder", + "version": "1.0.0", + "licenses": [ + "(MIT-1.0)" + ] + } + ], + "buildLogIds": [ + { + "id": "5839ede4-a43e-54f7-84f9-6af8884e7f47", + "platformID": "" + } + ], + "resolvedRequirements": [ + { + "requirement": { + "name": "provides_hello", + "namespace": "private/ActiveState-CLI" + }, + "resolvedSource": "88ece3b1-efd3-52cd-9bac-8a3c5c80e4c7" + }, + { + "requirement": { + "name": "alternative-build-selector", + "namespace": "internal" + }, + "resolvedSource": "a0018800-f1fb-53dd-8e10-049ba0b9245b" + }, + { + "requirement": { + "name": "mingw-build-selector", + "namespace": "internal" + }, + "resolvedSource": "b6588d63-067d-501e-84d4-d9a7881c1119" + } + ] +} diff --git a/test/integration/testdata/checkout-from-archive/windows/installer_config.json b/test/integration/testdata/checkout-from-archive/windows/installer_config.json new file mode 100644 index 0000000000..c0493365cd --- /dev/null +++ b/test/integration/testdata/checkout-from-archive/windows/installer_config.json @@ -0,0 +1,7 @@ +{ + "org_name": "ActiveState-CLI", + "project_name": "AlmostEmpty", + "commit_id": "6cd1cc1f-3886-439b-8373-c24ca06ab150", + "branch": "main", + "platform_id": "78977bc8-0f32-519d-80f3-9043f059398c" +} \ No newline at end of file diff --git a/test/integration/testdata/import/cyclonedx/bom.json b/test/integration/testdata/import/cyclonedx/bom.json new file mode 100644 index 0000000000..666a547602 --- /dev/null +++ b/test/integration/testdata/import/cyclonedx/bom.json @@ -0,0 +1,117 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:1f860713-54b9-4253-ba5a-9554851904af", + "version": 1, + "metadata": { + "timestamp": "2020-08-03T03:20:53.771Z", + "tools": [ + { + "vendor": "CycloneDX", + "name": "Node.js module", + "version": "2.0.0" + } + ], + "component": { + "type": "library", + "bom-ref": "pkg:npm/juice-shop@11.1.2", + "name": "juice-shop", + "version": "11.1.2", + "description": "Probably the most modern and sophisticated insecure web application", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:npm/juice-shop@11.1.2", + "externalReferences": [ + { + "type": "website", + "url": "https://owasp-juice.shop" + }, + { + "type": "issue-tracker", + "url": "https://github.com/bkimminich/juice-shop/issues" + }, + { + "type": "vcs", + "url": "git+https://github.com/bkimminich/juice-shop.git" + } + ] + } + }, + "components": [ + { + "type": "library", + "bom-ref": "pkg:npm/body-parser@1.19.0", + "name": "body-parser", + "version": "1.19.0", + "description": "Node.js body parsing middleware", + "hashes": [ + { + "alg": "SHA-1", + "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:npm/body-parser@1.19.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/expressjs/body-parser#readme" + }, + { + "type": "issue-tracker", + "url": "https://github.com/expressjs/body-parser/issues" + }, + { + "type": "vcs", + "url": "git+https://github.com/expressjs/body-parser.git" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:npm/bytes@3.1.0", + "name": "bytes", + "version": "3.1.0", + "description": "Utility to parse a string bytes to bytes and vice-versa", + "hashes": [ + { + "alg": "SHA-1", + "content": "f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:npm/bytes@3.1.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/visionmedia/bytes.js#readme" + }, + { + "type": "issue-tracker", + "url": "https://github.com/visionmedia/bytes.js/issues" + }, + { + "type": "vcs", + "url": "git+https://github.com/visionmedia/bytes.js.git" + } + ] + } + ] +} diff --git a/test/integration/testdata/import/cyclonedx/bom.xml b/test/integration/testdata/import/cyclonedx/bom.xml new file mode 100644 index 0000000000..1e510036d1 --- /dev/null +++ b/test/integration/testdata/import/cyclonedx/bom.xml @@ -0,0 +1,93 @@ + + + + 2020-08-03T03:19:55.999Z + + + CycloneDX + Node.js module + 2.0.0 + + + + juice-shop + 11.1.2 + + + + + + MIT + + + pkg:npm/juice-shop@11.1.2 + + + https://owasp-juice.shop + + + https://github.com/bkimminich/juice-shop/issues + + + git+https://github.com/bkimminich/juice-shop.git + + + + + + + body-parser + 1.19.0 + + + + + 96b2709e57c9c4e09a6fd66a8fd979844f69f08a + + + + MIT + + + pkg:npm/body-parser@1.19.0 + + + https://github.com/expressjs/body-parser#readme + + + https://github.com/expressjs/body-parser/issues + + + git+https://github.com/expressjs/body-parser.git + + + + + bytes + 3.1.0 + + + + + f6cf7933a360e0588fa9fde85651cdc7f805d1f6 + + + + MIT + + + pkg:npm/bytes@3.1.0 + + + https://github.com/visionmedia/bytes.js#readme + + + https://github.com/visionmedia/bytes.js/issues + + + git+https://github.com/visionmedia/bytes.js.git + + + + + diff --git a/test/integration/testdata/import/spdx/appbomination.spdx.json b/test/integration/testdata/import/spdx/appbomination.spdx.json new file mode 100644 index 0000000000..eedeab01b1 --- /dev/null +++ b/test/integration/testdata/import/spdx/appbomination.spdx.json @@ -0,0 +1,310 @@ +{ + "SPDXID" : "SPDXRef-DOCUMENT", + "spdxVersion" : "SPDX-2.2", + "creationInfo" : { + "comment" : "Created for SPDX DocFest Sept 2021", + "created" : "2021-09-02T13:46:32Z", + "creators" : [ "Person: Gary O'Neall", "Tool: Source Auditor Open Source Console" ], + "licenseListVersion" : "3.14" + }, + "name" : "SpdxDoc for App-BOM-ination", + "dataLicense" : "CC0-1.0", + "hasExtractedLicensingInfos" : [ { + "licenseId" : "LicenseRef-1", + "extractedText" : "This file is licensed under the following license.\r\n \r\nFAUST, INC. PROPRIETARY LICENSE:\r\n\r\nFAUST, INC. grants you a non-exclusive right to use, modify, and distribute\r\nthe file provided that (a) you distribute all copies and/or modifications of\r\nthis file, whether in source or binary form, under the same license, and (b)\r\nyou hereby irrevocably transfer and assign the ownership of your soul to Faust, \r\nInc. In the event the fair market value of your soul is less than $100 US, you\r\nagree to compensate Faust, Inc. for the difference. \r\n\r\nCopyright (C) 2016 Faust Inc. All, and I mean ALL, rights are reserved.", + "name" : "Faust Proprietary Notice" + } ], + "documentNamespace" : "http://www.sourceauditor.com/spdxdocs/appbomination-src/e3b71037-57de-44c9-8b7f-4e8a62f45311", + "documentDescribes" : [ "SPDXRef-1" ], + "packages" : [ { + "SPDXID" : "SPDXRef-1", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "498cebd51a4483d6e68c2fc62d27008252fa4f7b" + } ], + "copyrightText" : "Copyright (c) 2016 Faust, Inc.", + "description" : "A uniquely useless project with a cataclysmic software supply chain, to serve a test case for BOM solutions.", + "downloadLocation" : "https://github.com/act-project/App-BOM-ination/archive/refs/tags/1.0.zip", + "filesAnalyzed" : true, + "hasFiles" : [ "SPDXRef-7", "SPDXRef-10", "SPDXRef-2", "SPDXRef-3", "SPDXRef-4", "SPDXRef-6", "SPDXRef-9", "SPDXRef-11", "SPDXRef-12", "SPDXRef-14" ], + "homepage" : "https://github.com/act-project/App-BOM-ination", + "licenseComments" : "Faust proprietary notice was found in one or more source files. LGPL-2.0-or-later OR WTFPL was in a build configuration file and does not apply to the concluded license.", + "licenseConcluded" : "(LicenseRef-1 AND Apache-2.0)", + "licenseDeclared" : "Apache-2.0", + "licenseInfoFromFiles" : [ "LicenseRef-1", "Apache-2.0", "(LGPL-2.0-or-later OR WTFPL)" ], + "name" : "App-BOM-ination", + "originator" : "Person: Yevester", + "packageFileName" : "App-BOM-ination-1.0.zip", + "packageVerificationCode" : { + "packageVerificationCodeValue" : "be2fb65c6b22b81f1b273442d70479a41a3093e7" + }, + "sourceInfo" : "", + "summary" : "A uniquely useless project with a cataclysmic software supply chain, to serve a test case for BOM solutions.", + "supplier" : "Organization: ACT Project", + "versionInfo" : "1.0" + }, { + "SPDXID" : "SPDXRef-23", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "42a25dc3219429f0e5d060061f71acb49bf010a0" + } ], + "comment" : "Package info from Maven Central POM file", + "copyrightText" : "NOASSERTION", + "downloadLocation" : "https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar", + "externalRefs" : [ { + "referenceCategory" : "PACKAGE-MANAGER", + "referenceLocator" : "pkg:maven/org.hamcrest/hamcrest-core@1.3", + "referenceType" : "purl" + } ], + "filesAnalyzed" : false, + "licenseConcluded" : "BSD-3-Clause", + "licenseDeclared" : "NOASSERTION", + "name" : "hamcrest-core", + "packageFileName" : "hamcrest-core-1.3.jar", + "versionInfo" : "1.3" + }, { + "SPDXID" : "SPDXRef-21", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "5fe28b9518e58819180a43a850fbc0dd24b7c050" + } ], + "comment" : "Package info from Maven Central POM file", + "copyrightText" : "NOASSERTION", + "downloadLocation" : "https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.jar", + "externalRefs" : [ { + "referenceCategory" : "PACKAGE-MANAGER", + "referenceLocator" : "pkg:maven/org.apache.commons/commons-lang3@3.4", + "referenceType" : "purl" + } ], + "filesAnalyzed" : false, + "homepage" : "http://commons.apache.org/proper/commons-lang/", + "licenseConcluded" : "Apache-2.0", + "licenseDeclared" : "Apache-2.0", + "name" : "commons-lang3", + "packageFileName" : "commons-lang3-3.4.jar", + "versionInfo" : "3.4" + }, { + "SPDXID" : "SPDXRef-22", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "4e6be5af63e3373b4f0cbc4c151c13e059151e00" + } ], + "comment" : "Package info from Maven Central POM file", + "copyrightText" : "NOASSERTION", + "downloadLocation" : "https://repo1.maven.org/maven2/junit/junit/4.12/junit-4.12.jar", + "externalRefs" : [ { + "referenceCategory" : "PACKAGE-MANAGER", + "referenceLocator" : "pkg:maven/junit/junit@4.12", + "referenceType" : "purl" + } ], + "filesAnalyzed" : false, + "homepage" : "http://junit.org", + "licenseConcluded" : "EPL-1.0", + "licenseDeclared" : "EPL-1.0", + "name" : "junit", + "packageFileName" : "junit-4.12.jar", + "versionInfo" : "4.12" + }, { + "SPDXID" : "SPDXRef-20", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "466308a5554594190da5fe2c86b4a8e5037c37cc" + } ], + "comment" : "Package info from Maven Central POM file", + "copyrightText" : "NOASSERTION", + "downloadLocation" : "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar", + "externalRefs" : [ { + "referenceCategory" : "PACKAGE-MANAGER", + "referenceLocator" : "pkg:maven/org.slf4j/slf4j-api@1.7.21", + "referenceType" : "purl" + } ], + "filesAnalyzed" : false, + "homepage" : "http://www.slf4j.org", + "licenseConcluded" : "Apache-2.0", + "licenseDeclared" : "NOASSERTION", + "name" : "slf4j-api", + "packageFileName" : "slf4j-api-1.7.21.jar", + "versionInfo" : "1.7.21" + } ], + "files" : [ { + "SPDXID" : "SPDXRef-7", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "92170cdc034b2ff819323ff670d3b7266c8bffcd" + } ], + "copyrightText" : "NOASSERTION", + "fileName" : "./App-BOM-ination-1.0/LICENSE", + "fileTypes" : [ "OTHER" ], + "licenseConcluded" : "Apache-2.0", + "licenseInfoInFiles" : [ "NOASSERTION" ], + "noticeText" : "NOASSERTION" + }, { + "SPDXID" : "SPDXRef-9", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "340e8b696bc50d76cf50df943dbaf46591da9ef4" + } ], + "copyrightText" : "NOASSERTION", + "fileName" : "./App-BOM-ination-1.0/logo.png", + "fileTypes" : [ "BINARY" ], + "licenseConcluded" : "Apache-2.0", + "licenseInfoInFiles" : [ "NOASSERTION" ], + "noticeText" : "NOASSERTION" + }, { + "SPDXID" : "SPDXRef-3", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "67174de726d5caae455cd22e9c4450e9c490ac6b" + } ], + "copyrightText" : "NOASSERTION", + "fileName" : "./App-BOM-ination-1.0/gradle/wrapper/gradle-wrapper.properties", + "fileTypes" : [ "OTHER" ], + "licenseConcluded" : "(LicenseRef-1 AND Apache-2.0)", + "licenseInfoInFiles" : [ "NOASSERTION" ], + "noticeText" : "NOASSERTION" + }, { + "SPDXID" : "SPDXRef-4", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "b86a8c3bab5a3ed0441b3fe3b1f6b31ec1ead901" + } ], + "copyrightText" : "NOASSERTION", + "fileName" : "./App-BOM-ination-1.0/gradlew", + "fileTypes" : [ "OTHER" ], + "licenseConcluded" : "Apache-2.0", + "licenseInfoInFiles" : [ "NOASSERTION" ], + "noticeText" : "NOASSERTION" + }, { + "SPDXID" : "SPDXRef-6", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "d841ffc9855dcc642901e8abf28dee20b0485864" + } ], + "comment" : "BOMNOTE:File|", + "copyrightText" : "NOASSERTION", + "fileName" : "./App-BOM-ination-1.0/gradlew.bat", + "fileTypes" : [ "SOURCE" ], + "licenseConcluded" : "Apache-2.0", + "licenseInfoInFiles" : [ "NOASSERTION" ], + "noticeText" : "NOASSERTION" + }, { + "SPDXID" : "SPDXRef-2", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "9c55f0e3bd70363a02377f729d139a5d91325d40" + } ], + "copyrightText" : "NOASSERTION", + "fileName" : "./App-BOM-ination-1.0/build.gradle", + "fileTypes" : [ "OTHER" ], + "licenseConcluded" : "(LGPL-2.0-or-later OR WTFPL)", + "licenseInfoInFiles" : [ "NOASSERTION" ], + "noticeText" : "NOASSERTION" + }, { + "SPDXID" : "SPDXRef-14", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "2b7b936a3f185a53528724e4f4141030906963c2" + } ], + "copyrightText" : "NOASSERTION", + "fileName" : "./App-BOM-ination-1.0/src/main/java/com/github/appbomination/Main.java", + "fileTypes" : [ "SOURCE" ], + "licenseComments" : "Seen licenses generated by Source Auditor Scanner. Results should be manually verified.", + "licenseConcluded" : "Apache-2.0", + "licenseInfoInFiles" : [ "Apache-2.0" ], + "noticeText" : "NOASSERTION" + }, { + "SPDXID" : "SPDXRef-12", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "fd668bc0096794e4d8125a29f9a746c0ab1edc57" + } ], + "comment" : "BOMNOTE:File|Matched Notice='Faust Proprietary Notice'|", + "copyrightText" : "Copyright Faust Inc. All, and I mean ALL, rights are reserved", + "fileName" : "./App-BOM-ination-1.0/src/main/java/com/github/appbomination/InsufficientKarmaException.java", + "fileTypes" : [ "SOURCE" ], + "licenseConcluded" : "LicenseRef-1", + "licenseInfoInFiles" : [ "NOASSERTION" ], + "noticeText" : "NOASSERTION" + }, { + "SPDXID" : "SPDXRef-10", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "15399fcbbe6f3ff84c82039d446d820ecbbc3ac6" + } ], + "copyrightText" : "NOASSERTION", + "fileName" : "./App-BOM-ination-1.0/README.md", + "fileTypes" : [ "OTHER" ], + "licenseConcluded" : "Apache-2.0", + "licenseInfoInFiles" : [ "NOASSERTION" ], + "noticeText" : "NOASSERTION" + }, { + "SPDXID" : "SPDXRef-11", + "checksums" : [ { + "algorithm" : "SHA1", + "checksumValue" : "1458a5c5fb1189d2cc8212052975f39ae710d622" + } ], + "copyrightText" : "NOASSERTION", + "fileName" : "./App-BOM-ination-1.0/settings.gradle", + "fileTypes" : [ "OTHER" ], + "licenseConcluded" : "Apache-2.0", + "licenseInfoInFiles" : [ "NOASSERTION" ], + "noticeText" : "NOASSERTION" + } ], + "relationships" : [ { + "spdxElementId" : "SPDXRef-DOCUMENT", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "DESCRIBES" + }, { + "spdxElementId" : "SPDXRef-23", + "relatedSpdxElement" : "SPDXRef-22", + "relationshipType" : "DEPENDENCY_OF" + }, { + "spdxElementId" : "SPDXRef-21", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "DEPENDENCY_OF" + }, { + "spdxElementId" : "SPDXRef-22", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "TEST_DEPENDENCY_OF" + }, { + "spdxElementId" : "SPDXRef-20", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "DEPENDENCY_OF" + }, { + "spdxElementId" : "SPDXRef-7", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "CONTAINED_BY" + }, { + "spdxElementId" : "SPDXRef-9", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "CONTAINED_BY" + }, { + "spdxElementId" : "SPDXRef-4", + "relatedSpdxElement" : "SPDXRef-5", + "relationshipType" : "CONTAINED_BY" + }, { + "spdxElementId" : "SPDXRef-6", + "relatedSpdxElement" : "SPDXRef-5", + "relationshipType" : "CONTAINED_BY" + }, { + "spdxElementId" : "SPDXRef-2", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "METAFILE_OF" + }, { + "spdxElementId" : "SPDXRef-14", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "CONTAINED_BY" + }, { + "spdxElementId" : "SPDXRef-12", + "relatedSpdxElement" : "SPDXRef-13", + "relationshipType" : "CONTAINED_BY" + }, { + "spdxElementId" : "SPDXRef-10", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "CONTAINED_BY" + }, { + "spdxElementId" : "SPDXRef-11", + "relatedSpdxElement" : "SPDXRef-1", + "relationshipType" : "CONTAINED_BY" + } ] +} diff --git a/test/integration/testdata/import/spdx/example1.spdx b/test/integration/testdata/import/spdx/example1.spdx new file mode 100644 index 0000000000..ae4e52cadb --- /dev/null +++ b/test/integration/testdata/import/spdx/example1.spdx @@ -0,0 +1,58 @@ +SPDXVersion: SPDX-2.2 +DataLicense: CC0-1.0 +SPDXID: SPDXRef-DOCUMENT +DocumentName: hello +DocumentNamespace: https://swinslow.net/spdx-examples/example1/hello-v3 +Creator: Person: Steve Winslow (steve@swinslow.net) +Creator: Tool: github.com/spdx/tools-golang/builder +Creator: Tool: github.com/spdx/tools-golang/idsearcher +Created: 2021-08-26T01:46:00Z + +##### Package: hello + +PackageName: hello +PackageVersion: 1.0.0 +SPDXID: SPDXRef-Package-hello +PackageDownloadLocation: git+https://github.com/swinslow/spdx-examples.git#example1/content +FilesAnalyzed: true +PackageVerificationCode: 9d20237bb72087e87069f96afb41c6ca2fa2a342 +PackageLicenseConcluded: GPL-3.0-or-later +PackageLicenseInfoFromFiles: GPL-3.0-or-later +PackageLicenseDeclared: GPL-3.0-or-later +PackageCopyrightText: NOASSERTION + +Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-hello + +FileName: ./build/hello +SPDXID: SPDXRef-hello-binary +FileType: BINARY +FileChecksum: SHA1: 20291a81ef065ff891b537b64d4fdccaf6f5ac02 +FileChecksum: SHA256: 83a33ff09648bb5fc5272baca88cf2b59fd81ac4cc6817b86998136af368708e +FileChecksum: MD5: 08a12c966d776864cc1eb41fd03c3c3d +LicenseConcluded: GPL-3.0-or-later +LicenseInfoInFile: NOASSERTION +FileCopyrightText: NOASSERTION + +FileName: ./src/Makefile +SPDXID: SPDXRef-Makefile +FileType: SOURCE +FileChecksum: SHA1: 69a2e85696fff1865c3f0686d6c3824b59915c80 +FileChecksum: SHA256: 5da19033ba058e322e21c90e6d6d859c90b1b544e7840859c12cae5da005e79c +FileChecksum: MD5: 559424589a4f3f75fd542810473d8bc1 +LicenseConcluded: GPL-3.0-or-later +LicenseInfoInFile: GPL-3.0-or-later +FileCopyrightText: NOASSERTION + +FileName: ./src/hello.c +SPDXID: SPDXRef-hello-src +FileType: SOURCE +FileChecksum: SHA1: 20862a6d08391d07d09344029533ec644fac6b21 +FileChecksum: SHA256: b4e5ca56d1f9110ca94ed0bf4e6d9ac11c2186eb7cd95159c6fdb50e8db5a823 +FileChecksum: MD5: 935054fe899ca782e11003bbae5e166c +LicenseConcluded: GPL-3.0-or-later +LicenseInfoInFile: GPL-3.0-or-later +FileCopyrightText: Copyright Contributors to the spdx-examples project. + +Relationship: SPDXRef-hello-binary GENERATED_FROM SPDXRef-hello-src +Relationship: SPDXRef-hello-binary GENERATED_FROM SPDXRef-Makefile +Relationship: SPDXRef-Makefile BUILD_TOOL_OF SPDXRef-Package-hello diff --git a/test/integration/testdata/sample_ingredient/LICENSE.txt b/test/integration/testdata/sample_ingredient/LICENSE.txt new file mode 100644 index 0000000000..c74aceda03 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2016 The Python Packaging Authority (PyPA) + +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. diff --git a/test/integration/testdata/sample_ingredient/PKG-INFO b/test/integration/testdata/sample_ingredient/PKG-INFO new file mode 100644 index 0000000000..2d57b7f7b5 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/PKG-INFO @@ -0,0 +1,70 @@ +Metadata-Version: 2.1 +Name: sample_activestate +Version: 1.0.0 +Summary: Example Project of Building Wheels using ActiveState Platform +Home-page: https://github.com/pypa/sampleproject +Author: A. Random Developer +Author-email: author@example.com +Project-URL: Bug Reports, https://github.com/pypa/sampleproject/issues +Project-URL: Funding, https://donate.pypi.org +Project-URL: Say Thanks!, http://saythanks.io/to/example +Project-URL: Source, https://github.com/pypa/sampleproject/ +Keywords: sample,setuptools,development +Classifier: Development Status :: 3 - Alpha +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Build Tools +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3 :: Only +Requires-Python: >=3.7, <4 +Description-Content-Type: text/markdown +License-File: LICENSE.txt +Requires-Dist: peppercorn +Provides-Extra: dev +Requires-Dist: check-manifest; extra == "dev" +Provides-Extra: test +Requires-Dist: coverage; extra == "test" + +# A sample Python project + +![Python Logo](https://www.python.org/static/community_logos/python-logo.png "Sample inline image") + +A sample project that exists as an aid to the [Python Packaging User +Guide][packaging guide]'s [Tutorial on Packaging and Distributing +Projects][distribution tutorial]. + +This project does not aim to cover best practices for Python project +development as a whole. For example, it does not provide guidance or tool +recommendations for version control, documentation, or testing. + +[The source for this project is available here][src]. + +Most of the configuration for a Python project is done in the `setup.py` file, +an example of which is included in this project. You should edit this file +accordingly to adapt this sample project to your needs. + +---- + +This is the README file for the project. + +The file should use UTF-8 encoding and can be written using +[reStructuredText][rst] or [markdown][md use] with the appropriate [key set][md +use]. It will be used to generate the project webpage on PyPI and will be +displayed as the project homepage on common code-hosting services, and should be +written for that purpose. + +Typical contents for this file would include an overview of the project, basic +usage examples, etc. Generally, including the project changelog in here is not a +good idea, although a simple “What's New” section for the most recent version +may be appropriate. + +[packaging guide]: https://packaging.python.org +[distribution tutorial]: https://packaging.python.org/tutorials/packaging-projects/ +[src]: https://github.com/pypa/sampleproject +[rst]: http://docutils.sourceforge.net/rst.html +[md]: https://tools.ietf.org/html/rfc7764#section-3.5 "CommonMark variant" +[md use]: https://packaging.python.org/specifications/core-metadata/#description-content-type-optional diff --git a/test/integration/testdata/sample_ingredient/README.md b/test/integration/testdata/sample_ingredient/README.md new file mode 100644 index 0000000000..790503e288 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/README.md @@ -0,0 +1,40 @@ +# A sample Python project + +![Python Logo](https://www.python.org/static/community_logos/python-logo.png "Sample inline image") + +A sample project that exists as an aid to the [Python Packaging User +Guide][packaging guide]'s [Tutorial on Packaging and Distributing +Projects][distribution tutorial]. + +This project does not aim to cover best practices for Python project +development as a whole. For example, it does not provide guidance or tool +recommendations for version control, documentation, or testing. + +[The source for this project is available here][src]. + +Most of the configuration for a Python project is done in the `setup.py` file, +an example of which is included in this project. You should edit this file +accordingly to adapt this sample project to your needs. + +---- + +This is the README file for the project.......... + +The file should use UTF-8 encoding and can be written using +[reStructuredText][rst] or [markdown][md use] with the appropriate [key set][md +use]. It will be used to generate the project webpage on PyPI and will be +displayed as the project homepage on common code-hosting services, and should be +written for that purpose. + +Typical contents for this file would include an overview of the project, basic +usage examples, etc. Generally, including the project changelog in here is not a +good idea, although a simple “What's New” section for the most recent version +may be appropriate. + +[packaging guide]: https://packaging.python.org +[distribution tutorial]: https://packaging.python.org/tutorials/packaging-projects/ +[src]: https://github.com/pypa/sampleproject +[rst]: http://docutils.sourceforge.net/rst.html +[md]: https://tools.ietf.org/html/rfc7764#section-3.5 "CommonMark variant" +[md use]: https://packaging.python.org/specifications/core-metadata/#description-content-type-optional + diff --git a/test/integration/testdata/sample_ingredient/data/data_file b/test/integration/testdata/sample_ingredient/data/data_file new file mode 100644 index 0000000000..7c0646bfd5 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/data/data_file @@ -0,0 +1 @@ +some data \ No newline at end of file diff --git a/test/integration/testdata/sample_ingredient/pyproject.toml b/test/integration/testdata/sample_ingredient/pyproject.toml new file mode 100644 index 0000000000..9ebf20604e --- /dev/null +++ b/test/integration/testdata/sample_ingredient/pyproject.toml @@ -0,0 +1,5 @@ +[build-system] +# These are the assumed default build requirements from pip: +# https://pip.pypa.io/en/stable/reference/pip/#pep-517-and-518-support +requires = ["setuptools>=43.0.0", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/test/integration/testdata/sample_ingredient/setup.cfg b/test/integration/testdata/sample_ingredient/setup.cfg new file mode 100644 index 0000000000..10ba068c41 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/setup.cfg @@ -0,0 +1,7 @@ +[metadata] +license_files = LICENSE.txt + +[egg_info] +tag_build = +tag_date = 0 + diff --git a/test/integration/testdata/sample_ingredient/setup.py b/test/integration/testdata/sample_ingredient/setup.py new file mode 100644 index 0000000000..0f54d579f4 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/setup.py @@ -0,0 +1,181 @@ +"""A setuptools based setup module. + +See: +https://packaging.python.org/guides/distributing-packages-using-setuptools/ +https://github.com/pypa/sampleproject +""" + +# Always prefer setuptools over distutils +from setuptools import setup, find_packages +import pathlib + +here = pathlib.Path(__file__).parent.resolve() + +# Get the long description from the README file +long_description = (here / "README.md").read_text(encoding="utf-8") + +# Arguments marked as "Required" below must be included for upload to PyPI. +# Fields marked as "Optional" may be commented out. + +setup( + # This is the name of your project. The first time you publish this + # package, this name will be registered for you. It will determine how + # users can install this project, e.g.: + # + # $ pip install sampleproject + # + # And where it will live on PyPI: https://pypi.org/project/sampleproject/ + # + # There are some restrictions on what makes a valid project name + # specification here: + # https://packaging.python.org/specifications/core-metadata/#name + name="sample_activestate", # Required + # Versions should comply with PEP 440: + # https://www.python.org/dev/peps/pep-0440/ + # + # For a discussion on single-sourcing the version across setup.py and the + # project code, see + # https://packaging.python.org/guides/single-sourcing-package-version/ + version="1.0.0", # Required + # This is a one-line description or tagline of what your project does. This + # corresponds to the "Summary" metadata field: + # https://packaging.python.org/specifications/core-metadata/#summary + description="Example Project of Building Wheels using ActiveState Platform", # Optional + # This is an optional longer description of your project that represents + # the body of text which users will see when they visit PyPI. + # + # Often, this is the same as your README, so you can just read it in from + # that file directly (as we have already done above) + # + # This field corresponds to the "Description" metadata field: + # https://packaging.python.org/specifications/core-metadata/#description-optional + long_description=long_description, # Optional + # Denotes that our long_description is in Markdown; valid values are + # text/plain, text/x-rst, and text/markdown + # + # Optional if long_description is written in reStructuredText (rst) but + # required for plain-text or Markdown; if unspecified, "applications should + # attempt to render [the long_description] as text/x-rst; charset=UTF-8 and + # fall back to text/plain if it is not valid rst" (see link below) + # + # This field corresponds to the "Description-Content-Type" metadata field: + # https://packaging.python.org/specifications/core-metadata/#description-content-type-optional + long_description_content_type="text/markdown", # Optional (see note above) + # This should be a valid link to your project's main homepage. + # + # This field corresponds to the "Home-Page" metadata field: + # https://packaging.python.org/specifications/core-metadata/#home-page-optional + url="https://github.com/pypa/sampleproject", # Optional + # This should be your name or the name of the organization which owns the + # project. + author="A. Random Developer", # Optional + # This should be a valid email address corresponding to the author listed + # above. + author_email="author@example.com", # Optional + # Classifiers help users find your project by categorizing it. + # + # For a list of valid classifiers, see https://pypi.org/classifiers/ + classifiers=[ # Optional + # How mature is this project? Common values are + # 3 - Alpha + # 4 - Beta + # 5 - Production/Stable + "Development Status :: 3 - Alpha", + # Indicate who your project is intended for + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", + # Pick your license as you wish + "License :: OSI Approved :: MIT License", + # Specify the Python versions you support here. In particular, ensure + # that you indicate you support Python 3. These classifiers are *not* + # checked by 'pip install'. See instead 'python_requires' below. + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3 :: Only", + ], + # This field adds keywords for your project which will appear on the + # project page. What does your project relate to? + # + # Note that this is a list of additional keywords, separated + # by commas, to be used to assist searching for the distribution in a + # larger catalog. + keywords="sample, setuptools, development", # Optional + # When your source code is in a subdirectory under the project root, e.g. + # `src/`, it is necessary to specify the `package_dir` argument. + package_dir={"": "src"}, # Optional + # You can just specify package directories manually here if your project is + # simple. Or you can use find_packages(). + # + # Alternatively, if you just want to distribute a single Python file, use + # the `py_modules` argument instead as follows, which will expect a file + # called `my_module.py` to exist: + # + # py_modules=["my_module"], + # + packages=find_packages(where="src"), # Required + # Specify which Python versions you support. In contrast to the + # 'Programming Language' classifiers above, 'pip install' will check this + # and refuse to install the project if the version does not match. See + # https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires + python_requires=">=3.7, <4", + # This field lists other packages that your project depends on to run. + # Any package you put here will be installed by pip when your project is + # installed, so they must be valid existing projects. + # + # For an analysis of "install_requires" vs pip's requirements files see: + # https://packaging.python.org/discussions/install-requires-vs-requirements/ + install_requires=["peppercorn"], # Optional + # List additional groups of dependencies here (e.g. development + # dependencies). Users will be able to install these using the "extras" + # syntax, for example: + # + # $ pip install sampleproject[dev] + # + # Similar to `install_requires` above, these must be valid existing + # projects. + extras_require={ # Optional + "dev": ["check-manifest"], + "test": ["coverage"], + }, + # If there are data files included in your packages that need to be + # installed, specify them here. + package_data={ # Optional + "sample": ["package_data.dat"], + }, + # Although 'package_data' is the preferred approach, in some case you may + # need to place data files outside of your packages. See: + # http://docs.python.org/distutils/setupscript.html#installing-additional-files + # + # In this case, 'data_file' will be installed into '/my_data' + data_files=[("my_data", ["data/data_file"])], # Optional + # To provide executable scripts, use entry points in preference to the + # "scripts" keyword. Entry points provide cross-platform support and allow + # `pip` to create the appropriate form of executable for the target + # platform. + # + # For example, the following would provide a command called `sample` which + # executes the function `main` from this package when invoked: + entry_points={ # Optional + "console_scripts": [ + "sample=sample:main", + ], + }, + # List additional URLs that are relevant to your project as a dict. + # + # This field corresponds to the "Project-URL" metadata fields: + # https://packaging.python.org/specifications/core-metadata/#project-url-multiple-use + # + # Examples listed include a pattern for specifying where the package tracks + # issues, where the source is hosted, where to say thanks to the package + # maintainers, and where to support the project financially. The key is + # what's used to render the link text on PyPI. + project_urls={ # Optional + "Bug Reports": "https://github.com/pypa/sampleproject/issues", + "Funding": "https://donate.pypi.org", + "Say Thanks!": "http://saythanks.io/to/example", + "Source": "https://github.com/pypa/sampleproject/", + }, +) diff --git a/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/PKG-INFO b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/PKG-INFO new file mode 100644 index 0000000000..2d57b7f7b5 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/PKG-INFO @@ -0,0 +1,70 @@ +Metadata-Version: 2.1 +Name: sample_activestate +Version: 1.0.0 +Summary: Example Project of Building Wheels using ActiveState Platform +Home-page: https://github.com/pypa/sampleproject +Author: A. Random Developer +Author-email: author@example.com +Project-URL: Bug Reports, https://github.com/pypa/sampleproject/issues +Project-URL: Funding, https://donate.pypi.org +Project-URL: Say Thanks!, http://saythanks.io/to/example +Project-URL: Source, https://github.com/pypa/sampleproject/ +Keywords: sample,setuptools,development +Classifier: Development Status :: 3 - Alpha +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Build Tools +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3 :: Only +Requires-Python: >=3.7, <4 +Description-Content-Type: text/markdown +License-File: LICENSE.txt +Requires-Dist: peppercorn +Provides-Extra: dev +Requires-Dist: check-manifest; extra == "dev" +Provides-Extra: test +Requires-Dist: coverage; extra == "test" + +# A sample Python project + +![Python Logo](https://www.python.org/static/community_logos/python-logo.png "Sample inline image") + +A sample project that exists as an aid to the [Python Packaging User +Guide][packaging guide]'s [Tutorial on Packaging and Distributing +Projects][distribution tutorial]. + +This project does not aim to cover best practices for Python project +development as a whole. For example, it does not provide guidance or tool +recommendations for version control, documentation, or testing. + +[The source for this project is available here][src]. + +Most of the configuration for a Python project is done in the `setup.py` file, +an example of which is included in this project. You should edit this file +accordingly to adapt this sample project to your needs. + +---- + +This is the README file for the project. + +The file should use UTF-8 encoding and can be written using +[reStructuredText][rst] or [markdown][md use] with the appropriate [key set][md +use]. It will be used to generate the project webpage on PyPI and will be +displayed as the project homepage on common code-hosting services, and should be +written for that purpose. + +Typical contents for this file would include an overview of the project, basic +usage examples, etc. Generally, including the project changelog in here is not a +good idea, although a simple “What's New” section for the most recent version +may be appropriate. + +[packaging guide]: https://packaging.python.org +[distribution tutorial]: https://packaging.python.org/tutorials/packaging-projects/ +[src]: https://github.com/pypa/sampleproject +[rst]: http://docutils.sourceforge.net/rst.html +[md]: https://tools.ietf.org/html/rfc7764#section-3.5 "CommonMark variant" +[md use]: https://packaging.python.org/specifications/core-metadata/#description-content-type-optional diff --git a/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/SOURCES.txt b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/SOURCES.txt new file mode 100644 index 0000000000..d71d502dcc --- /dev/null +++ b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/SOURCES.txt @@ -0,0 +1,15 @@ +LICENSE.txt +README.md +pyproject.toml +setup.cfg +setup.py +data/data_file +src/sample_activestate/__init__.py +src/sample_activestate/simple.py +src/sample_activestate.egg-info/PKG-INFO +src/sample_activestate.egg-info/SOURCES.txt +src/sample_activestate.egg-info/dependency_links.txt +src/sample_activestate.egg-info/entry_points.txt +src/sample_activestate.egg-info/requires.txt +src/sample_activestate.egg-info/top_level.txt +tests/test_simple.py \ No newline at end of file diff --git a/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/dependency_links.txt b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/dependency_links.txt new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/entry_points.txt b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/entry_points.txt new file mode 100644 index 0000000000..21b1ba31a1 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +sample = sample:main diff --git a/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/requires.txt b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/requires.txt new file mode 100644 index 0000000000..d3f379815f --- /dev/null +++ b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/requires.txt @@ -0,0 +1,7 @@ +peppercorn + +[dev] +check-manifest + +[test] +coverage diff --git a/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/top_level.txt b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/top_level.txt new file mode 100644 index 0000000000..ac18024e0b --- /dev/null +++ b/test/integration/testdata/sample_ingredient/src/sample_activestate.egg-info/top_level.txt @@ -0,0 +1 @@ +sample_activestate diff --git a/test/integration/testdata/sample_ingredient/src/sample_activestate/__init__.py b/test/integration/testdata/sample_ingredient/src/sample_activestate/__init__.py new file mode 100644 index 0000000000..c8f1064994 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/src/sample_activestate/__init__.py @@ -0,0 +1,3 @@ +def main(): + """Entry point for the application script""" + print("Call your main application code here") diff --git a/test/integration/testdata/sample_ingredient/src/sample_activestate/simple.py b/test/integration/testdata/sample_ingredient/src/sample_activestate/simple.py new file mode 100644 index 0000000000..c929f885b6 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/src/sample_activestate/simple.py @@ -0,0 +1,2 @@ +def add_one(number): + return number + 1 diff --git a/test/integration/testdata/sample_ingredient/tests/test_simple.py b/test/integration/testdata/sample_ingredient/tests/test_simple.py new file mode 100644 index 0000000000..b7a0ee3a65 --- /dev/null +++ b/test/integration/testdata/sample_ingredient/tests/test_simple.py @@ -0,0 +1,17 @@ +# the inclusion of the tests module is not meant to offer best practices for +# testing in general, but rather to support the `find_packages` example in +# setup.py that excludes installing the "tests" package + +import unittest + +from sample.simple import add_one + + +class TestSimple(unittest.TestCase): + + def test_add_one(self): + self.assertEqual(add_one(5), 6) + + +if __name__ == '__main__': + unittest.main() diff --git a/test/integration/testdata/tools/refreshenv/refreshenv.bat b/test/integration/testdata/tools/refreshenv/refreshenv.bat index 416ea6680e..d421d1d24c 100644 --- a/test/integration/testdata/tools/refreshenv/refreshenv.bat +++ b/test/integration/testdata/tools/refreshenv/refreshenv.bat @@ -8,7 +8,7 @@ :: With this batch file, there should be no need to reload command :: environment every time you want environment changes to propagate -::echo "RefreshEnv.cmd only works from cmd.exe, please install the Chocolatey Profile to take advantage of refreshenv from PowerShell" +::echo "RefreshEnv.cmd only works from cmd.exe. Please install the Chocolatey Profile to take advantage of refreshenv from PowerShell" echo | set /p dummy="Refreshing environment variables from registry for cmd.exe. Please wait..." goto main diff --git a/test/integration/uninstall_int_test.go b/test/integration/uninstall_int_test.go index d344e17895..d6875666cf 100644 --- a/test/integration/uninstall_int_test.go +++ b/test/integration/uninstall_int_test.go @@ -51,7 +51,6 @@ func (suite *UninstallIntegrationTestSuite) install(ts *e2e.Session) string { cmd := "bash" opts := []e2e.SpawnOptSetter{ e2e.OptArgs(script, appInstallDir, "-n"), - e2e.OptAppendEnv(constants.DisableRuntime + "=false"), e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), e2e.OptAppendEnv(fmt.Sprintf("%s=FOO", constants.OverrideSessionTokenEnvVarName)), } @@ -68,7 +67,7 @@ func (suite *UninstallIntegrationTestSuite) install(ts *e2e.Session) string { } func (suite *UninstallIntegrationTestSuite) testUninstall(all bool) { - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() appInstallDir := suite.install(ts) @@ -140,6 +139,11 @@ func (suite *UninstallIntegrationTestSuite) testUninstall(all bool) { } } + if runtime.GOOS == "windows" { + shortcutDir := filepath.Join(ts.Dirs.HomeDir, "AppData", "Roaming", "Microsoft", "Windows", "Start Menu", "Programs", "ActiveState") + suite.NoDirExists(shortcutDir, "shortcut dir should not exist after uninstall") + } + if fileutils.DirExists(binDir) { suite.Fail("bin directory should not exist after uninstall") } diff --git a/test/integration/update_int_test.go b/test/integration/update_int_test.go index cfe56e2ce5..8bffc3a167 100644 --- a/test/integration/update_int_test.go +++ b/test/integration/update_int_test.go @@ -132,7 +132,7 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateAvailable() { func (suite *UpdateIntegrationTestSuite) TestUpdate() { suite.OnlyRunForTags(tagsuite.Update, tagsuite.Critical) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() suite.testUpdate(ts, filepath.Dir(ts.Dirs.Bin)) @@ -175,7 +175,7 @@ func (suite *UpdateIntegrationTestSuite) testUpdate(ts *e2e.Session, baseDir str func (suite *UpdateIntegrationTestSuite) TestUpdate_Repair() { suite.OnlyRunForTags(tagsuite.Update) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() cfg, err := config.NewCustom(ts.Dirs.Config, singlethread.New(), true) @@ -290,7 +290,7 @@ func (suite *UpdateIntegrationTestSuite) TestAutoUpdate() { // suite.T().Skip("Test will not work until v0.34.0") suite.OnlyRunForTags(tagsuite.Update, tagsuite.Critical) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() suite.testAutoUpdate(ts, filepath.Dir(ts.Dirs.Bin)) @@ -359,7 +359,7 @@ func (suite *UpdateIntegrationTestSuite) installLatestReleaseVersion(ts *e2e.Ses func (suite *UpdateIntegrationTestSuite) TestAutoUpdateToCurrent() { suite.OnlyRunForTags(tagsuite.Update, tagsuite.Critical) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() installDir := filepath.Join(ts.Dirs.Work, "install") @@ -378,7 +378,7 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateToCurrent() { } suite.OnlyRunForTags(tagsuite.Update, tagsuite.Critical) - ts := e2e.New(suite.T(), true) + ts := e2e.New(suite.T(), false) defer ts.Close() installDir := filepath.Join(ts.Dirs.Work, "install") diff --git a/test/integration/update_lock_int_test.go b/test/integration/update_lock_int_test.go index c675779778..6e9f9add34 100644 --- a/test/integration/update_lock_int_test.go +++ b/test/integration/update_lock_int_test.go @@ -219,12 +219,9 @@ func (suite *UpdateIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Python3", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + ts.PrepareEmptyProject() - cp = ts.Spawn("update", "lock", "-o", "json") + cp := ts.Spawn("update", "lock", "-o", "json") cp.Expect(`"channel":`) cp.Expect(`"version":`) cp.ExpectExitCode(0) diff --git a/test/integration/upgrade_int_test.go b/test/integration/upgrade_int_test.go new file mode 100644 index 0000000000..27b0eb66be --- /dev/null +++ b/test/integration/upgrade_int_test.go @@ -0,0 +1,70 @@ +package integration + +import ( + "testing" + + "github.com/ActiveState/cli/internal/testhelpers/e2e" + "github.com/ActiveState/cli/internal/testhelpers/suite" + "github.com/ActiveState/cli/internal/testhelpers/tagsuite" + "github.com/ActiveState/termtest" +) + +type UpgradeIntegrationTestSuite struct { + tagsuite.Suite +} + +func (suite *UpgradeIntegrationTestSuite) TestUpgrade() { + suite.OnlyRunForTags(tagsuite.Upgrade) + + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.PrepareProject("ActiveState-CLI-Testing/python-upgradeable", "d0e56f96-b956-4b0c-9c20-938d3e843ab9") + + commitBefore := ts.CommitID() + + // Normally you wouldn't specify the timestamp except for special use-cases, but tests work better if they're + // reproducible, not to mention faster if they can hit the cache. + time := "2024-08-23T18:35:55.818Z" + + cp := ts.Spawn("upgrade", "--ts", time) + cp.Expect("transitive dependencies touched") + cp.Expect("install these upgrades?") + cp.SendLine("y") + cp.Expect("Upgrade completed") + cp.ExpectExitCode(0) + + // The ordering of these is not guaranteed, so we get a bit creative here + snapshot := cp.Snapshot() + suite.Contains(snapshot, "pytest") + suite.Contains(snapshot, "requests") + suite.Contains(snapshot, "7.2.2 > 8.3.2") // old pytest version + suite.Contains(snapshot, "2.28.2 > 2.32.3") // old requests version + + suite.NotEqual(commitBefore, ts.CommitID()) +} + +func (suite *UpgradeIntegrationTestSuite) TestUpgradeJSON() { + suite.OnlyRunForTags(tagsuite.Upgrade) + + ts := e2e.New(suite.T(), false) + defer ts.Close() + + ts.PrepareProject("ActiveState-CLI-Testing/python-upgradeable", "d0e56f96-b956-4b0c-9c20-938d3e843ab9") + + commitBefore := ts.CommitID() + + cp := ts.SpawnWithOpts( + e2e.OptArgs("upgrade", "--output=json"), + e2e.OptTermTest(termtest.OptRows(500)), // Ensure json fits inside snapshot + ) + cp.ExpectExitCode(0) + + AssertValidJSON(suite.T(), cp) + + suite.NotEqual(commitBefore, ts.CommitID()) +} + +func TestUpgradeIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(UpgradeIntegrationTestSuite)) +} diff --git a/test/integration/use_int_test.go b/test/integration/use_int_test.go index 543071c8bc..d9b781eaab 100644 --- a/test/integration/use_int_test.go +++ b/test/integration/use_int_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/ActiveState/cli/internal/config" - "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/osutils" @@ -29,17 +28,13 @@ func (suite *UseIntegrationTestSuite) TestUse() { defer ts.Close() // Checkout. - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + cp := ts.Spawn("checkout", "ActiveState-CLI/Python3") + cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) // Use. - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "ActiveState-CLI/Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("use", "ActiveState-CLI/Python3") + cp.Expect("Switched to project") cp.ExpectExitCode(0) // Verify runtime works. @@ -49,17 +44,13 @@ func (suite *UseIntegrationTestSuite) TestUse() { cp.ExpectExitCode(0) // Checkout another project. - cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9")) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + cp = ts.Spawn("checkout", "ActiveState-CLI/Python-3.9") + cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) // Use it. - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "ActiveState-CLI/Python-3.9"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("use", "ActiveState-CLI/Python-3.9") + cp.Expect("Switched to project") cp.ExpectExitCode(0) // Verify the new runtime works. @@ -68,10 +59,7 @@ func (suite *UseIntegrationTestSuite) TestUse() { cp.ExpectExitCode(0) // Switch back using just the project name. - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp = ts.Spawn("use", "Python3") cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) @@ -81,7 +69,7 @@ func (suite *UseIntegrationTestSuite) TestUse() { cp.ExpectExitCode(0) // Test failure switching to project name that was not checked out. - cp = ts.SpawnWithOpts(e2e.OptArgs("use", "NotCheckedOut")) + cp = ts.Spawn("use", "NotCheckedOut") cp.Expect("Cannot find the NotCheckedOut project.") cp.ExpectExitCode(1) ts.IgnoreLogErrors() @@ -93,19 +81,17 @@ func (suite *UseIntegrationTestSuite) TestUseCwd() { ts := e2e.New(suite.T(), false) defer ts.Close() - pythonDir := filepath.Join(ts.Dirs.Work, "MyPython3") + projDir := filepath.Join(ts.Dirs.Work, "MyEmpty") - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3", pythonDir)) - cp.Expect("Skipping runtime setup") + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Empty", projDir)) cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( e2e.OptArgs("use"), - e2e.OptWD(pythonDir), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), + e2e.OptWD(projDir), ) - cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) + cp.Expect("Switched to project") cp.ExpectExitCode(0) emptyDir := filepath.Join(ts.Dirs.Work, "EmptyDir") @@ -127,16 +113,12 @@ func (suite *UseIntegrationTestSuite) TestReset() { ts.SetupRCFile() - cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out project") + cp := ts.Spawn("checkout", "ActiveState-CLI/Python3") + cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "ActiveState-CLI/Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("use", "ActiveState-CLI/Python3") + cp.Expect("Switched to project") cp.ExpectExitCode(0) python3Exe := filepath.Join(ts.Dirs.DefaultBin, "python3"+osutils.ExeExtension) @@ -150,21 +132,21 @@ func (suite *UseIntegrationTestSuite) TestReset() { suite.Contains(string(fileutils.ReadFileUnsafe(rcfile)), ts.Dirs.DefaultBin, "PATH does not have your project in it") } - cp = ts.SpawnWithOpts(e2e.OptArgs("use", "reset")) + cp = ts.Spawn("use", "reset") cp.Expect("Continue?") cp.SendLine("n") cp.Expect("Reset aborted by user") cp.ExpectExitCode(1) ts.IgnoreLogErrors() - cp = ts.SpawnWithOpts(e2e.OptArgs("use", "reset", "--non-interactive")) + cp = ts.Spawn("use", "reset", "--non-interactive") cp.Expect("Stopped using your project runtime") cp.Expect("Note you may need to") cp.ExpectExitCode(0) suite.False(fileutils.TargetExists(python3Exe), python3Exe+" still exists") - cp = ts.SpawnWithOpts(e2e.OptArgs("use", "reset")) + cp = ts.Spawn("use", "reset") cp.Expect("No project to stop using") cp.ExpectExitCode(1) @@ -179,28 +161,22 @@ func (suite *UseIntegrationTestSuite) TestShow() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.OptArgs("use", "show")) + cp := ts.Spawn("use", "show") cp.Expect("No project is being used") cp.ExpectExitCode(1) ts.IgnoreLogErrors() - cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) - cp.Expect("Skipping runtime setup") + cp = ts.Spawn("checkout", "ActiveState-CLI/Empty") cp.Expect("Checked out project") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "ActiveState-CLI/Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("use", "ActiveState-CLI/Empty") + cp.Expect("Switched to project") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "show"), - ) - cp.Expect("The active project is ActiveState-CLI/Python3") - projectDir := filepath.Join(ts.Dirs.Work, "Python3") + cp = ts.Spawn("use", "show") + cp.Expect("The active project is ActiveState-CLI/Empty") + projectDir := filepath.Join(ts.Dirs.Work, "Empty") if runtime.GOOS != "windows" { cp.Expect(projectDir) } else { @@ -216,7 +192,7 @@ func (suite *UseIntegrationTestSuite) TestShow() { err := os.RemoveAll(projectDir) suite.Require().NoError(err) - cp = ts.SpawnWithOpts(e2e.OptArgs("use", "show")) + cp = ts.Spawn("use", "show") cp.Expect("Cannot find your project") // Both Windows and MacOS can run into path comparison issues with symlinks and long paths. if runtime.GOOS == "linux" { @@ -224,11 +200,11 @@ func (suite *UseIntegrationTestSuite) TestShow() { } cp.ExpectExitCode(1) - cp = ts.SpawnWithOpts(e2e.OptArgs("use", "reset", "--non-interactive")) + cp = ts.Spawn("use", "reset", "--non-interactive") cp.Expect("Stopped using your project runtime") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.OptArgs("use", "show")) + cp = ts.Spawn("use", "show") cp.Expect("No project is being used") cp.ExpectExitCode(1) } @@ -239,29 +215,19 @@ func (suite *UseIntegrationTestSuite) TestSetupNotice() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty") cp.Expect(locale.T("install_runtime")) - cp.Expect("Checked out project", e2e.RuntimeSourcingTimeoutOpt) + cp.Expect("Checked out project") cp.ExpectExitCode(0) - suite.Require().NoError(os.RemoveAll(filepath.Join(ts.Dirs.Work, "Python3"))) // runtime marker still exists + suite.Require().NoError(os.RemoveAll(filepath.Join(ts.Dirs.Work, "Empty"))) // runtime marker still exists - cp = ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/Python3#623dadf8-ebf9-4876-bfde-f45afafe5ea8"), - ) - cp.Expect("Skipping runtime setup") + cp = ts.Spawn("checkout", "ActiveState-CLI/Empty#265f9914-ad4d-4e0a-a128-9d4e8c5db820") cp.Expect("Checked out project") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "Python3"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect("Setting Up Runtime") - cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("use", "Empty") + cp.Expect("Switched to project") cp.ExpectExitCode(0) } @@ -270,16 +236,12 @@ func (suite *UseIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("checkout", "ActiveState-CLI/Perl-5.32", ".") - cp.Expect("Skipping runtime setup") + cp := ts.Spawn("checkout", "ActiveState-CLI/Empty", ".") cp.Expect("Checked out") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts( - e2e.OptArgs("use", "-o", "json"), - e2e.OptAppendEnv(constants.DisableRuntime+"=false"), - ) - cp.Expect(`"namespace":`, e2e.RuntimeSourcingTimeoutOpt) + cp = ts.Spawn("use", "-o", "json") + cp.Expect(`"namespace":`) cp.Expect(`"path":`) cp.Expect(`"executables":`) cp.ExpectExitCode(0) diff --git a/vendor/github.com/99designs/gqlgen/complexity/complexity.go b/vendor/github.com/99designs/gqlgen/complexity/complexity.go index e3ecf7612d..288bb539b5 100644 --- a/vendor/github.com/99designs/gqlgen/complexity/complexity.go +++ b/vendor/github.com/99designs/gqlgen/complexity/complexity.go @@ -1,11 +1,12 @@ package complexity import ( - "github.com/99designs/gqlgen/graphql" "github.com/vektah/gqlparser/v2/ast" + + "github.com/99designs/gqlgen/graphql" ) -func Calculate(es graphql.ExecutableSchema, op *ast.OperationDefinition, vars map[string]interface{}) int { +func Calculate(es graphql.ExecutableSchema, op *ast.OperationDefinition, vars map[string]any) int { walker := complexityWalker{ es: es, schema: es.Schema(), @@ -17,7 +18,7 @@ func Calculate(es graphql.ExecutableSchema, op *ast.OperationDefinition, vars ma type complexityWalker struct { es graphql.ExecutableSchema schema *ast.Schema - vars map[string]interface{} + vars map[string]any } func (cw complexityWalker) selectionSetComplexity(selectionSet ast.SelectionSet) int { @@ -56,7 +57,7 @@ func (cw complexityWalker) selectionSetComplexity(selectionSet ast.SelectionSet) return complexity } -func (cw complexityWalker) interfaceFieldComplexity(def *ast.Definition, field string, childComplexity int, args map[string]interface{}) int { +func (cw complexityWalker) interfaceFieldComplexity(def *ast.Definition, field string, childComplexity int, args map[string]any) int { // Interfaces don't have their own separate field costs, so they have to assume the worst case. // We iterate over all implementors and choose the most expensive one. maxComplexity := 0 @@ -70,7 +71,7 @@ func (cw complexityWalker) interfaceFieldComplexity(def *ast.Definition, field s return maxComplexity } -func (cw complexityWalker) fieldComplexity(object, field string, childComplexity int, args map[string]interface{}) int { +func (cw complexityWalker) fieldComplexity(object, field string, childComplexity int, args map[string]any) int { if customComplexity, ok := cw.es.Complexity(object, field, childComplexity, args); ok && customComplexity >= childComplexity { return customComplexity } diff --git a/vendor/github.com/99designs/gqlgen/graphql/any.go b/vendor/github.com/99designs/gqlgen/graphql/any.go index 6ea8bf2eae..be600b2f42 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/any.go +++ b/vendor/github.com/99designs/gqlgen/graphql/any.go @@ -5,7 +5,7 @@ import ( "io" ) -func MarshalAny(v interface{}) Marshaler { +func MarshalAny(v any) Marshaler { return WriterFunc(func(w io.Writer) { err := json.NewEncoder(w).Encode(v) if err != nil { @@ -14,6 +14,6 @@ func MarshalAny(v interface{}) Marshaler { }) } -func UnmarshalAny(v interface{}) (interface{}, error) { +func UnmarshalAny(v any) (any, error) { return v, nil } diff --git a/vendor/github.com/99designs/gqlgen/graphql/bool.go b/vendor/github.com/99designs/gqlgen/graphql/bool.go index f435e0c098..d9797a38e9 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/bool.go +++ b/vendor/github.com/99designs/gqlgen/graphql/bool.go @@ -3,24 +3,25 @@ package graphql import ( "fmt" "io" + "strconv" "strings" ) func MarshalBoolean(b bool) Marshaler { - if b { - return WriterFunc(func(w io.Writer) { w.Write(trueLit) }) - } - return WriterFunc(func(w io.Writer) { w.Write(falseLit) }) + str := strconv.FormatBool(b) + return WriterFunc(func(w io.Writer) { w.Write([]byte(str)) }) } -func UnmarshalBoolean(v interface{}) (bool, error) { +func UnmarshalBoolean(v any) (bool, error) { switch v := v.(type) { case string: - return strings.ToLower(v) == "true", nil + return strings.EqualFold(v, "true"), nil case int: return v != 0, nil case bool: return v, nil + case nil: + return false, nil default: return false, fmt.Errorf("%T is not a bool", v) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/cache.go b/vendor/github.com/99designs/gqlgen/graphql/cache.go index fe86ca3502..8804cfe04f 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/cache.go +++ b/vendor/github.com/99designs/gqlgen/graphql/cache.go @@ -3,27 +3,29 @@ package graphql import "context" // Cache is a shared store for APQ and query AST caching -type Cache interface { +type Cache[T any] interface { // Get looks up a key's value from the cache. - Get(ctx context.Context, key string) (value interface{}, ok bool) + Get(ctx context.Context, key string) (value T, ok bool) // Add adds a value to the cache. - Add(ctx context.Context, key string, value interface{}) + Add(ctx context.Context, key string, value T) } // MapCache is the simplest implementation of a cache, because it can not evict it should only be used in tests -type MapCache map[string]interface{} +type MapCache[T any] map[string]T // Get looks up a key's value from the cache. -func (m MapCache) Get(ctx context.Context, key string) (value interface{}, ok bool) { +func (m MapCache[T]) Get(_ context.Context, key string) (value T, ok bool) { v, ok := m[key] return v, ok } // Add adds a value to the cache. -func (m MapCache) Add(ctx context.Context, key string, value interface{}) { m[key] = value } +func (m MapCache[T]) Add(_ context.Context, key string, value T) { m[key] = value } -type NoCache struct{} +type NoCache[T any, T2 *T] struct{} -func (n NoCache) Get(ctx context.Context, key string) (value interface{}, ok bool) { return nil, false } -func (n NoCache) Add(ctx context.Context, key string, value interface{}) {} +var _ Cache[*string] = (*NoCache[string, *string])(nil) + +func (n NoCache[T, T2]) Get(_ context.Context, _ string) (value T2, ok bool) { return nil, false } +func (n NoCache[T, T2]) Add(_ context.Context, _ string, _ T2) {} diff --git a/vendor/github.com/99designs/gqlgen/graphql/coercion.go b/vendor/github.com/99designs/gqlgen/graphql/coercion.go index d3d3c18b2b..533ab82149 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/coercion.go +++ b/vendor/github.com/99designs/gqlgen/graphql/coercion.go @@ -5,51 +5,51 @@ import ( ) // CoerceList applies coercion from a single value to a list. -func CoerceList(v interface{}) []interface{} { - var vSlice []interface{} +func CoerceList(v any) []any { + var vSlice []any if v != nil { switch v := v.(type) { - case []interface{}: + case []any: // already a slice no coercion required vSlice = v case []string: if len(v) > 0 { - vSlice = []interface{}{v[0]} + vSlice = []any{v[0]} } case []json.Number: if len(v) > 0 { - vSlice = []interface{}{v[0]} + vSlice = []any{v[0]} } case []bool: if len(v) > 0 { - vSlice = []interface{}{v[0]} + vSlice = []any{v[0]} } - case []map[string]interface{}: + case []map[string]any: if len(v) > 0 { - vSlice = []interface{}{v[0]} + vSlice = []any{v[0]} } case []float64: if len(v) > 0 { - vSlice = []interface{}{v[0]} + vSlice = []any{v[0]} } case []float32: if len(v) > 0 { - vSlice = []interface{}{v[0]} + vSlice = []any{v[0]} } case []int: if len(v) > 0 { - vSlice = []interface{}{v[0]} + vSlice = []any{v[0]} } case []int32: if len(v) > 0 { - vSlice = []interface{}{v[0]} + vSlice = []any{v[0]} } case []int64: if len(v) > 0 { - vSlice = []interface{}{v[0]} + vSlice = []any{v[0]} } default: - vSlice = []interface{}{v} + vSlice = []any{v} } } return vSlice diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_field.go b/vendor/github.com/99designs/gqlgen/graphql/context_field.go index 1f9a6e88db..b3fab91017 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/context_field.go +++ b/vendor/github.com/99designs/gqlgen/graphql/context_field.go @@ -19,13 +19,13 @@ type FieldContext struct { // The name of the type this field belongs to Object string // These are the args after processing, they can be mutated in middleware to change what the resolver will get. - Args map[string]interface{} + Args map[string]any // The raw field Field CollectedField // The index of array in path. Index *int // The result object of resolver - Result interface{} + Result any // IsMethod indicates if the resolver is a method IsMethod bool // IsResolver indicates if the field has a user-specified resolver @@ -98,7 +98,7 @@ func WithFieldContext(ctx context.Context, rc *FieldContext) context.Context { return context.WithValue(ctx, resolverCtx, rc) } -func equalPath(a ast.Path, b ast.Path) bool { +func equalPath(a, b ast.Path) bool { if len(a) != len(b) { return false } diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_operation.go b/vendor/github.com/99designs/gqlgen/graphql/context_operation.go index 0518ecc6ba..d515acce18 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/context_operation.go +++ b/vendor/github.com/99designs/gqlgen/graphql/context_operation.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/vektah/gqlparser/v2/ast" + "github.com/vektah/gqlparser/v2/gqlerror" ) // Deprecated: Please update all references to OperationContext instead @@ -13,7 +14,7 @@ type RequestContext = OperationContext type OperationContext struct { RawQuery string - Variables map[string]interface{} + Variables map[string]any OperationName string Doc *ast.QueryDocument Headers http.Header @@ -35,7 +36,7 @@ func (c *OperationContext) Validate(ctx context.Context) error { return errors.New("field 'RawQuery' is required") } if c.Variables == nil { - c.Variables = make(map[string]interface{}) + c.Variables = make(map[string]any) } if c.ResolverMiddleware == nil { return errors.New("field 'ResolverMiddleware' is required") @@ -72,8 +73,8 @@ func WithOperationContext(ctx context.Context, rc *OperationContext) context.Con // // Some errors can happen outside of an operation, eg json unmarshal errors. func HasOperationContext(ctx context.Context) bool { - _, ok := ctx.Value(operationCtx).(*OperationContext) - return ok + val, ok := ctx.Value(operationCtx).(*OperationContext) + return ok && val != nil } // This is just a convenient wrapper method for CollectFields @@ -102,16 +103,23 @@ Next: // Errorf sends an error string to the client, passing it through the formatter. // Deprecated: use graphql.AddErrorf(ctx, err) instead -func (c *OperationContext) Errorf(ctx context.Context, format string, args ...interface{}) { +func (c *OperationContext) Errorf(ctx context.Context, format string, args ...any) { AddErrorf(ctx, format, args...) } -// Error sends an error to the client, passing it through the formatter. -// Deprecated: use graphql.AddError(ctx, err) instead +// Error add error or multiple errors (if underlaying type is gqlerror.List) into the stack. +// Then it will be sends to the client, passing it through the formatter. func (c *OperationContext) Error(ctx context.Context, err error) { + if errList, ok := err.(gqlerror.List); ok { + for _, e := range errList { + AddError(ctx, e) + } + return + } + AddError(ctx, err) } -func (c *OperationContext) Recover(ctx context.Context, err interface{}) error { +func (c *OperationContext) Recover(ctx context.Context, err any) error { return ErrorOnPath(ctx, c.RecoverFunc(ctx, err)) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_path.go b/vendor/github.com/99designs/gqlgen/graphql/context_path.go index a46ed83ddc..bdb53e7a74 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/context_path.go +++ b/vendor/github.com/99designs/gqlgen/graphql/context_path.go @@ -34,7 +34,6 @@ func (fic *PathContext) Path() ast.Path { if fic.ParentField != nil { fieldPath := fic.ParentField.Path() return append(fieldPath, path...) - } return path diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_response.go b/vendor/github.com/99designs/gqlgen/graphql/context_response.go index c128fdb49c..e0f3285fb0 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/context_response.go +++ b/vendor/github.com/99designs/gqlgen/graphql/context_response.go @@ -15,7 +15,7 @@ type responseContext struct { errors gqlerror.List errorsMu sync.Mutex - extensions map[string]interface{} + extensions map[string]any extensionsMu sync.Mutex } @@ -36,8 +36,16 @@ func WithResponseContext(ctx context.Context, presenterFunc ErrorPresenterFunc, }) } +func WithFreshResponseContext(ctx context.Context) context.Context { + e := getResponseContext(ctx) + return context.WithValue(ctx, resultCtx, &responseContext{ + errorPresenter: e.errorPresenter, + recover: e.recover, + }) +} + // AddErrorf writes a formatted error to the client, first passing it through the error presenter. -func AddErrorf(ctx context.Context, format string, args ...interface{}) { +func AddErrorf(ctx context.Context, format string, args ...any) { AddError(ctx, fmt.Errorf(format, args...)) } @@ -52,7 +60,7 @@ func AddError(ctx context.Context, err error) { c.errors = append(c.errors, presentedError) } -func Recover(ctx context.Context, err interface{}) (userMessage error) { +func Recover(ctx context.Context, err any) (userMessage error) { c := getResponseContext(ctx) return ErrorOnPath(ctx, c.recover(ctx, err)) } @@ -117,13 +125,13 @@ func GetErrors(ctx context.Context) gqlerror.List { } // RegisterExtension allows you to add a new extension into the graphql response -func RegisterExtension(ctx context.Context, key string, value interface{}) { +func RegisterExtension(ctx context.Context, key string, value any) { c := getResponseContext(ctx) c.extensionsMu.Lock() defer c.extensionsMu.Unlock() if c.extensions == nil { - c.extensions = make(map[string]interface{}) + c.extensions = make(map[string]any) } if _, ok := c.extensions[key]; ok { @@ -134,16 +142,16 @@ func RegisterExtension(ctx context.Context, key string, value interface{}) { } // GetExtensions returns any extensions registered in the current result context -func GetExtensions(ctx context.Context) map[string]interface{} { +func GetExtensions(ctx context.Context) map[string]any { ext := getResponseContext(ctx).extensions if ext == nil { - return map[string]interface{}{} + return map[string]any{} } return ext } -func GetExtension(ctx context.Context, name string) interface{} { +func GetExtension(ctx context.Context, name string) any { ext := getResponseContext(ctx).extensions if ext == nil { return nil diff --git a/vendor/github.com/99designs/gqlgen/graphql/deferred.go b/vendor/github.com/99designs/gqlgen/graphql/deferred.go new file mode 100644 index 0000000000..1aeb48c180 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/deferred.go @@ -0,0 +1,26 @@ +package graphql + +import ( + "context" + + "github.com/vektah/gqlparser/v2/ast" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +type Deferrable struct { + Label string +} + +type DeferredGroup struct { + Path ast.Path + Label string + FieldSet *FieldSet + Context context.Context +} + +type DeferredResult struct { + Path ast.Path + Label string + Result Marshaler + Errors gqlerror.List +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/duration.go b/vendor/github.com/99designs/gqlgen/graphql/duration.go new file mode 100644 index 0000000000..bf2b564776 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/duration.go @@ -0,0 +1,27 @@ +package graphql + +import ( + "errors" + "time" + + dur "github.com/sosodev/duration" +) + +// UnmarshalDuration returns the duration from a string in ISO8601 format +func UnmarshalDuration(v any) (time.Duration, error) { + input, ok := v.(string) + if !ok { + return 0, errors.New("input must be a string") + } + + d2, err := dur.Parse(input) + if err != nil { + return 0, err + } + return d2.ToTimeDuration(), nil +} + +// MarshalDuration returns the duration on ISO8601 format +func MarshalDuration(d time.Duration) Marshaler { + return MarshalString(dur.Format(d)) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go b/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go index 854b206f4e..58ca7cbee7 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go +++ b/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go @@ -40,7 +40,7 @@ func Set(err error, value string) { } if gqlErr.Extensions == nil { - gqlErr.Extensions = map[string]interface{}{} + gqlErr.Extensions = map[string]any{} } gqlErr.Extensions["code"] = value diff --git a/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go b/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go index 541b65fbee..aa9d7c44c3 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go +++ b/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go @@ -12,7 +12,7 @@ import ( type ExecutableSchema interface { Schema() *ast.Schema - Complexity(typeName, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) + Complexity(typeName, fieldName string, childComplexity int, args map[string]any) (int, bool) Exec(ctx context.Context) ResponseHandler } @@ -45,9 +45,19 @@ func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies if len(satisfies) > 0 && !instanceOf(sel.TypeCondition, satisfies) { continue } + + shouldDefer, label := deferrable(sel.Directives, reqCtx.Variables) + for _, childField := range collectFields(reqCtx, sel.SelectionSet, satisfies, visited) { - f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField }) + f := getOrCreateAndAppendField( + &groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, + func() CollectedField { return childField }) f.Selections = append(f.Selections, childField.Selections...) + if shouldDefer { + f.Deferrable = &Deferrable{ + Label: label, + } + } } case *ast.FragmentSpread: @@ -70,9 +80,16 @@ func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies continue } + shouldDefer, label := deferrable(sel.Directives, reqCtx.Variables) + for _, childField := range collectFields(reqCtx, fragment.SelectionSet, satisfies, visited) { - f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField }) + f := getOrCreateAndAppendField(&groupedFields, + childField.Name, childField.Alias, childField.ObjectDefinition, + func() CollectedField { return childField }) f.Selections = append(f.Selections, childField.Selections...) + if shouldDefer { + f.Deferrable = &Deferrable{Label: label} + } } default: @@ -87,6 +104,7 @@ type CollectedField struct { *ast.Field Selections ast.SelectionSet + Deferrable *Deferrable } func instanceOf(val string, satisfies []string) bool { @@ -98,7 +116,7 @@ func instanceOf(val string, satisfies []string) bool { return false } -func getOrCreateAndAppendField(c *[]CollectedField, name string, alias string, objectDefinition *ast.Definition, creator func() CollectedField) *CollectedField { +func getOrCreateAndAppendField(c *[]CollectedField, name, alias string, objectDefinition *ast.Definition, creator func() CollectedField) *CollectedField { for i, cf := range *c { if cf.Name == name && cf.Alias == alias { if cf.ObjectDefinition == objectDefinition { @@ -118,6 +136,11 @@ func getOrCreateAndAppendField(c *[]CollectedField, name string, alias string, o return &(*c)[i] } } + for _, ifc := range cf.ObjectDefinition.Interfaces { + if ifc == objectDefinition.Name { + return &(*c)[i] + } + } } } @@ -127,7 +150,7 @@ func getOrCreateAndAppendField(c *[]CollectedField, name string, alias string, o return &(*c)[len(*c)-1] } -func shouldIncludeNode(directives ast.DirectiveList, variables map[string]interface{}) bool { +func shouldIncludeNode(directives ast.DirectiveList, variables map[string]any) bool { if len(directives) == 0 { return true } @@ -145,7 +168,33 @@ func shouldIncludeNode(directives ast.DirectiveList, variables map[string]interf return !skip && include } -func resolveIfArgument(d *ast.Directive, variables map[string]interface{}) bool { +func deferrable(directives ast.DirectiveList, variables map[string]any) (shouldDefer bool, label string) { + d := directives.ForName("defer") + if d == nil { + return false, "" + } + + shouldDefer = true + + for _, arg := range d.Arguments { + switch arg.Name { + case "if": + if value, err := arg.Value.Value(variables); err == nil { + shouldDefer, _ = value.(bool) + } + case "label": + if value, err := arg.Value.Value(variables); err == nil { + label, _ = value.(string) + } + default: + panic(fmt.Sprintf("defer: argument '%s' not supported", arg.Name)) + } + } + + return shouldDefer, label +} + +func resolveIfArgument(d *ast.Directive, variables map[string]any) bool { arg := d.Arguments.ForName("if") if arg == nil { panic(fmt.Sprintf("%s: argument 'if' not defined", d.Name)) diff --git a/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go b/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go index 5d7433162f..c4c4118975 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go +++ b/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go @@ -15,28 +15,28 @@ var _ ExecutableSchema = &ExecutableSchemaMock{} // ExecutableSchemaMock is a mock implementation of ExecutableSchema. // -// func TestSomethingThatUsesExecutableSchema(t *testing.T) { +// func TestSomethingThatUsesExecutableSchema(t *testing.T) { // -// // make and configure a mocked ExecutableSchema -// mockedExecutableSchema := &ExecutableSchemaMock{ -// ComplexityFunc: func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) { -// panic("mock out the Complexity method") -// }, -// ExecFunc: func(ctx context.Context) ResponseHandler { -// panic("mock out the Exec method") -// }, -// SchemaFunc: func() *ast.Schema { -// panic("mock out the Schema method") -// }, -// } +// // make and configure a mocked ExecutableSchema +// mockedExecutableSchema := &ExecutableSchemaMock{ +// ComplexityFunc: func(typeName string, fieldName string, childComplexity int, args map[string]any) (int, bool) { +// panic("mock out the Complexity method") +// }, +// ExecFunc: func(ctx context.Context) ResponseHandler { +// panic("mock out the Exec method") +// }, +// SchemaFunc: func() *ast.Schema { +// panic("mock out the Schema method") +// }, +// } // -// // use mockedExecutableSchema in code that requires ExecutableSchema -// // and then make assertions. +// // use mockedExecutableSchema in code that requires ExecutableSchema +// // and then make assertions. // -// } +// } type ExecutableSchemaMock struct { // ComplexityFunc mocks the Complexity method. - ComplexityFunc func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) + ComplexityFunc func(typeName string, fieldName string, childComplexity int, args map[string]any) (int, bool) // ExecFunc mocks the Exec method. ExecFunc func(ctx context.Context) ResponseHandler @@ -55,7 +55,7 @@ type ExecutableSchemaMock struct { // ChildComplexity is the childComplexity argument value. ChildComplexity int // Args is the args argument value. - Args map[string]interface{} + Args map[string]any } // Exec holds details about calls to the Exec method. Exec []struct { @@ -72,7 +72,7 @@ type ExecutableSchemaMock struct { } // Complexity calls ComplexityFunc. -func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) { +func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string, childComplexity int, args map[string]any) (int, bool) { if mock.ComplexityFunc == nil { panic("ExecutableSchemaMock.ComplexityFunc: method is nil but ExecutableSchema.Complexity was just called") } @@ -80,7 +80,7 @@ func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string, TypeName string FieldName string ChildComplexity int - Args map[string]interface{} + Args map[string]any }{ TypeName: typeName, FieldName: fieldName, @@ -95,18 +95,19 @@ func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string, // ComplexityCalls gets all the calls that were made to Complexity. // Check the length with: -// len(mockedExecutableSchema.ComplexityCalls()) +// +// len(mockedExecutableSchema.ComplexityCalls()) func (mock *ExecutableSchemaMock) ComplexityCalls() []struct { TypeName string FieldName string ChildComplexity int - Args map[string]interface{} + Args map[string]any } { var calls []struct { TypeName string FieldName string ChildComplexity int - Args map[string]interface{} + Args map[string]any } mock.lockComplexity.RLock() calls = mock.calls.Complexity @@ -132,7 +133,8 @@ func (mock *ExecutableSchemaMock) Exec(ctx context.Context) ResponseHandler { // ExecCalls gets all the calls that were made to Exec. // Check the length with: -// len(mockedExecutableSchema.ExecCalls()) +// +// len(mockedExecutableSchema.ExecCalls()) func (mock *ExecutableSchemaMock) ExecCalls() []struct { Ctx context.Context } { @@ -160,7 +162,8 @@ func (mock *ExecutableSchemaMock) Schema() *ast.Schema { // SchemaCalls gets all the calls that were made to Schema. // Check the length with: -// len(mockedExecutableSchema.SchemaCalls()) +// +// len(mockedExecutableSchema.SchemaCalls()) func (mock *ExecutableSchemaMock) SchemaCalls() []struct { } { var calls []struct { diff --git a/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go b/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go index c46a007b99..566b04763e 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go +++ b/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go @@ -3,14 +3,17 @@ package executor import ( "context" - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/errcode" "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/gqlerror" "github.com/vektah/gqlparser/v2/parser" "github.com/vektah/gqlparser/v2/validator" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/errcode" ) +const parserTokenNoLimit = 0 + // Executor executes graphql queries against a schema. type Executor struct { es graphql.ExecutableSchema @@ -19,7 +22,9 @@ type Executor struct { errorPresenter graphql.ErrorPresenterFunc recoverFunc graphql.RecoverFunc - queryCache graphql.Cache + queryCache graphql.Cache[*ast.QueryDocument] + + parserTokenLimit int } var _ graphql.GraphExecutor = &Executor{} @@ -28,11 +33,12 @@ var _ graphql.GraphExecutor = &Executor{} // recovery callbacks, and no query cache or extensions. func New(es graphql.ExecutableSchema) *Executor { e := &Executor{ - es: es, - errorPresenter: graphql.DefaultErrorPresenter, - recoverFunc: graphql.DefaultRecover, - queryCache: graphql.NoCache{}, - ext: processExtensions(nil), + es: es, + errorPresenter: graphql.DefaultErrorPresenter, + recoverFunc: graphql.DefaultRecover, + queryCache: graphql.NoCache[ast.QueryDocument, *ast.QueryDocument]{}, + ext: processExtensions(nil), + parserTokenLimit: parserTokenNoLimit, } return e } @@ -78,7 +84,6 @@ func (e *Executor) CreateOperationContext( var err error rc.Variables, err = validator.VariableValues(e.es.Schema(), rc.Operation, params.Variables) - if err != nil { gqlErr, ok := err.(*gqlerror.Error) if ok { @@ -152,11 +157,11 @@ func (e *Executor) DispatchError(ctx context.Context, list gqlerror.List) *graph return resp } -func (e *Executor) PresentRecoveredError(ctx context.Context, err interface{}) error { +func (e *Executor) PresentRecoveredError(ctx context.Context, err any) error { return e.errorPresenter(ctx, e.recoverFunc(ctx, err)) } -func (e *Executor) SetQueryCache(cache graphql.Cache) { +func (e *Executor) SetQueryCache(cache graphql.Cache[*ast.QueryDocument]) { e.queryCache = cache } @@ -168,6 +173,10 @@ func (e *Executor) SetRecoverFunc(f graphql.RecoverFunc) { e.recoverFunc = f } +func (e *Executor) SetParserTokenLimit(limit int) { + e.parserTokenLimit = limit +} + // parseQuery decodes the incoming query and validates it, pulling from cache if present. // // NOTE: This should NOT look at variables, they will change per request. It should only parse and @@ -185,10 +194,10 @@ func (e *Executor) parseQuery( stats.Parsing.End = now stats.Validation.Start = now - return doc.(*ast.QueryDocument), nil + return doc, nil } - doc, err := parser.ParseQuery(&ast.Source{Input: query}) + doc, err := parser.ParseQueryWithTokenLimit(&ast.Source{Input: query}, e.parserTokenLimit) if err != nil { gqlErr, ok := err.(*gqlerror.Error) if ok { diff --git a/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go b/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go index a8eebf110c..758d8e4ec8 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go +++ b/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go @@ -2,6 +2,7 @@ package executor import ( "context" + "errors" "fmt" "github.com/99designs/gqlgen/graphql" @@ -68,7 +69,7 @@ func processExtensions(exts []graphql.HandlerExtension) extensions { rootFieldMiddleware: func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { return next(ctx) }, - fieldMiddleware: func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + fieldMiddleware: func(ctx context.Context, next graphql.Resolver) (res any, err error) { return next(ctx) }, } @@ -105,8 +106,8 @@ func processExtensions(exts []graphql.HandlerExtension) extensions { if p, ok := p.(graphql.FieldInterceptor); ok { previous := e.fieldMiddleware - e.fieldMiddleware = func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - return p.InterceptField(ctx, func(ctx context.Context) (res interface{}, err error) { + e.fieldMiddleware = func(ctx context.Context, next graphql.Resolver) (res any, err error) { + return p.InterceptField(ctx, func(ctx context.Context) (res any, err error) { return previous(ctx, next) }) } @@ -134,7 +135,7 @@ func (r aroundOpFunc) ExtensionName() string { func (r aroundOpFunc) Validate(schema graphql.ExecutableSchema) error { if r == nil { - return fmt.Errorf("OperationFunc can not be nil") + return errors.New("OperationFunc can not be nil") } return nil } @@ -151,7 +152,7 @@ func (r aroundRespFunc) ExtensionName() string { func (r aroundRespFunc) Validate(schema graphql.ExecutableSchema) error { if r == nil { - return fmt.Errorf("ResponseFunc can not be nil") + return errors.New("ResponseFunc can not be nil") } return nil } @@ -160,7 +161,7 @@ func (r aroundRespFunc) InterceptResponse(ctx context.Context, next graphql.Resp return r(ctx, next) } -type aroundFieldFunc func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) +type aroundFieldFunc func(ctx context.Context, next graphql.Resolver) (res any, err error) func (f aroundFieldFunc) ExtensionName() string { return "InlineFieldFunc" @@ -168,12 +169,12 @@ func (f aroundFieldFunc) ExtensionName() string { func (f aroundFieldFunc) Validate(schema graphql.ExecutableSchema) error { if f == nil { - return fmt.Errorf("FieldFunc can not be nil") + return errors.New("FieldFunc can not be nil") } return nil } -func (f aroundFieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { +func (f aroundFieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res any, err error) { return f(ctx, next) } @@ -185,7 +186,7 @@ func (f aroundRootFieldFunc) ExtensionName() string { func (f aroundRootFieldFunc) Validate(schema graphql.ExecutableSchema) error { if f == nil { - return fmt.Errorf("RootFieldFunc can not be nil") + return errors.New("RootFieldFunc can not be nil") } return nil } diff --git a/vendor/github.com/99designs/gqlgen/graphql/fieldset.go b/vendor/github.com/99designs/gqlgen/graphql/fieldset.go index 351e266fdb..2c9e3dc932 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/fieldset.go +++ b/vendor/github.com/99designs/gqlgen/graphql/fieldset.go @@ -1,19 +1,21 @@ package graphql import ( + "context" "io" "sync" ) type FieldSet struct { - fields []CollectedField - Values []Marshaler - delayed []delayedResult + fields []CollectedField + Values []Marshaler + Invalids uint32 + delayed []delayedResult } type delayedResult struct { i int - f func() Marshaler + f func(context.Context) Marshaler } func NewFieldSet(fields []CollectedField) *FieldSet { @@ -23,15 +25,20 @@ func NewFieldSet(fields []CollectedField) *FieldSet { } } -func (m *FieldSet) Concurrently(i int, f func() Marshaler) { +func (m *FieldSet) AddField(field CollectedField) { + m.fields = append(m.fields, field) + m.Values = append(m.Values, nil) +} + +func (m *FieldSet) Concurrently(i int, f func(context.Context) Marshaler) { m.delayed = append(m.delayed, delayedResult{i: i, f: f}) } -func (m *FieldSet) Dispatch() { +func (m *FieldSet) Dispatch(ctx context.Context) { if len(m.delayed) == 1 { // only one concurrent task, no need to spawn a goroutine or deal create waitgroups d := m.delayed[0] - m.Values[d.i] = d.f() + m.Values[d.i] = d.f(ctx) } else if len(m.delayed) > 1 { // more than one concurrent task, use the main goroutine to do one, only spawn goroutines for the others @@ -39,12 +46,12 @@ func (m *FieldSet) Dispatch() { for _, d := range m.delayed[1:] { wg.Add(1) go func(d delayedResult) { - m.Values[d.i] = d.f() - wg.Done() + defer wg.Done() + m.Values[d.i] = d.f(ctx) }(d) } - m.Values[m.delayed[0].i] = m.delayed[0].f() + m.Values[m.delayed[0].i] = m.delayed[0].f(ctx) wg.Wait() } } diff --git a/vendor/github.com/99designs/gqlgen/graphql/float.go b/vendor/github.com/99designs/gqlgen/graphql/float.go index ccb825ddb8..b140d5bc74 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/float.go +++ b/vendor/github.com/99designs/gqlgen/graphql/float.go @@ -3,6 +3,7 @@ package graphql import ( "context" "encoding/json" + "errors" "fmt" "io" "math" @@ -11,11 +12,11 @@ import ( func MarshalFloat(f float64) Marshaler { return WriterFunc(func(w io.Writer) { - io.WriteString(w, fmt.Sprintf("%g", f)) + fmt.Fprintf(w, "%g", f) }) } -func UnmarshalFloat(v interface{}) (float64, error) { +func UnmarshalFloat(v any) (float64, error) { switch v := v.(type) { case string: return strconv.ParseFloat(v, 64) @@ -27,6 +28,8 @@ func UnmarshalFloat(v interface{}) (float64, error) { return v, nil case json.Number: return strconv.ParseFloat(string(v), 64) + case nil: + return 0, nil default: return 0, fmt.Errorf("%T is not an float", v) } @@ -35,13 +38,13 @@ func UnmarshalFloat(v interface{}) (float64, error) { func MarshalFloatContext(f float64) ContextMarshaler { return ContextWriterFunc(func(ctx context.Context, w io.Writer) error { if math.IsInf(f, 0) || math.IsNaN(f) { - return fmt.Errorf("cannot marshal infinite no NaN float values") + return errors.New("cannot marshal infinite no NaN float values") } - io.WriteString(w, fmt.Sprintf("%g", f)) + fmt.Fprintf(w, "%g", f) return nil }) } -func UnmarshalFloatContext(ctx context.Context, v interface{}) (float64, error) { +func UnmarshalFloatContext(ctx context.Context, v any) (float64, error) { return UnmarshalFloat(v) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler.go b/vendor/github.com/99designs/gqlgen/graphql/handler.go index b76381f43e..4df36117b8 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler.go @@ -16,18 +16,18 @@ type ( ResponseHandler func(ctx context.Context) *Response ResponseMiddleware func(ctx context.Context, next ResponseHandler) *Response - Resolver func(ctx context.Context) (res interface{}, err error) - FieldMiddleware func(ctx context.Context, next Resolver) (res interface{}, err error) + Resolver func(ctx context.Context) (res any, err error) + FieldMiddleware func(ctx context.Context, next Resolver) (res any, err error) RootResolver func(ctx context.Context) Marshaler RootFieldMiddleware func(ctx context.Context, next RootResolver) Marshaler RawParams struct { - Query string `json:"query"` - OperationName string `json:"operationName"` - Variables map[string]interface{} `json:"variables"` - Extensions map[string]interface{} `json:"extensions"` - Headers http.Header `json:"headers"` + Query string `json:"query"` + OperationName string `json:"operationName"` + Variables map[string]any `json:"variables"` + Extensions map[string]any `json:"extensions"` + Headers http.Header `json:"headers"` ReadTime TraceTiming `json:"-"` } @@ -42,14 +42,14 @@ type ( // Its important to understand the lifecycle of a graphql request and the terminology we use in gqlgen // before working with these // - // +--- REQUEST POST /graphql --------------------------------------------+ - // | +- OPERATION query OpName { viewer { name } } -----------------------+ | - // | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | | - // | +- OPERATION subscription OpName2 { chat { message } } --------------+ | - // | | RESPONSE { "data": { "chat": { "message": "hello" } } } | | - // | | RESPONSE { "data": { "chat": { "message": "byee" } } } | | - // | +--------------------------------------------------------------------+ | - // +------------------------------------------------------------------------+ + // +--- REQUEST POST /graphql --------------------------------------------+ + // | +- OPERATION query OpName { viewer { name } } -----------------------+ | + // | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | | + // | +- OPERATION subscription OpName2 { chat { message } } --------------+ | + // | | RESPONSE { "data": { "chat": { "message": "hello" } } } | | + // | | RESPONSE { "data": { "chat": { "message": "byee" } } } | | + // | +--------------------------------------------------------------------+ | + // +------------------------------------------------------------------------+ HandlerExtension interface { // ExtensionName should be a CamelCase string version of the extension which may be shown in stats and logging. ExtensionName() string @@ -86,7 +86,7 @@ type ( // FieldInterceptor called around each field FieldInterceptor interface { - InterceptField(ctx context.Context, next Resolver) (res interface{}, err error) + InterceptField(ctx context.Context, next Resolver) (res any, err error) } // Transport provides support for different wire level encodings of graphql requests, eg Form, Get, Post, Websocket @@ -103,7 +103,7 @@ func (p *RawParams) AddUpload(upload Upload, key, path string) *gqlerror.Error { return gqlerror.Errorf("invalid operations paths for key %s", key) } - var ptr interface{} = p.Variables + var ptr any = p.Variables parts := strings.Split(path, ".") // skip the first part (variables) because we started there @@ -114,15 +114,15 @@ func (p *RawParams) AddUpload(upload Upload, key, path string) *gqlerror.Error { } if index, parseNbrErr := strconv.Atoi(p); parseNbrErr == nil { if last { - ptr.([]interface{})[index] = upload + ptr.([]any)[index] = upload } else { - ptr = ptr.([]interface{})[index] + ptr = ptr.([]any)[index] } } else { if last { - ptr.(map[string]interface{})[p] = upload + ptr.(map[string]any)[p] = upload } else { - ptr = ptr.(map[string]interface{})[p] + ptr = ptr.(map[string]any)[p] } } } diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go index 866276eed9..a4cb32c955 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go @@ -4,14 +4,13 @@ import ( "context" "crypto/sha256" "encoding/hex" - "fmt" - - "github.com/99designs/gqlgen/graphql/errcode" + "errors" + "github.com/mitchellh/mapstructure" "github.com/vektah/gqlparser/v2/gqlerror" "github.com/99designs/gqlgen/graphql" - "github.com/mitchellh/mapstructure" + "github.com/99designs/gqlgen/graphql/errcode" ) const ( @@ -24,7 +23,7 @@ const ( // hash in the next request. // see https://github.com/apollographql/apollo-link-persisted-queries type AutomaticPersistedQuery struct { - Cache graphql.Cache + Cache graphql.Cache[string] } type ApqStats struct { @@ -48,7 +47,7 @@ func (a AutomaticPersistedQuery) ExtensionName() string { func (a AutomaticPersistedQuery) Validate(schema graphql.ExecutableSchema) error { if a.Cache == nil { - return fmt.Errorf("AutomaticPersistedQuery.Cache can not be nil") + return errors.New("AutomaticPersistedQuery.Cache can not be nil") } return nil } @@ -73,14 +72,14 @@ func (a AutomaticPersistedQuery) MutateOperationParameters(ctx context.Context, fullQuery := false if rawParams.Query == "" { + var ok bool // client sent optimistic query hash without query string, get it from the cache - query, ok := a.Cache.Get(ctx, extension.Sha256) + rawParams.Query, ok = a.Cache.Get(ctx, extension.Sha256) if !ok { err := gqlerror.Errorf(errPersistedQueryNotFound) errcode.Set(err, errPersistedQueryNotFoundCode) return err } - rawParams.Query = query.(string) } else { // client sent optimistic query hash with query string, verify and store it if computeQueryHash(rawParams.Query) != extension.Sha256 { diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go index 2d853802bf..af1e002fc1 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go @@ -2,12 +2,13 @@ package extension import ( "context" - "fmt" + "errors" + + "github.com/vektah/gqlparser/v2/gqlerror" "github.com/99designs/gqlgen/complexity" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/errcode" - "github.com/vektah/gqlparser/v2/gqlerror" ) const errComplexityLimit = "COMPLEXITY_LIMIT_EXCEEDED" @@ -51,7 +52,7 @@ func (c ComplexityLimit) ExtensionName() string { func (c *ComplexityLimit) Validate(schema graphql.ExecutableSchema) error { if c.Func == nil { - return fmt.Errorf("ComplexityLimit func can not be nil") + return errors.New("ComplexityLimit func can not be nil") } c.es = schema return nil @@ -59,17 +60,17 @@ func (c *ComplexityLimit) Validate(schema graphql.ExecutableSchema) error { func (c ComplexityLimit) MutateOperationContext(ctx context.Context, rc *graphql.OperationContext) *gqlerror.Error { op := rc.Doc.Operations.ForName(rc.OperationName) - complexity := complexity.Calculate(c.es, op, rc.Variables) + complexityCalcs := complexity.Calculate(c.es, op, rc.Variables) limit := c.Func(ctx, rc) rc.Stats.SetExtension(complexityExtension, &ComplexityStats{ - Complexity: complexity, + Complexity: complexityCalcs, ComplexityLimit: limit, }) - if complexity > limit { - err := gqlerror.Errorf("operation has complexity %d, which exceeds the limit of %d", complexity, limit) + if complexityCalcs > limit { + err := gqlerror.Errorf("operation has complexity %d, which exceeds the limit of %d", complexityCalcs, limit) errcode.Set(err, errComplexityLimit) return err } diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go index acc5db2fbc..8e3912651d 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go @@ -3,8 +3,9 @@ package extension import ( "context" - "github.com/99designs/gqlgen/graphql" "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/99designs/gqlgen/graphql" ) // EnableIntrospection enables clients to reflect all of the types available on the graph. diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go b/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go index e2b1561acb..946022bfeb 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go @@ -3,30 +3,31 @@ package lru import ( "context" + lru "github.com/hashicorp/golang-lru/v2" + "github.com/99designs/gqlgen/graphql" - lru "github.com/hashicorp/golang-lru" ) -type LRU struct { - lru *lru.Cache +type LRU[T any] struct { + lru *lru.Cache[string, T] } -var _ graphql.Cache = &LRU{} +var _ graphql.Cache[any] = &LRU[any]{} -func New(size int) *LRU { - cache, err := lru.New(size) +func New[T any](size int) *LRU[T] { + cache, err := lru.New[string, T](size) if err != nil { // An error is only returned for non-positive cache size // and we already checked for that. panic("unexpected error creating cache: " + err.Error()) } - return &LRU{cache} + return &LRU[T]{cache} } -func (l LRU) Get(ctx context.Context, key string) (value interface{}, ok bool) { +func (l LRU[T]) Get(ctx context.Context, key string) (value T, ok bool) { return l.lru.Get(key) } -func (l LRU) Add(ctx context.Context, key string, value interface{}) { +func (l LRU[T]) Add(ctx context.Context, key string, value T) { l.lru.Add(key, value) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/server.go b/vendor/github.com/99designs/gqlgen/graphql/handler/server.go index b6524d8da1..644bad8d99 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/server.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/server.go @@ -3,16 +3,19 @@ package handler import ( "context" "encoding/json" + "errors" "fmt" "net/http" "time" + "github.com/vektah/gqlparser/v2/ast" + "github.com/vektah/gqlparser/v2/gqlerror" + "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/executor" "github.com/99designs/gqlgen/graphql/handler/extension" "github.com/99designs/gqlgen/graphql/handler/lru" "github.com/99designs/gqlgen/graphql/handler/transport" - "github.com/vektah/gqlparser/v2/gqlerror" ) type ( @@ -39,11 +42,11 @@ func NewDefaultServer(es graphql.ExecutableSchema) *Server { srv.AddTransport(transport.POST{}) srv.AddTransport(transport.MultipartForm{}) - srv.SetQueryCache(lru.New(1000)) + srv.SetQueryCache(lru.New[*ast.QueryDocument](1000)) srv.Use(extension.Introspection{}) srv.Use(extension.AutomaticPersistedQuery{ - Cache: lru.New(100), + Cache: lru.New[string](100), }) return srv @@ -61,10 +64,14 @@ func (s *Server) SetRecoverFunc(f graphql.RecoverFunc) { s.exec.SetRecoverFunc(f) } -func (s *Server) SetQueryCache(cache graphql.Cache) { +func (s *Server) SetQueryCache(cache graphql.Cache[*ast.QueryDocument]) { s.exec.SetQueryCache(cache) } +func (s *Server) SetParserTokenLimit(limit int) { + s.exec.SetParserTokenLimit(limit) +} + func (s *Server) Use(extension graphql.HandlerExtension) { s.exec.Use(extension) } @@ -106,7 +113,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { resp := &graphql.Response{Errors: []*gqlerror.Error{gqlErr}} b, _ := json.Marshal(resp) w.WriteHeader(http.StatusUnprocessableEntity) - w.Write(b) + _, _ = w.Write(b) } }() @@ -127,10 +134,10 @@ func sendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) { if err != nil { panic(err) } - w.Write(b) + _, _ = w.Write(b) } -func sendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) { +func sendErrorf(w http.ResponseWriter, code int, format string, args ...any) { sendError(w, code, &gqlerror.Error{Message: fmt.Sprintf(format, args...)}) } @@ -142,7 +149,7 @@ func (r OperationFunc) ExtensionName() string { func (r OperationFunc) Validate(schema graphql.ExecutableSchema) error { if r == nil { - return fmt.Errorf("OperationFunc can not be nil") + return errors.New("OperationFunc can not be nil") } return nil } @@ -159,7 +166,7 @@ func (r ResponseFunc) ExtensionName() string { func (r ResponseFunc) Validate(schema graphql.ExecutableSchema) error { if r == nil { - return fmt.Errorf("ResponseFunc can not be nil") + return errors.New("ResponseFunc can not be nil") } return nil } @@ -168,7 +175,7 @@ func (r ResponseFunc) InterceptResponse(ctx context.Context, next graphql.Respon return r(ctx, next) } -type FieldFunc func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) +type FieldFunc func(ctx context.Context, next graphql.Resolver) (res any, err error) func (f FieldFunc) ExtensionName() string { return "InlineFieldFunc" @@ -176,11 +183,11 @@ func (f FieldFunc) ExtensionName() string { func (f FieldFunc) Validate(schema graphql.ExecutableSchema) error { if f == nil { - return fmt.Errorf("FieldFunc can not be nil") + return errors.New("FieldFunc can not be nil") } return nil } -func (f FieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { +func (f FieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res any, err error) { return f(ctx, next) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go index b1aeaf144d..1fefb5738c 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go @@ -5,8 +5,9 @@ import ( "fmt" "net/http" - "github.com/99designs/gqlgen/graphql" "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/99designs/gqlgen/graphql" ) // SendError sends a best effort error to a raw response writer. It assumes the client can understand the standard @@ -17,10 +18,10 @@ func SendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) { if err != nil { panic(err) } - w.Write(b) + _, _ = w.Write(b) } // SendErrorf wraps SendError to add formatted messages -func SendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) { +func SendErrorf(w http.ResponseWriter, code int, format string, args ...any) { SendError(w, code, &gqlerror.Error{Message: fmt.Sprintf(format, args...)}) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/headers.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/headers.go new file mode 100644 index 0000000000..bc4e572444 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/headers.go @@ -0,0 +1,17 @@ +package transport + +import "net/http" + +func writeHeaders(w http.ResponseWriter, headers map[string][]string) { + if len(headers) == 0 { + headers = map[string][]string{ + "Content-Type": {"application/json"}, + } + } + + for key, values := range headers { + for _, value := range values { + w.Header().Add(key, value) + } + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form_multipart.go similarity index 96% rename from vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go rename to vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form_multipart.go index 3d3477b9ba..b9eb5f8f43 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form_multipart.go @@ -20,6 +20,10 @@ type MultipartForm struct { // as multipart/form-data in memory, with the remainder stored on disk in // temporary files. MaxMemory int64 + + // Map of all headers that are added to graphql response. If not + // set, only one header: Content-Type: application/json will be set. + ResponseHeaders map[string][]string } var _ graphql.Transport = MultipartForm{} @@ -52,7 +56,7 @@ func (f MultipartForm) maxMemory() int64 { } func (f MultipartForm) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { - w.Header().Set("Content-Type", "application/json") + writeHeaders(w, f.ResponseHeaders) start := graphql.Now() diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form_urlencoded.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form_urlencoded.go new file mode 100644 index 0000000000..f877c2dd26 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form_urlencoded.go @@ -0,0 +1,119 @@ +package transport + +import ( + "io" + "mime" + "net/http" + "net/url" + "strings" + + "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/99designs/gqlgen/graphql" +) + +// FORM implements the application/x-www-form-urlencoded side of the default HTTP transport +type UrlEncodedForm struct { + // Map of all headers that are added to graphql response. If not + // set, only one header: Content-Type: application/json will be set. + ResponseHeaders map[string][]string +} + +var _ graphql.Transport = UrlEncodedForm{} + +func (h UrlEncodedForm) Supports(r *http.Request) bool { + if r.Header.Get("Upgrade") != "" { + return false + } + + mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return false + } + + return r.Method == "POST" && mediaType == "application/x-www-form-urlencoded" +} + +func (h UrlEncodedForm) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + ctx := r.Context() + writeHeaders(w, h.ResponseHeaders) + params := &graphql.RawParams{} + start := graphql.Now() + params.Headers = r.Header + params.ReadTime = graphql.TraceTiming{ + Start: start, + End: graphql.Now(), + } + + bodyString, err := getRequestBody(r) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + gqlErr := gqlerror.Errorf("could not get form body: %+v", err) + resp := exec.DispatchError(ctx, gqlerror.List{gqlErr}) + writeJson(w, resp) + return + } + + params, err = h.parseBody(bodyString) + if err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + gqlErr := gqlerror.Errorf("could not cleanup body: %+v", err) + resp := exec.DispatchError(ctx, gqlerror.List{gqlErr}) + writeJson(w, resp) + return + } + + rc, opErr := exec.CreateOperationContext(ctx, params) + if opErr != nil { + w.WriteHeader(statusFor(opErr)) + resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), opErr) + writeJson(w, resp) + return + } + + var responses graphql.ResponseHandler + responses, ctx = exec.DispatchOperation(ctx, rc) + writeJson(w, responses(ctx)) +} + +func (h UrlEncodedForm) parseBody(bodyString string) (*graphql.RawParams, error) { + switch { + case strings.Contains(bodyString, "\"query\":"): + // body is json + return h.parseJson(bodyString) + case strings.HasPrefix(bodyString, "query=%7B"): + // body is urlencoded + return h.parseEncoded(bodyString) + default: + // body is plain text + params := &graphql.RawParams{} + params.Query = strings.TrimPrefix(bodyString, "query=") + + return params, nil + } +} + +func (h UrlEncodedForm) parseEncoded(bodyString string) (*graphql.RawParams, error) { + params := &graphql.RawParams{} + + query, err := url.QueryUnescape(bodyString) + if err != nil { + return nil, err + } + + params.Query = strings.TrimPrefix(query, "query=") + + return params, nil +} + +func (h UrlEncodedForm) parseJson(bodyString string) (*graphql.RawParams, error) { + params := &graphql.RawParams{} + bodyReader := io.NopCloser(strings.NewReader(bodyString)) + + err := jsonDecode(bodyReader, ¶ms) + if err != nil { + return nil, err + } + + return params, nil +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go index 8114ba66a3..470a0fbec2 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go @@ -7,15 +7,20 @@ import ( "net/url" "strings" - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/errcode" "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/errcode" ) // GET implements the GET side of the default HTTP transport // defined in https://github.com/APIs-guru/graphql-over-http#get -type GET struct{} +type GET struct { + // Map of all headers that are added to graphql response. If not + // set, only one header: Content-Type: application/json will be set. + ResponseHeaders map[string][]string +} var _ graphql.Transport = GET{} @@ -34,7 +39,7 @@ func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecut writeJsonError(w, err.Error()) return } - w.Header().Set("Content-Type", "application/json") + writeHeaders(w, h.ResponseHeaders) raw := &graphql.RawParams{ Query: query.Get("query"), @@ -79,7 +84,7 @@ func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecut writeJson(w, responses(ctx)) } -func jsonDecode(r io.Reader, val interface{}) error { +func jsonDecode(r io.Reader, val any) error { dec := json.NewDecoder(r) dec.UseNumber() return dec.Decode(val) diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_graphql.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_graphql.go new file mode 100644 index 0000000000..0bad1110de --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_graphql.go @@ -0,0 +1,97 @@ +package transport + +import ( + "mime" + "net/http" + "net/url" + "strings" + + "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/99designs/gqlgen/graphql" +) + +// GRAPHQL implements the application/graphql side of the HTTP transport +// see: https://graphql.org/learn/serving-over-http/#post-request +// If the "application/graphql" Content-Type header is present, treat +// the HTTP POST body contents as the GraphQL query string. +type GRAPHQL struct { + // Map of all headers that are added to graphql response. If not + // set, only one header: Content-Type: application/json will be set. + ResponseHeaders map[string][]string +} + +var _ graphql.Transport = GRAPHQL{} + +func (h GRAPHQL) Supports(r *http.Request) bool { + if r.Header.Get("Upgrade") != "" { + return false + } + + mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return false + } + + return r.Method == "POST" && mediaType == "application/graphql" +} + +func (h GRAPHQL) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + ctx := r.Context() + writeHeaders(w, h.ResponseHeaders) + params := &graphql.RawParams{} + start := graphql.Now() + params.Headers = r.Header + params.ReadTime = graphql.TraceTiming{ + Start: start, + End: graphql.Now(), + } + + bodyString, err := getRequestBody(r) + if err != nil { + gqlErr := gqlerror.Errorf("could not get request body: %+v", err) + resp := exec.DispatchError(ctx, gqlerror.List{gqlErr}) + writeJson(w, resp) + return + } + + params.Query, err = cleanupBody(bodyString) + if err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + gqlErr := gqlerror.Errorf("could not cleanup body: %+v", err) + resp := exec.DispatchError(ctx, gqlerror.List{gqlErr}) + writeJson(w, resp) + return + } + + rc, opErr := exec.CreateOperationContext(ctx, params) + if opErr != nil { + w.WriteHeader(statusFor(opErr)) + resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), opErr) + writeJson(w, resp) + return + } + + var responses graphql.ResponseHandler + responses, ctx = exec.DispatchOperation(ctx, rc) + writeJson(w, responses(ctx)) +} + +// Makes sure we strip "query=" keyword from body and +// that body is not url escaped +func cleanupBody(body string) (out string, err error) { + // Some clients send 'query=' at the start of body payload. Let's remove + // it to get GQL query only. + body = strings.TrimPrefix(body, "query=") + + // Body payload can be url encoded or not. We check if %7B - "{" character + // is where query starts. If it is, query is url encoded. + if strings.HasPrefix(body, "%7B") { + body, err = url.QueryUnescape(body) + if err != nil { + return body, err + } + } + + return body, err +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go index 99c3157185..985f8db294 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go @@ -1,15 +1,24 @@ package transport import ( + "fmt" + "io" "mime" "net/http" + "strings" + + "github.com/vektah/gqlparser/v2/gqlerror" "github.com/99designs/gqlgen/graphql" ) // POST implements the POST side of the default HTTP transport // defined in https://github.com/APIs-guru/graphql-over-http#post -type POST struct{} +type POST struct { + // Map of all headers that are added to graphql response. If not + // set, only one header: Content-Type: application/json will be set. + ResponseHeaders map[string][]string +} var _ graphql.Transport = POST{} @@ -26,31 +35,58 @@ func (h POST) Supports(r *http.Request) bool { return r.Method == "POST" && mediaType == "application/json" } -func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { - w.Header().Set("Content-Type", "application/json") - - var params *graphql.RawParams - start := graphql.Now() - if err := jsonDecode(r.Body, ¶ms); err != nil { - w.WriteHeader(http.StatusBadRequest) - writeJsonErrorf(w, "json body could not be decoded: "+err.Error()) - return +func getRequestBody(r *http.Request) (string, error) { + if r == nil || r.Body == nil { + return "", nil + } + body, err := io.ReadAll(r.Body) + if err != nil { + return "", fmt.Errorf("unable to get Request Body %w", err) } + return string(body), nil +} +func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + ctx := r.Context() + writeHeaders(w, h.ResponseHeaders) + params := &graphql.RawParams{} + start := graphql.Now() params.Headers = r.Header - params.ReadTime = graphql.TraceTiming{ Start: start, End: graphql.Now(), } - rc, err := exec.CreateOperationContext(r.Context(), params) + bodyString, err := getRequestBody(r) if err != nil { - w.WriteHeader(statusFor(err)) - resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), err) + gqlErr := gqlerror.Errorf("could not get json request body: %+v", err) + resp := exec.DispatchError(ctx, gqlerror.List{gqlErr}) + writeJson(w, resp) + return + } + + bodyReader := io.NopCloser(strings.NewReader(bodyString)) + if err = jsonDecode(bodyReader, ¶ms); err != nil { + w.WriteHeader(http.StatusBadRequest) + gqlErr := gqlerror.Errorf( + "json request body could not be decoded: %+v body:%s", + err, + bodyString, + ) + resp := exec.DispatchError(ctx, gqlerror.List{gqlErr}) writeJson(w, resp) return } - responses, ctx := exec.DispatchOperation(r.Context(), rc) + + rc, opErr := exec.CreateOperationContext(ctx, params) + if opErr != nil { + w.WriteHeader(statusFor(opErr)) + resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), opErr) + writeJson(w, resp) + return + } + + var responses graphql.ResponseHandler + responses, ctx = exec.DispatchOperation(ctx, rc) writeJson(w, responses(ctx)) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/sse.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/sse.go new file mode 100644 index 0000000000..1d59fdffe5 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/sse.go @@ -0,0 +1,107 @@ +package transport + +import ( + "encoding/json" + "fmt" + "io" + "log" + "mime" + "net/http" + "strings" + + "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/99designs/gqlgen/graphql" +) + +type SSE struct{} + +var _ graphql.Transport = SSE{} + +func (t SSE) Supports(r *http.Request) bool { + if !strings.Contains(r.Header.Get("Accept"), "text/event-stream") { + return false + } + mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return false + } + return r.Method == http.MethodPost && mediaType == "application/json" +} + +func (t SSE) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + ctx := r.Context() + flusher, ok := w.(http.Flusher) + if !ok { + SendErrorf(w, http.StatusInternalServerError, "streaming unsupported") + return + } + defer flusher.Flush() + + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + w.Header().Set("Content-Type", "application/json") + + params := &graphql.RawParams{} + start := graphql.Now() + params.Headers = r.Header + params.ReadTime = graphql.TraceTiming{ + Start: start, + End: graphql.Now(), + } + + bodyString, err := getRequestBody(r) + if err != nil { + gqlErr := gqlerror.Errorf("could not get json request body: %+v", err) + resp := exec.DispatchError(ctx, gqlerror.List{gqlErr}) + log.Printf("could not get json request body: %+v", err.Error()) + writeJson(w, resp) + return + } + + bodyReader := io.NopCloser(strings.NewReader(bodyString)) + if err = jsonDecode(bodyReader, ¶ms); err != nil { + w.WriteHeader(http.StatusBadRequest) + gqlErr := gqlerror.Errorf( + "json request body could not be decoded: %+v body:%s", + err, + bodyString, + ) + resp := exec.DispatchError(ctx, gqlerror.List{gqlErr}) + log.Printf("decoding error: %+v body:%s", err.Error(), bodyString) + writeJson(w, resp) + return + } + + rc, opErr := exec.CreateOperationContext(ctx, params) + ctx = graphql.WithOperationContext(ctx, rc) + + w.Header().Set("Content-Type", "text/event-stream") + fmt.Fprint(w, ":\n\n") + flusher.Flush() + + if opErr != nil { + resp := exec.DispatchError(ctx, opErr) + writeJsonWithSSE(w, resp) + } else { + responses, ctx := exec.DispatchOperation(ctx, rc) + for { + response := responses(ctx) + if response == nil { + break + } + writeJsonWithSSE(w, response) + flusher.Flush() + } + } + + fmt.Fprint(w, "event: complete\n\n") +} + +func writeJsonWithSSE(w io.Writer, response *graphql.Response) { + b, err := json.Marshal(response) + if err != nil { + panic(err) + } + fmt.Fprintf(w, "event: next\ndata: %s\n\n", b) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go index ce845c1964..aca7207eb9 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go @@ -5,8 +5,9 @@ import ( "fmt" "io" - "github.com/99designs/gqlgen/graphql" "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/99designs/gqlgen/graphql" ) func writeJson(w io.Writer, response *graphql.Response) { @@ -21,7 +22,7 @@ func writeJsonError(w io.Writer, msg string) { writeJson(w, &graphql.Response{Errors: gqlerror.List{{Message: msg}}}) } -func writeJsonErrorf(w io.Writer, format string, args ...interface{}) { +func writeJsonErrorf(w io.Writer, format string, args ...any) { writeJson(w, &graphql.Response{Errors: gqlerror.List{{Message: fmt.Sprintf(format, args...)}}}) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go index 51b1104ccc..32e31c7c75 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go @@ -12,10 +12,11 @@ import ( "sync" "time" - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/errcode" "github.com/gorilla/websocket" "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/errcode" ) type ( @@ -24,8 +25,19 @@ type ( InitFunc WebsocketInitFunc InitTimeout time.Duration ErrorFunc WebsocketErrorFunc + CloseFunc WebsocketCloseFunc KeepAlivePingInterval time.Duration + PongOnlyInterval time.Duration PingPongInterval time.Duration + /* If PingPongInterval has a non-0 duration, then when the server sends a ping + * it sets a ReadDeadline of PingPongInterval*2 and if the client doesn't respond + * with pong before that deadline is reached then the connection will die with a + * 1006 error code. + * + * MissingPongOk if true, tells the server to not use a ReadDeadline such that a + * missing/slow pong response from the client doesn't kill the connection. + */ + MissingPongOk bool didInjectSubprotocols bool } @@ -37,14 +49,20 @@ type ( active map[string]context.CancelFunc mu sync.Mutex keepAliveTicker *time.Ticker + pongOnlyTicker *time.Ticker pingPongTicker *time.Ticker + receivedPong bool exec graphql.GraphExecutor + closed bool initPayload InitPayload } - WebsocketInitFunc func(ctx context.Context, initPayload InitPayload) (context.Context, error) + WebsocketInitFunc func(ctx context.Context, initPayload InitPayload) (context.Context, *InitPayload, error) WebsocketErrorFunc func(ctx context.Context, err error) + + // Callback called when websocket is closed. + WebsocketCloseFunc func(ctx context.Context, closeCode int) ) var errReadTimeout = errors.New("read timeout") @@ -85,7 +103,7 @@ func (t Websocket) Do(w http.ResponseWriter, r *http.Request, exec graphql.Graph switch ws.Subprotocol() { default: msg := websocket.FormatCloseMessage(websocket.CloseProtocolError, fmt.Sprintf("unsupported negotiated subprotocol %s", ws.Subprotocol())) - ws.WriteMessage(websocket.CloseMessage, msg) + _ = ws.WriteMessage(websocket.CloseMessage, msg) return case graphqlwsSubprotocol, "": // clients are required to send a subprotocol, to be backward compatible with the previous implementation we select @@ -175,17 +193,27 @@ func (c *wsConnection) init() bool { } } + var initAckPayload *InitPayload if c.InitFunc != nil { - ctx, err := c.InitFunc(c.ctx, c.initPayload) + var ctx context.Context + ctx, initAckPayload, err = c.InitFunc(c.ctx, c.initPayload) if err != nil { - c.sendConnectionError(err.Error()) + c.sendConnectionError("%s", err.Error()) c.close(websocket.CloseNormalClosure, "terminated") return false } c.ctx = ctx } - c.write(&message{t: connectionAckMessageType}) + if initAckPayload != nil { + initJsonAckPayload, err := json.Marshal(*initAckPayload) + if err != nil { + panic(err) + } + c.write(&message{t: connectionAckMessageType, payload: initJsonAckPayload}) + } else { + c.write(&message{t: connectionAckMessageType}) + } c.write(&message{t: keepAliveMessageType}) case connectionCloseMessageType: c.close(websocket.CloseNormalClosure, "terminated") @@ -211,7 +239,6 @@ func (c *wsConnection) run() { ctx, cancel := context.WithCancel(c.ctx) defer func() { cancel() - c.close(websocket.CloseAbnormalClosure, "unexpected closure") }() // If we're running in graphql-ws mode, create a timer that will trigger a @@ -224,16 +251,28 @@ func (c *wsConnection) run() { go c.keepAlive(ctx) } + // If we're running in graphql-transport-ws mode, create a timer that will trigger a + // just a pong message every interval + if c.conn.Subprotocol() == graphqltransportwsSubprotocol && c.PongOnlyInterval != 0 { + c.mu.Lock() + c.pongOnlyTicker = time.NewTicker(c.PongOnlyInterval) + c.mu.Unlock() + + go c.keepAlivePongOnly(ctx) + } + // If we're running in graphql-transport-ws mode, create a timer that will - // trigger a ping message every interval + // trigger a ping message every interval and expect a pong! if c.conn.Subprotocol() == graphqltransportwsSubprotocol && c.PingPongInterval != 0 { c.mu.Lock() c.pingPongTicker = time.NewTicker(c.PingPongInterval) c.mu.Unlock() - // Note: when the connection is closed by this deadline, the client - // will receive an "invalid close code" - c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval)) + if !c.MissingPongOk { + // Note: when the connection is closed by this deadline, the client + // will receive an "invalid close code" + _ = c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval)) + } go c.ping(ctx) } @@ -268,7 +307,11 @@ func (c *wsConnection) run() { case pingMessageType: c.write(&message{t: pongMessageType, payload: m.payload}) case pongMessageType: - c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval)) + c.mu.Lock() + c.receivedPong = true + c.mu.Unlock() + // Clear ReadTimeout -- 0 time val clears. + _ = c.conn.SetReadDeadline(time.Time{}) default: c.sendConnectionError("unexpected message %s", m.t) c.close(websocket.CloseProtocolError, "unexpected message") @@ -277,6 +320,18 @@ func (c *wsConnection) run() { } } +func (c *wsConnection) keepAlivePongOnly(ctx context.Context) { + for { + select { + case <-ctx.Done(): + c.pongOnlyTicker.Stop() + return + case <-c.pongOnlyTicker.C: + c.write(&message{t: pongMessageType, payload: json.RawMessage{}}) + } + } +} + func (c *wsConnection) keepAlive(ctx context.Context) { for { select { @@ -297,6 +352,14 @@ func (c *wsConnection) ping(ctx context.Context) { return case <-c.pingPongTicker.C: c.write(&message{t: pingMessageType, payload: json.RawMessage{}}) + // The initial deadline for this method is set in run() + // if we have not yet received a pong, don't reset the deadline. + c.mu.Lock() + if !c.MissingPongOk && c.receivedPong { + _ = c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval)) + } + c.receivedPong = false + c.mu.Unlock() } } } @@ -305,7 +368,7 @@ func (c *wsConnection) closeOnCancel(ctx context.Context) { <-ctx.Done() if r := closeReasonForContext(ctx); r != "" { - c.sendConnectionError(r) + c.sendConnectionError("%s", r) } c.close(websocket.CloseNormalClosure, "terminated") } @@ -350,6 +413,7 @@ func (c *wsConnection) subscribe(start time.Time, msg *message) { c.mu.Unlock() go func() { + ctx = withSubscriptionErrorContext(ctx) defer func() { if r := recover(); r != nil { err := rc.Recover(ctx, r) @@ -362,7 +426,11 @@ func (c *wsConnection) subscribe(start time.Time, msg *message) { } c.sendError(msg.id, gqlerr) } - c.complete(msg.id) + if errs := getSubscriptionError(ctx); len(errs) != 0 { + c.sendError(msg.id, errs...) + } else { + c.complete(msg.id) + } c.mu.Lock() delete(c.active, msg.id) c.mu.Unlock() @@ -411,7 +479,7 @@ func (c *wsConnection) sendError(id string, errors ...*gqlerror.Error) { c.write(&message{t: errorMessageType, id: id, payload: b}) } -func (c *wsConnection) sendConnectionError(format string, args ...interface{}) { +func (c *wsConnection) sendConnectionError(format string, args ...any) { b, err := json.Marshal(&gqlerror.Error{Message: fmt.Sprintf(format, args...)}) if err != nil { panic(err) @@ -422,10 +490,19 @@ func (c *wsConnection) sendConnectionError(format string, args ...interface{}) { func (c *wsConnection) close(closeCode int, message string) { c.mu.Lock() + if c.closed { + c.mu.Unlock() + return + } _ = c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(closeCode, message)) for _, closer := range c.active { closer() } + c.closed = true c.mu.Unlock() _ = c.conn.Close() + + if c.CloseFunc != nil { + c.CloseFunc(c.ctx, closeCode) + } } diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go index a5f84ba2dc..35105535e7 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go @@ -10,7 +10,7 @@ const ( // InitPayload is a structure that is parsed from the websocket init message payload. TO use // request headers for non-websocket, instead wrap the graphql handler in a middleware. -type InitPayload map[string]interface{} +type InitPayload map[string]any // GetString safely gets a string value from the payload. It returns an empty string if the // payload is nil or the value isn't set. diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_resolver_error.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_resolver_error.go new file mode 100644 index 0000000000..cb8e3ed1a3 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_resolver_error.go @@ -0,0 +1,69 @@ +package transport + +import ( + "context" + + "github.com/vektah/gqlparser/v2/gqlerror" +) + +// A private key for context that only this package can access. This is important +// to prevent collisions between different context uses +var wsSubscriptionErrorCtxKey = &wsSubscriptionErrorContextKey{"subscription-error"} + +type wsSubscriptionErrorContextKey struct { + name string +} + +type subscriptionError struct { + errs []*gqlerror.Error +} + +// AddSubscriptionError is used to let websocket return an error message after subscription resolver returns a channel. +// for example: +// +// func (r *subscriptionResolver) Method(ctx context.Context) (<-chan *model.Message, error) { +// ch := make(chan *model.Message) +// go func() { +// defer func() { +// close(ch) +// } +// // some kind of block processing (e.g.: gRPC client streaming) +// stream, err := gRPCClientStreamRequest(ctx) +// if err != nil { +// transport.AddSubscriptionError(ctx, err) +// return // must return and close channel so websocket can send error back +// } +// for { +// m, err := stream.Recv() +// if err == io.EOF { +// return +// } +// if err != nil { +// transport.AddSubscriptionError(ctx, err) +// return // must return and close channel so websocket can send error back +// } +// ch <- m +// } +// }() +// +// return ch, nil +// } +// +// see https://github.com/99designs/gqlgen/pull/2506 for more details +func AddSubscriptionError(ctx context.Context, err *gqlerror.Error) { + subscriptionErrStruct := getSubscriptionErrorStruct(ctx) + subscriptionErrStruct.errs = append(subscriptionErrStruct.errs, err) +} + +func withSubscriptionErrorContext(ctx context.Context) context.Context { + return context.WithValue(ctx, wsSubscriptionErrorCtxKey, &subscriptionError{}) +} + +func getSubscriptionErrorStruct(ctx context.Context) *subscriptionError { + v, _ := ctx.Value(wsSubscriptionErrorCtxKey).(*subscriptionError) + return v +} + +func getSubscriptionError(ctx context.Context) []*gqlerror.Error { + return getSubscriptionErrorStruct(ctx).errs +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/id.go b/vendor/github.com/99designs/gqlgen/graphql/id.go index b24605d1d8..2a946dfa74 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/id.go +++ b/vendor/github.com/99designs/gqlgen/graphql/id.go @@ -11,7 +11,7 @@ func MarshalID(s string) Marshaler { return MarshalString(s) } -func UnmarshalID(v interface{}) (string, error) { +func UnmarshalID(v any) (string, error) { switch v := v.(type) { case string: return v, nil @@ -22,13 +22,9 @@ func UnmarshalID(v interface{}) (string, error) { case int64: return strconv.FormatInt(v, 10), nil case float64: - return fmt.Sprintf("%f", v), nil + return strconv.FormatFloat(v, 'f', 6, 64), nil case bool: - if v { - return "true", nil - } else { - return "false", nil - } + return strconv.FormatBool(v), nil case nil: return "null", nil default: @@ -42,7 +38,7 @@ func MarshalIntID(i int) Marshaler { }) } -func UnmarshalIntID(v interface{}) (int, error) { +func UnmarshalIntID(v any) (int, error) { switch v := v.(type) { case string: return strconv.Atoi(v) @@ -56,3 +52,32 @@ func UnmarshalIntID(v interface{}) (int, error) { return 0, fmt.Errorf("%T is not an int", v) } } + +func MarshalUintID(i uint) Marshaler { + return WriterFunc(func(w io.Writer) { + writeQuotedString(w, strconv.FormatUint(uint64(i), 10)) + }) +} + +func UnmarshalUintID(v any) (uint, error) { + switch v := v.(type) { + case string: + result, err := strconv.ParseUint(v, 10, 64) + return uint(result), err + case int: + return uint(v), nil + case int64: + return uint(v), nil + case int32: + return uint(v), nil + case uint32: + return uint(v), nil + case uint64: + return uint(v), nil + case json.Number: + result, err := strconv.ParseUint(string(v), 10, 64) + return uint(result), err + default: + return 0, fmt.Errorf("%T is not an uint", v) + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/input.go b/vendor/github.com/99designs/gqlgen/graphql/input.go index 88c3efaa6e..681fe08017 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/input.go +++ b/vendor/github.com/99designs/gqlgen/graphql/input.go @@ -10,7 +10,7 @@ const unmarshalInputCtx key = "unmarshal_input_context" // BuildUnmarshalerMap returns a map of unmarshal functions of the ExecutableContext // to use with the WithUnmarshalerMap function. -func BuildUnmarshalerMap(unmarshaler ...interface{}) map[reflect.Type]reflect.Value { +func BuildUnmarshalerMap(unmarshaler ...any) map[reflect.Type]reflect.Value { maps := make(map[reflect.Type]reflect.Value) for _, v := range unmarshaler { ft := reflect.TypeOf(v) @@ -28,7 +28,7 @@ func WithUnmarshalerMap(ctx context.Context, maps map[reflect.Type]reflect.Value } // UnmarshalInputFromContext allows unmarshaling input object from a context. -func UnmarshalInputFromContext(ctx context.Context, raw, v interface{}) error { +func UnmarshalInputFromContext(ctx context.Context, raw, v any) error { m, ok := ctx.Value(unmarshalInputCtx).(map[reflect.Type]reflect.Value) if m == nil || !ok { return errors.New("graphql: the input context is empty") diff --git a/vendor/github.com/99designs/gqlgen/graphql/int.go b/vendor/github.com/99designs/gqlgen/graphql/int.go index 57d0d589ba..41cad3f1f3 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/int.go +++ b/vendor/github.com/99designs/gqlgen/graphql/int.go @@ -13,7 +13,7 @@ func MarshalInt(i int) Marshaler { }) } -func UnmarshalInt(v interface{}) (int, error) { +func UnmarshalInt(v any) (int, error) { switch v := v.(type) { case string: return strconv.Atoi(v) @@ -23,6 +23,8 @@ func UnmarshalInt(v interface{}) (int, error) { return int(v), nil case json.Number: return strconv.Atoi(string(v)) + case nil: + return 0, nil default: return 0, fmt.Errorf("%T is not an int", v) } @@ -34,7 +36,7 @@ func MarshalInt64(i int64) Marshaler { }) } -func UnmarshalInt64(v interface{}) (int64, error) { +func UnmarshalInt64(v any) (int64, error) { switch v := v.(type) { case string: return strconv.ParseInt(v, 10, 64) @@ -44,6 +46,8 @@ func UnmarshalInt64(v interface{}) (int64, error) { return v, nil case json.Number: return strconv.ParseInt(string(v), 10, 64) + case nil: + return 0, nil default: return 0, fmt.Errorf("%T is not an int", v) } @@ -55,7 +59,7 @@ func MarshalInt32(i int32) Marshaler { }) } -func UnmarshalInt32(v interface{}) (int32, error) { +func UnmarshalInt32(v any) (int32, error) { switch v := v.(type) { case string: iv, err := strconv.ParseInt(v, 10, 32) @@ -73,6 +77,8 @@ func UnmarshalInt32(v interface{}) (int32, error) { return 0, err } return int32(iv), nil + case nil: + return 0, nil default: return 0, fmt.Errorf("%T is not an int", v) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go index 8482d62a86..30c865cc0d 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go +++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go @@ -74,13 +74,15 @@ func (f *Field) IsDeprecated() bool { } func (f *Field) DeprecationReason() *string { - if f.deprecation == nil { + if f.deprecation == nil || !f.IsDeprecated() { return nil } reason := f.deprecation.Arguments.ForName("reason") + if reason == nil { - return nil + defaultReason := "No longer supported" + return &defaultReason } return &reason.Value.Raw diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go index b7b0ad94e0..897b1a098f 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go +++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go @@ -2,7 +2,6 @@ package introspection import ( "sort" - "strings" "github.com/vektah/gqlparser/v2/ast" ) @@ -22,9 +21,6 @@ func (s *Schema) Types() []Type { typeIndex := map[string]Type{} typeNames := make([]string, 0, len(s.schema.Types)) for _, typ := range s.schema.Types { - if strings.HasPrefix(typ.Name, "__") { - continue - } typeNames = append(typeNames, typ.Name) typeIndex[typ.Name] = *WrapTypeFromDef(s.schema, typ) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/jsonw.go b/vendor/github.com/99designs/gqlgen/graphql/jsonw.go index 54e293f1ad..16bb63b730 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/jsonw.go +++ b/vendor/github.com/99designs/gqlgen/graphql/jsonw.go @@ -28,7 +28,7 @@ type Marshaler interface { } type Unmarshaler interface { - UnmarshalGQL(v interface{}) error + UnmarshalGQL(v any) error } type ContextMarshaler interface { @@ -36,7 +36,7 @@ type ContextMarshaler interface { } type ContextUnmarshaler interface { - UnmarshalGQLContext(ctx context.Context, v interface{}) error + UnmarshalGQLContext(ctx context.Context, v any) error } type contextMarshalerAdapter struct { diff --git a/vendor/github.com/99designs/gqlgen/graphql/omittable.go b/vendor/github.com/99designs/gqlgen/graphql/omittable.go new file mode 100644 index 0000000000..89716400b6 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/omittable.go @@ -0,0 +1,58 @@ +package graphql + +import "encoding/json" + +// Omittable is a wrapper around a value that also stores whether it is set +// or not. +type Omittable[T any] struct { + value T + set bool +} + +var ( + _ json.Marshaler = Omittable[struct{}]{} + _ json.Unmarshaler = (*Omittable[struct{}])(nil) +) + +func OmittableOf[T any](value T) Omittable[T] { + return Omittable[T]{ + value: value, + set: true, + } +} + +func (o Omittable[T]) Value() T { + if !o.set { + var zero T + return zero + } + return o.value +} + +func (o Omittable[T]) ValueOK() (T, bool) { + if !o.set { + var zero T + return zero, false + } + return o.value, true +} + +func (o Omittable[T]) IsSet() bool { + return o.set +} + +func (o Omittable[T]) MarshalJSON() ([]byte, error) { + if !o.set { + return []byte("null"), nil + } + return json.Marshal(o.value) +} + +func (o *Omittable[T]) UnmarshalJSON(bytes []byte) error { + err := json.Unmarshal(bytes, &o.value) + if err != nil { + return err + } + o.set = true + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/playground/altair_playground.go b/vendor/github.com/99designs/gqlgen/graphql/playground/altair_playground.go new file mode 100644 index 0000000000..f7c55cbd00 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/playground/altair_playground.go @@ -0,0 +1,84 @@ +package playground + +import ( + "html/template" + "net/http" +) + +var altairPage = template.Must(template.New("altair").Parse(` + + + + + {{.title}} + + + + + + + + + +
+
+
+ Altair +
+
+ + + +
+
+
+
+ + + + + + + + +`)) + +// AltairHandler responsible for setting up the altair playground +func AltairHandler(title, endpoint string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + err := altairPage.Execute(w, map[string]any{ + "title": title, + "endpoint": endpoint, + "endpointIsAbsolute": endpointHasScheme(endpoint), + "subscriptionEndpoint": getSubscriptionEndpoint(endpoint), + "version": "5.0.5", + "cssSRI": "sha256-kZ35e5mdMYN5ALEbnsrA2CLn85Oe4hBodfsih9BqNxs=", + "mainSRI": "sha256-nWdVTcGTlBDV1L04UQnqod+AJedzBCnKHv6Ct65liHE=", + "polyfillsSRI": "sha256-1aVEg2sROcCQ/RxU3AlcPaRZhZdIWA92q2M+mdd/R4c=", + "runtimeSRI": "sha256-cK2XhXqQr0WS1Z5eKNdac0rJxTD6miC3ubd+aEVMQDk=", + }) + if err != nil { + panic(err) + } + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/playground/apollo_sandbox_playground.go b/vendor/github.com/99designs/gqlgen/graphql/playground/apollo_sandbox_playground.go new file mode 100644 index 0000000000..f998b4d8c3 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/playground/apollo_sandbox_playground.go @@ -0,0 +1,186 @@ +package playground + +import ( + "encoding/json" + "fmt" + "html/template" + "net/http" +) + +// NOTE: New version available at https://embeddable-sandbox.cdn.apollographql.com/ --> +var apolloSandboxPage = template.Must(template.New("ApolloSandbox").Parse(` + + + + + {{.title}} + + + + + + +
+ + + +`)) + +// ApolloSandboxHandler responsible for setting up the apollo sandbox playground +func ApolloSandboxHandler(title, endpoint string, opts ...ApolloSandboxOption) http.HandlerFunc { + options := &apolloSandboxOptions{ + HideCookieToggle: true, + InitialState: apolloSandboxInitialState{ + IncludeCookies: true, + PollForSchemaUpdates: false, + }, + } + + for _, opt := range opts { + opt(options) + } + + optionsBytes, err := json.Marshal(options) + if err != nil { + panic(fmt.Errorf("failed to marshal apollo sandbox options: %w", err)) + } + + return func(w http.ResponseWriter, r *http.Request) { + err := apolloSandboxPage.Execute(w, map[string]any{ + "title": title, + "endpoint": endpoint, + "endpointIsAbsolute": endpointHasScheme(endpoint), + "mainSRI": "sha256-pYhw/8TGkZxk960PMMpDtjhw9YtKXUzGv6XQQaMJSh8=", + "options": string(optionsBytes), + }) + if err != nil { + panic(err) + } + } +} + +// See https://www.apollographql.com/docs/graphos/explorer/sandbox/#options --> +type apolloSandboxOptions struct { + HideCookieToggle bool `json:"hideCookieToggle"` + EndpointIsEditable bool `json:"endpointIsEditable"` + InitialState apolloSandboxInitialState `json:"initialState,omitempty"` +} + +type apolloSandboxInitialState struct { + IncludeCookies bool `json:"includeCookies"` + Document string `json:"document,omitempty"` + Variables map[string]any `json:"variables,omitempty"` + Headers map[string]any `json:"headers,omitempty"` + CollectionId string `json:"collectionId,omitempty"` + OperationId string `json:"operationId,omitempty"` + PollForSchemaUpdates bool `json:"pollForSchemaUpdates"` + SharedHeaders map[string]any `json:"sharedHeaders,omitempty"` +} + +type ApolloSandboxOption func(options *apolloSandboxOptions) + +// WithApolloSandboxHideCookieToggle By default, the embedded Sandbox does not show the Include cookies toggle in its connection settings. +// +// Set hideCookieToggle to false to enable users of your embedded Sandbox instance to toggle the Include cookies setting. +func WithApolloSandboxHideCookieToggle(hideCookieToggle bool) ApolloSandboxOption { + return func(options *apolloSandboxOptions) { + options.HideCookieToggle = hideCookieToggle + } +} + +// WithApolloSandboxEndpointIsEditable By default, the embedded Sandbox has a URL input box that is editable by users. +// +// Set endpointIsEditable to false to prevent users of your embedded Sandbox instance from changing the endpoint URL. +func WithApolloSandboxEndpointIsEditable(endpointIsEditable bool) ApolloSandboxOption { + return func(options *apolloSandboxOptions) { + options.EndpointIsEditable = endpointIsEditable + } +} + +// WithApolloSandboxInitialStateIncludeCookies Set this value to true if you want the Sandbox to pass { credentials: 'include' } for its requests by default. +// +// If you set hideCookieToggle to false, users can override this default setting with the Include cookies toggle. (By default, the embedded Sandbox does not show the Include cookies toggle in its connection settings.) +// +// If you also pass the handleRequest option, this option is ignored. +// +// Read more about the fetch API and credentials here https://developer.mozilla.org/en-US/docs/Web/API/fetch#credentials +func WithApolloSandboxInitialStateIncludeCookies(includeCookies bool) ApolloSandboxOption { + return func(options *apolloSandboxOptions) { + options.InitialState.IncludeCookies = includeCookies + } +} + +// WithApolloSandboxInitialStateDocument Document operation to populate in the Sandbox's editor on load. +// +// If you omit this, the Sandbox initially loads an example query based on your schema. +func WithApolloSandboxInitialStateDocument(document string) ApolloSandboxOption { + return func(options *apolloSandboxOptions) { + options.InitialState.Document = document + } +} + +// WithApolloSandboxInitialStateVariables Variables containing initial variable values to populate in the Sandbox on load. +// +// If provided, these variables should apply to the initial query you provide for document. +func WithApolloSandboxInitialStateVariables(variables map[string]any) ApolloSandboxOption { + return func(options *apolloSandboxOptions) { + options.InitialState.Variables = variables + } +} + +// WithApolloSandboxInitialStateHeaders Headers containing initial variable values to populate in the Sandbox on load. +// +// If provided, these variables should apply to the initial query you provide for document. +func WithApolloSandboxInitialStateHeaders(headers map[string]any) ApolloSandboxOption { + return func(options *apolloSandboxOptions) { + options.InitialState.Headers = headers + } +} + +// WithApolloSandboxInitialStateCollectionIdAndOperationId The ID of a collection, paired with an operation ID to populate in the Sandbox on load. +// +// You can find these values from a registered graph in Studio by clicking the ... menu next to an operation in the Explorer of that graph and selecting View operation details. +func WithApolloSandboxInitialStateCollectionIdAndOperationId(collectionId, operationId string) ApolloSandboxOption { + return func(options *apolloSandboxOptions) { + options.InitialState.CollectionId = collectionId + options.InitialState.OperationId = operationId + } +} + +// WithApolloSandboxInitialStatePollForSchemaUpdates If true, the embedded Sandbox periodically polls your initialEndpoint for schema updates. +// +// The default value is false. +func WithApolloSandboxInitialStatePollForSchemaUpdates(pollForSchemaUpdates bool) ApolloSandboxOption { + return func(options *apolloSandboxOptions) { + options.InitialState.PollForSchemaUpdates = pollForSchemaUpdates + } +} + +// WithApolloSandboxInitialStateSharedHeaders Headers that are applied by default to every operation executed by the embedded Sandbox. +// +// Users can disable the application of these headers, but they can't modify their values. +// +// The embedded Sandbox always includes these headers in its introspection queries to your initialEndpoint. +func WithApolloSandboxInitialStateSharedHeaders(sharedHeaders map[string]any) ApolloSandboxOption { + return func(options *apolloSandboxOptions) { + options.InitialState.SharedHeaders = sharedHeaders + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go b/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go index 08e5e4a8d7..816fcca39d 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go +++ b/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go @@ -24,12 +24,12 @@ var page = template.Must(template.New("graphiql").Parse(` } @@ -58,13 +58,24 @@ var page = template.Must(template.New("graphiql").Parse(` const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:'; const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}}; {{- end}} +{{- if .fetcherHeaders}} + const fetcherHeaders = {{.fetcherHeaders}}; +{{- else}} + const fetcherHeaders = undefined; +{{- end}} +{{- if .uiHeaders}} + const uiHeaders = {{.uiHeaders}}; +{{- else}} + const uiHeaders = undefined; +{{- end}} - const fetcher = GraphiQL.createFetcher({ url, subscriptionUrl }); + const fetcher = GraphiQL.createFetcher({ url, subscriptionUrl, headers: fetcherHeaders }); ReactDOM.render( React.createElement(GraphiQL, { fetcher: fetcher, isHeadersEditorEnabled: true, - shouldPersistHeaders: true + shouldPersistHeaders: true, + headers: JSON.stringify(uiHeaders, null, 2) }), document.getElementById('graphiql'), ); @@ -74,19 +85,28 @@ var page = template.Must(template.New("graphiql").Parse(` `)) // Handler responsible for setting up the playground -func Handler(title string, endpoint string) http.HandlerFunc { +func Handler(title, endpoint string) http.HandlerFunc { + return HandlerWithHeaders(title, endpoint, nil, nil) +} + +// HandlerWithHeaders sets up the playground. +// fetcherHeaders are used by the playground's fetcher instance and will not be visible in the UI. +// uiHeaders are default headers that will show up in the UI headers editor. +func HandlerWithHeaders(title, endpoint string, fetcherHeaders, uiHeaders map[string]string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "text/html; charset=UTF-8") - err := page.Execute(w, map[string]interface{}{ + err := page.Execute(w, map[string]any{ "title": title, "endpoint": endpoint, + "fetcherHeaders": fetcherHeaders, + "uiHeaders": uiHeaders, "endpointIsAbsolute": endpointHasScheme(endpoint), "subscriptionEndpoint": getSubscriptionEndpoint(endpoint), - "version": "2.0.7", - "cssSRI": "sha256-gQryfbGYeYFxnJYnfPStPYFt0+uv8RP8Dm++eh00G9c=", - "jsSRI": "sha256-qQ6pw7LwTLC+GfzN+cJsYXfVWRKH9O5o7+5H96gTJhQ=", - "reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=", - "reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=", + "version": "3.0.6", + "cssSRI": "sha256-wTzfn13a+pLMB5rMeysPPR1hO7x0SwSeQI+cnw7VdbE=", + "jsSRI": "sha256-eNxH+Ah7Z9up9aJYTQycgyNuy953zYZwE9Rqf5rH+r4=", + "reactSRI": "sha256-S0lp+k7zWUMk2ixteM6HZvu8L9Eh//OVrt+ZfbCpmgY=", + "reactDOMSRI": "sha256-IXWO0ITNDjfnNXIu5POVfqlgYoop36bDzhodR6LW5Pc=", }) if err != nil { panic(err) diff --git a/vendor/github.com/99designs/gqlgen/graphql/recovery.go b/vendor/github.com/99designs/gqlgen/graphql/recovery.go index 9bc0e47e1d..4aae69195d 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/recovery.go +++ b/vendor/github.com/99designs/gqlgen/graphql/recovery.go @@ -9,9 +9,9 @@ import ( "github.com/vektah/gqlparser/v2/gqlerror" ) -type RecoverFunc func(ctx context.Context, err interface{}) (userMessage error) +type RecoverFunc func(ctx context.Context, err any) (userMessage error) -func DefaultRecover(ctx context.Context, err interface{}) error { +func DefaultRecover(ctx context.Context, err any) error { fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr) debug.PrintStack() diff --git a/vendor/github.com/99designs/gqlgen/graphql/response.go b/vendor/github.com/99designs/gqlgen/graphql/response.go index 0d36049a33..e37b5cfc1e 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/response.go +++ b/vendor/github.com/99designs/gqlgen/graphql/response.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" + "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/gqlerror" ) @@ -12,12 +13,15 @@ import ( // https://github.com/facebook/graphql/commit/7b40390d48680b15cb93e02d46ac5eb249689876#diff-757cea6edf0288677a9eea4cfc801d87R107 // and https://github.com/facebook/graphql/pull/384 type Response struct { - Errors gqlerror.List `json:"errors,omitempty"` - Data json.RawMessage `json:"data"` - Extensions map[string]interface{} `json:"extensions,omitempty"` + Errors gqlerror.List `json:"errors,omitempty"` + Data json.RawMessage `json:"data"` + Label string `json:"label,omitempty"` + Path ast.Path `json:"path,omitempty"` + HasNext *bool `json:"hasNext,omitempty"` + Extensions map[string]any `json:"extensions,omitempty"` } -func ErrorResponse(ctx context.Context, messagef string, args ...interface{}) *Response { +func ErrorResponse(ctx context.Context, messagef string, args ...any) *Response { return &Response{ Errors: gqlerror.List{{Message: fmt.Sprintf(messagef, args...)}}, } diff --git a/vendor/github.com/99designs/gqlgen/graphql/stats.go b/vendor/github.com/99designs/gqlgen/graphql/stats.go index a52e143ebe..1bf2ad9e66 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/stats.go +++ b/vendor/github.com/99designs/gqlgen/graphql/stats.go @@ -12,9 +12,9 @@ type Stats struct { Parsing TraceTiming Validation TraceTiming - // Stats collected by handler extensions. Dont use directly, the extension should provide a type safe way to + // Stats collected by handler extensions. Don't use directly, the extension should provide a type safe way to // access this. - extension map[string]interface{} + extension map[string]any } type TraceTiming struct { @@ -26,7 +26,7 @@ var ctxTraceStart key = "trace_start" // StartOperationTrace captures the current time and stores it in context. This will eventually be added to request // context but we want to grab it as soon as possible. For transports that can only handle a single graphql query -// per http requests you dont need to call this at all, the server will do it for you. For transports that handle +// per http requests you don't need to call this at all, the server will do it for you. For transports that handle // multiple (eg batching, subscriptions) this should be called before decoding each request. func StartOperationTrace(ctx context.Context) context.Context { return context.WithValue(ctx, ctxTraceStart, Now()) @@ -42,14 +42,14 @@ func GetStartTime(ctx context.Context) time.Time { return t } -func (c *Stats) SetExtension(name string, data interface{}) { +func (c *Stats) SetExtension(name string, data any) { if c.extension == nil { - c.extension = map[string]interface{}{} + c.extension = map[string]any{} } c.extension[name] = data } -func (c *Stats) GetExtension(name string) interface{} { +func (c *Stats) GetExtension(name string) any { if c.extension == nil { return nil } diff --git a/vendor/github.com/99designs/gqlgen/graphql/string.go b/vendor/github.com/99designs/gqlgen/graphql/string.go index 742e50cc3b..6622734e3e 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/string.go +++ b/vendor/github.com/99designs/gqlgen/graphql/string.go @@ -1,6 +1,7 @@ package graphql import ( + "encoding/json" "fmt" "io" "strconv" @@ -46,7 +47,7 @@ func writeQuotedString(w io.Writer, s string) { io.WriteString(w, `"`) } -func UnmarshalString(v interface{}) (string, error) { +func UnmarshalString(v any) (string, error) { switch v := v.(type) { case string: return v, nil @@ -55,15 +56,13 @@ func UnmarshalString(v interface{}) (string, error) { case int64: return strconv.FormatInt(v, 10), nil case float64: - return fmt.Sprintf("%f", v), nil + return strconv.FormatFloat(v, 'f', -1, 64), nil + case json.Number: + return string(v), nil case bool: - if v { - return "true", nil - } else { - return "false", nil - } + return strconv.FormatBool(v), nil case nil: - return "null", nil + return "", nil default: return "", fmt.Errorf("%T is not a string", v) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/time.go b/vendor/github.com/99designs/gqlgen/graphql/time.go index ef3d17da32..a5fe903013 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/time.go +++ b/vendor/github.com/99designs/gqlgen/graphql/time.go @@ -17,7 +17,7 @@ func MarshalTime(t time.Time) Marshaler { }) } -func UnmarshalTime(v interface{}) (time.Time, error) { +func UnmarshalTime(v any) (time.Time, error) { if tmpStr, ok := v.(string); ok { return time.Parse(time.RFC3339Nano, tmpStr) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/uint.go b/vendor/github.com/99designs/gqlgen/graphql/uint.go index 9349c2f4d2..cd5d235503 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/uint.go +++ b/vendor/github.com/99designs/gqlgen/graphql/uint.go @@ -2,6 +2,7 @@ package graphql import ( "encoding/json" + "errors" "fmt" "io" "strconv" @@ -13,18 +14,28 @@ func MarshalUint(i uint) Marshaler { }) } -func UnmarshalUint(v interface{}) (uint, error) { +func UnmarshalUint(v any) (uint, error) { switch v := v.(type) { case string: u64, err := strconv.ParseUint(v, 10, 64) return uint(u64), err case int: + if v < 0 { + return 0, errors.New("cannot convert negative numbers to uint") + } + return uint(v), nil case int64: + if v < 0 { + return 0, errors.New("cannot convert negative numbers to uint") + } + return uint(v), nil case json.Number: u64, err := strconv.ParseUint(string(v), 10, 64) return uint(u64), err + case nil: + return 0, nil default: return 0, fmt.Errorf("%T is not an uint", v) } @@ -36,16 +47,26 @@ func MarshalUint64(i uint64) Marshaler { }) } -func UnmarshalUint64(v interface{}) (uint64, error) { +func UnmarshalUint64(v any) (uint64, error) { switch v := v.(type) { case string: return strconv.ParseUint(v, 10, 64) case int: + if v < 0 { + return 0, errors.New("cannot convert negative numbers to uint64") + } + return uint64(v), nil case int64: + if v < 0 { + return 0, errors.New("cannot convert negative numbers to uint64") + } + return uint64(v), nil case json.Number: return strconv.ParseUint(string(v), 10, 64) + case nil: + return 0, nil default: return 0, fmt.Errorf("%T is not an uint", v) } @@ -57,17 +78,25 @@ func MarshalUint32(i uint32) Marshaler { }) } -func UnmarshalUint32(v interface{}) (uint32, error) { +func UnmarshalUint32(v any) (uint32, error) { switch v := v.(type) { case string: - iv, err := strconv.ParseInt(v, 10, 32) + iv, err := strconv.ParseUint(v, 10, 32) if err != nil { return 0, err } return uint32(iv), nil case int: + if v < 0 { + return 0, errors.New("cannot convert negative numbers to uint32") + } + return uint32(v), nil case int64: + if v < 0 { + return 0, errors.New("cannot convert negative numbers to uint32") + } + return uint32(v), nil case json.Number: iv, err := strconv.ParseUint(string(v), 10, 32) @@ -75,6 +104,8 @@ func UnmarshalUint32(v interface{}) (uint32, error) { return 0, err } return uint32(iv), nil + case nil: + return 0, nil default: return 0, fmt.Errorf("%T is not an uint", v) } diff --git a/vendor/github.com/99designs/gqlgen/graphql/upload.go b/vendor/github.com/99designs/gqlgen/graphql/upload.go index dafbde6508..b603ab04c8 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/upload.go +++ b/vendor/github.com/99designs/gqlgen/graphql/upload.go @@ -18,7 +18,7 @@ func MarshalUpload(f Upload) Marshaler { }) } -func UnmarshalUpload(v interface{}) (Upload, error) { +func UnmarshalUpload(v any) (Upload, error) { upload, ok := v.(Upload) if !ok { return Upload{}, fmt.Errorf("%T is not an Upload", v) diff --git a/vendor/github.com/99designs/gqlgen/graphql/uuid.go b/vendor/github.com/99designs/gqlgen/graphql/uuid.go new file mode 100644 index 0000000000..e9f22dccdb --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/uuid.go @@ -0,0 +1,25 @@ +package graphql + +import ( + "fmt" + + "github.com/google/uuid" +) + +func MarshalUUID(id uuid.UUID) Marshaler { + if id == uuid.Nil { + return Null + } + return MarshalString(id.String()) +} + +func UnmarshalUUID(v any) (uuid.UUID, error) { + switch v := v.(type) { + case string: + return uuid.Parse(v) + case []byte: + return uuid.ParseBytes(v) + default: + return uuid.Nil, fmt.Errorf("%T is not a uuid", v) + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/version.go b/vendor/github.com/99designs/gqlgen/graphql/version.go index a03d70aca1..1b5912b419 100644 --- a/vendor/github.com/99designs/gqlgen/graphql/version.go +++ b/vendor/github.com/99designs/gqlgen/graphql/version.go @@ -1,3 +1,3 @@ package graphql -const Version = "v0.17.19" +const Version = "v0.17.54" diff --git a/vendor/github.com/ActiveState/termtest/expect.go b/vendor/github.com/ActiveState/termtest/expect.go index ee26707432..d340777a80 100644 --- a/vendor/github.com/ActiveState/termtest/expect.go +++ b/vendor/github.com/ActiveState/termtest/expect.go @@ -86,7 +86,7 @@ func (tt *TermTest) ExpectCustom(consumer consumer, opts ...SetExpectOpt) (rerr return fmt.Errorf("could not create expect options: %w", err) } - cons, err := tt.outputProducer.addConsumer(tt, consumer, expectOpts.ToConsumerOpts()...) + cons, err := tt.outputProducer.addConsumer(consumer, expectOpts.ToConsumerOpts()...) if err != nil { return fmt.Errorf("could not add consumer: %w", err) } @@ -180,11 +180,11 @@ func (tt *TermTest) expectExitCode(exitCode int, match bool, opts ...SetExpectOp select { case <-time.After(timeoutV): return fmt.Errorf("after %s: %w", timeoutV, TimeoutError) - case state := <-tt.Exited(false): // do not wait for unread output since it's not read by this select{} - if state.Err != nil && (state.ProcessState == nil || state.ProcessState.ExitCode() == 0) { - return fmt.Errorf("cmd wait failed: %w", state.Err) + case err := <-waitChan(tt.cmd.Wait): + if err != nil && (tt.cmd.ProcessState == nil || tt.cmd.ProcessState.ExitCode() == 0) { + return fmt.Errorf("cmd wait failed: %w", err) } - if err := tt.assertExitCode(state.ProcessState.ExitCode(), exitCode, match); err != nil { + if err := tt.assertExitCode(tt.cmd.ProcessState.ExitCode(), exitCode, match); err != nil { return err } } diff --git a/vendor/github.com/ActiveState/termtest/helpers.go b/vendor/github.com/ActiveState/termtest/helpers.go index 9092a7577f..ef5b241b8f 100644 --- a/vendor/github.com/ActiveState/termtest/helpers.go +++ b/vendor/github.com/ActiveState/termtest/helpers.go @@ -4,7 +4,6 @@ import ( "bytes" "errors" "os" - "os/exec" "strings" "time" ) @@ -23,20 +22,10 @@ type cmdExit struct { Err error } -// waitForCmdExit turns process.wait() into a channel so that it can be used within a select{} statement -func waitForCmdExit(cmd *exec.Cmd) chan *cmdExit { - exit := make(chan *cmdExit, 1) - go func() { - err := cmd.Wait() - exit <- &cmdExit{ProcessState: cmd.ProcessState, Err: err} - }() - return exit -} - func waitChan[T any](wait func() T) chan T { - done := make(chan T) + done := make(chan T, 1) go func() { - done <- wait() + wait() close(done) }() return done diff --git a/vendor/github.com/ActiveState/termtest/outputconsumer.go b/vendor/github.com/ActiveState/termtest/outputconsumer.go index 5e51c26a4d..b5dc925bf0 100644 --- a/vendor/github.com/ActiveState/termtest/outputconsumer.go +++ b/vendor/github.com/ActiveState/termtest/outputconsumer.go @@ -15,7 +15,6 @@ type outputConsumer struct { opts *OutputConsumerOpts isalive bool mutex *sync.Mutex - tt *TermTest } type OutputConsumerOpts struct { @@ -37,7 +36,7 @@ func OptsConsTimeout(timeout time.Duration) func(o *OutputConsumerOpts) { } } -func newOutputConsumer(tt *TermTest, consume consumer, opts ...SetConsOpt) *outputConsumer { +func newOutputConsumer(consume consumer, opts ...SetConsOpt) *outputConsumer { oc := &outputConsumer{ consume: consume, opts: &OutputConsumerOpts{ @@ -47,7 +46,6 @@ func newOutputConsumer(tt *TermTest, consume consumer, opts ...SetConsOpt) *outp waiter: make(chan error, 1), isalive: true, mutex: &sync.Mutex{}, - tt: tt, } for _, optSetter := range opts { @@ -83,6 +81,23 @@ func (e *outputConsumer) Report(buffer []byte) (int, error) { return pos, err } +type errConsumerStopped struct { + reason error +} + +func (e errConsumerStopped) Error() string { + return fmt.Sprintf("consumer stopped, reason: %s", e.reason) +} + +func (e errConsumerStopped) Unwrap() error { + return e.reason +} + +func (e *outputConsumer) Stop(reason error) { + e.opts.Logger.Printf("stopping consumer, reason: %s\n", reason) + e.waiter <- errConsumerStopped{reason} +} + func (e *outputConsumer) wait() error { e.opts.Logger.Println("started waiting") defer e.opts.Logger.Println("stopped waiting") @@ -103,11 +118,5 @@ func (e *outputConsumer) wait() error { e.mutex.Lock() e.opts.Logger.Println("Encountered timeout") return fmt.Errorf("after %s: %w", e.opts.Timeout, TimeoutError) - case state := <-e.tt.Exited(true): // allow for output to be read first by first case in this select{} - e.mutex.Lock() - if state.Err != nil { - e.opts.Logger.Println("Encountered error waiting for process to exit: %s\n", state.Err.Error()) - } - return fmt.Errorf("process exited (status: %d)", state.ProcessState.ExitCode()) } } diff --git a/vendor/github.com/ActiveState/termtest/outputproducer.go b/vendor/github.com/ActiveState/termtest/outputproducer.go index 8c68b7ae6e..178a06b685 100644 --- a/vendor/github.com/ActiveState/termtest/outputproducer.go +++ b/vendor/github.com/ActiveState/termtest/outputproducer.go @@ -54,8 +54,7 @@ func (o *outputProducer) listen(r io.Reader, w io.Writer, appendBuffer func([]by for { o.opts.Logger.Println("listen: loop") if err := o.processNextRead(br, w, appendBuffer, size); err != nil { - if errors.Is(err, ptyEOF) { - o.opts.Logger.Println("listen: reached EOF") + if errors.Is(err, PtyEOF) { return nil } else { return fmt.Errorf("could not poll reader: %w", err) @@ -64,7 +63,7 @@ func (o *outputProducer) listen(r io.Reader, w io.Writer, appendBuffer func([]by } } -var ptyEOF = errors.New("pty closed") +var PtyEOF = errors.New("pty closed") func (o *outputProducer) processNextRead(r io.Reader, w io.Writer, appendBuffer func([]byte, bool) error, size int) error { o.opts.Logger.Printf("processNextRead started with size: %d\n", size) @@ -78,6 +77,7 @@ func (o *outputProducer) processNextRead(r io.Reader, w io.Writer, appendBuffer pathError := &fs.PathError{} if errors.Is(errRead, fs.ErrClosed) || errors.Is(errRead, io.EOF) || (runtime.GOOS == "linux" && errors.As(errRead, &pathError)) { isEOF = true + o.opts.Logger.Println("reached EOF") } } @@ -96,7 +96,8 @@ func (o *outputProducer) processNextRead(r io.Reader, w io.Writer, appendBuffer if errRead != nil { if isEOF { - return errors.Join(errRead, ptyEOF) + o.closeConsumers(PtyEOF) + return errors.Join(errRead, PtyEOF) } return fmt.Errorf("could not read pty output: %w", errRead) } @@ -194,6 +195,19 @@ func (o *outputProducer) processDirtyOutput(output []byte, cursorPos int, cleanU return append(append(alreadyCleanedOutput, processedOutput...), unprocessedOutput...), processedCursorPos, newCleanUptoPos, nil } +func (o *outputProducer) closeConsumers(reason error) { + o.opts.Logger.Println("closing consumers") + defer o.opts.Logger.Println("closed consumers") + + o.mutex.Lock() + defer o.mutex.Unlock() + + for n := 0; n < len(o.consumers); n++ { + o.consumers[n].Stop(reason) + o.consumers = append(o.consumers[:n], o.consumers[n+1:]...) + } +} + func (o *outputProducer) flushConsumers() error { o.opts.Logger.Println("flushing consumers") defer o.opts.Logger.Println("flushed consumers") @@ -238,12 +252,12 @@ func (o *outputProducer) flushConsumers() error { return nil } -func (o *outputProducer) addConsumer(tt *TermTest, consume consumer, opts ...SetConsOpt) (*outputConsumer, error) { +func (o *outputProducer) addConsumer(consume consumer, opts ...SetConsOpt) (*outputConsumer, error) { o.opts.Logger.Printf("adding consumer") defer o.opts.Logger.Printf("added consumer") opts = append(opts, OptConsInherit(o.opts)) - listener := newOutputConsumer(tt, consume, opts...) + listener := newOutputConsumer(consume, opts...) o.consumers = append(o.consumers, listener) if err := o.flushConsumers(); err != nil { diff --git a/vendor/github.com/ActiveState/termtest/termtest.go b/vendor/github.com/ActiveState/termtest/termtest.go index d363ad0ff4..fbcc2aa47e 100644 --- a/vendor/github.com/ActiveState/termtest/termtest.go +++ b/vendor/github.com/ActiveState/termtest/termtest.go @@ -23,8 +23,8 @@ type TermTest struct { ptmx pty.Pty outputProducer *outputProducer listenError chan error + waitError chan error opts *Opts - exited *cmdExit } type ErrorHandler func(*TermTest, error) error @@ -79,6 +79,7 @@ func New(cmd *exec.Cmd, opts ...SetOpt) (*TermTest, error) { cmd: cmd, outputProducer: newOutputProducer(optv), listenError: make(chan error, 1), + waitError: make(chan error, 1), opts: optv, } @@ -228,6 +229,7 @@ func (tt *TermTest) start() (rerr error) { tt.term = vt10x.New(vt10x.WithWriter(ptmx), vt10x.WithSize(tt.opts.Cols, tt.opts.Rows)) // Start listening for output + // We use a waitgroup here to ensure the listener is active before consumers are attached. wg := &sync.WaitGroup{} wg.Add(1) go func() { @@ -236,12 +238,18 @@ func (tt *TermTest) start() (rerr error) { err := tt.outputProducer.Listen(tt.ptmx, tt.term) tt.listenError <- err }() - wg.Wait() go func() { - tt.exited = <-waitForCmdExit(tt.cmd) + // We start waiting right away, because on Windows the PTY isn't closed until the process exits, which in turn + // can't happen unless we've told the pty we're ready for it to close. + // This of course isn't ideal, but until the pty library fixes the cross-platform inconsistencies we have to + // work around these limitations. + defer tt.opts.Logger.Printf("waitIndefinitely finished") + tt.waitError <- tt.waitIndefinitely() }() + wg.Wait() + return nil } @@ -252,13 +260,8 @@ func (tt *TermTest) Wait(timeout time.Duration) (rerr error) { tt.opts.Logger.Println("wait called") defer tt.opts.Logger.Println("wait closed") - errc := make(chan error, 1) - go func() { - errc <- tt.WaitIndefinitely() - }() - select { - case err := <-errc: + case err := <-tt.waitError: // WaitIndefinitely already invokes the expect error handler return err case <-time.After(timeout): @@ -324,28 +327,6 @@ func (tt *TermTest) SendCtrlC() { tt.Send(string([]byte{0x03})) // 0x03 is ASCII character for ^C } -// Exited returns a channel that sends the given termtest's command cmdExit info when available. -// This can be used within a select{} statement. -// If waitExtra is given, waits a little bit before sending cmdExit info. This allows any fellow -// switch cases with output consumers to handle unprocessed stdout. If there are no such cases -// (e.g. ExpectExit(), where we want to catch an exit ASAP), waitExtra should be false. -func (tt *TermTest) Exited(waitExtra bool) chan *cmdExit { - return waitChan(func() *cmdExit { - ticker := time.NewTicker(processExitPollInterval) - for { - select { - case <-ticker.C: - if tt.exited != nil { - if waitExtra { // allow sibling output consumer cases to handle their output - time.Sleep(processExitExtraWait) - } - return tt.exited - } - } - } - }) -} - func (tt *TermTest) errorHandler(rerr *error) { err := *rerr if err == nil { diff --git a/vendor/github.com/ActiveState/termtest/termtest_other.go b/vendor/github.com/ActiveState/termtest/termtest_other.go index 79cbc1bcce..21db974af0 100644 --- a/vendor/github.com/ActiveState/termtest/termtest_other.go +++ b/vendor/github.com/ActiveState/termtest/termtest_other.go @@ -12,7 +12,7 @@ func syscallErrorCode(err error) int { return -1 } -func (tt *TermTest) WaitIndefinitely() error { +func (tt *TermTest) waitIndefinitely() error { tt.opts.Logger.Println("WaitIndefinitely called") defer tt.opts.Logger.Println("WaitIndefinitely closed") diff --git a/vendor/github.com/ActiveState/termtest/termtest_windows.go b/vendor/github.com/ActiveState/termtest/termtest_windows.go index b767028a12..68ca81de02 100644 --- a/vendor/github.com/ActiveState/termtest/termtest_windows.go +++ b/vendor/github.com/ActiveState/termtest/termtest_windows.go @@ -16,10 +16,10 @@ func syscallErrorCode(err error) int { return 0 } -// WaitIndefinitely on Windows has to work around a Windows PTY bug where the PTY will NEVER exit by itself: +// waitIndefinitely on Windows has to work around a Windows PTY bug where the PTY will NEVER exit by itself: // https://github.com/photostorm/pty/issues/3 // Instead we wait for the process itself to exit, and after a grace period will shut down the pty. -func (tt *TermTest) WaitIndefinitely() error { +func (tt *TermTest) waitIndefinitely() error { tt.opts.Logger.Println("WaitIndefinitely called") defer tt.opts.Logger.Println("WaitIndefinitely closed") @@ -27,11 +27,6 @@ func (tt *TermTest) WaitIndefinitely() error { tt.opts.Logger.Printf("Waiting for PID %d to exit\n", tt.Cmd().Process.Pid) for { - // There is a race condition here; which is that the pty could still be processing the last of the output - // when the process exits. This sleep tries to work around this, but on slow hosts this may not be sufficient. - // This also gives some time in between process lookups - time.Sleep(100 * time.Millisecond) - // For some reason os.Process will always return a process even when the process has exited. // According to the docs this shouldn't happen, but here we are. // Using gopsutil seems to correctly identify the (not) running process. @@ -39,6 +34,14 @@ func (tt *TermTest) WaitIndefinitely() error { if err != nil { return fmt.Errorf("could not find process: %d: %w", tt.Cmd().Process.Pid, err) } + + // There is a race condition here; which is that the pty could still be processing the last of the output + // when the process exits. This sleep tries to work around this, but on slow hosts this may not be sufficient. + // We want this after the process state is asserted, but before we break out, to ensure we give at least the + // specified time AFTER the process has exited. + // This also povides time between process lookups. + time.Sleep(100 * time.Millisecond) + if !exists { break } diff --git a/vendor/github.com/bmatcuk/doublestar/v4/.codecov.yml b/vendor/github.com/bmatcuk/doublestar/v4/.codecov.yml new file mode 100644 index 0000000000..db6e504a9a --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/.codecov.yml @@ -0,0 +1,10 @@ +coverage: + status: + project: + default: + threshold: 1% + patch: + default: + target: 70% +ignore: + - globoptions.go diff --git a/vendor/go.mozilla.org/pkcs7/.gitignore b/vendor/github.com/bmatcuk/doublestar/v4/.gitignore similarity index 85% rename from vendor/go.mozilla.org/pkcs7/.gitignore rename to vendor/github.com/bmatcuk/doublestar/v4/.gitignore index daf913b1b3..af212ecc28 100644 --- a/vendor/go.mozilla.org/pkcs7/.gitignore +++ b/vendor/github.com/bmatcuk/doublestar/v4/.gitignore @@ -1,3 +1,8 @@ +# vi +*~ +*.swp +*.swo + # Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a @@ -22,3 +27,6 @@ _testmain.go *.exe *.test *.prof + +# test directory +test/ diff --git a/vendor/go.mozilla.org/pkcs7/LICENSE b/vendor/github.com/bmatcuk/doublestar/v4/LICENSE similarity index 97% rename from vendor/go.mozilla.org/pkcs7/LICENSE rename to vendor/github.com/bmatcuk/doublestar/v4/LICENSE index 75f3209085..309c9d1d11 100644 --- a/vendor/go.mozilla.org/pkcs7/LICENSE +++ b/vendor/github.com/bmatcuk/doublestar/v4/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 Andrew Smith +Copyright (c) 2014 Bob Matcuk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/bmatcuk/doublestar/v4/README.md b/vendor/github.com/bmatcuk/doublestar/v4/README.md new file mode 100644 index 0000000000..21929a9545 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/README.md @@ -0,0 +1,431 @@ +# doublestar + +Path pattern matching and globbing supporting `doublestar` (`**`) patterns. + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/bmatcuk/doublestar)](https://pkg.go.dev/github.com/bmatcuk/doublestar/v4) +[![Release](https://img.shields.io/github/release/bmatcuk/doublestar.svg?branch=master)](https://github.com/bmatcuk/doublestar/releases) +[![Build Status](https://github.com/bmatcuk/doublestar/actions/workflows/test.yml/badge.svg)](https://github.com/bmatcuk/doublestar/actions) +[![codecov.io](https://img.shields.io/codecov/c/github/bmatcuk/doublestar.svg?branch=master)](https://codecov.io/github/bmatcuk/doublestar?branch=master) +[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/bmatcuk) + +## About + +#### [Upgrading?](UPGRADING.md) + +**doublestar** is a [golang] implementation of path pattern matching and +globbing with support for "doublestar" (aka globstar: `**`) patterns. + +doublestar patterns match files and directories recursively. For example, if +you had the following directory structure: + +```bash +grandparent +`-- parent + |-- child1 + `-- child2 +``` + +You could find the children with patterns such as: `**/child*`, +`grandparent/**/child?`, `**/parent/*`, or even just `**` by itself (which will +return all files and directories recursively). + +Bash's globstar is doublestar's inspiration and, as such, works similarly. +Note that the doublestar must appear as a path component by itself. A pattern +such as `/path**` is invalid and will be treated the same as `/path*`, but +`/path*/**` should achieve the desired result. Additionally, `/path/**` will +match all directories and files under the path directory, but `/path/**/` will +only match directories. + +v4 is a complete rewrite with a focus on performance. Additionally, +[doublestar] has been updated to use the new [io/fs] package for filesystem +access. As a result, it is only supported by [golang] v1.16+. + +## Installation + +**doublestar** can be installed via `go get`: + +```bash +go get github.com/bmatcuk/doublestar/v4 +``` + +To use it in your code, you must import it: + +```go +import "github.com/bmatcuk/doublestar/v4" +``` + +## Usage + +### ErrBadPattern + +```go +doublestar.ErrBadPattern +``` + +Returned by various functions to report that the pattern is malformed. At the +moment, this value is equal to `path.ErrBadPattern`, but, for portability, this +equivalence should probably not be relied upon. + +### Match + +```go +func Match(pattern, name string) (bool, error) +``` + +Match returns true if `name` matches the file name `pattern` ([see +"patterns"]). `name` and `pattern` are split on forward slash (`/`) characters +and may be relative or absolute. + +Match requires pattern to match all of name, not just a substring. The only +possible returned error is `ErrBadPattern`, when pattern is malformed. + +Note: this is meant as a drop-in replacement for `path.Match()` which always +uses `'/'` as the path separator. If you want to support systems which use a +different path separator (such as Windows), what you want is `PathMatch()`. +Alternatively, you can run `filepath.ToSlash()` on both pattern and name and +then use this function. + +Note: users should _not_ count on the returned error, +`doublestar.ErrBadPattern`, being equal to `path.ErrBadPattern`. + + +### MatchUnvalidated + +```go +func MatchUnvalidated(pattern, name string) bool +``` + +MatchUnvalidated can provide a small performance improvement if you don't care +about whether or not the pattern is valid (perhaps because you already ran +`ValidatePattern`). Note that there's really only one case where this +performance improvement is realized: when pattern matching reaches the end of +`name` before reaching the end of `pattern`, such as `Match("a/b/c", "a")`. + + +### PathMatch + +```go +func PathMatch(pattern, name string) (bool, error) +``` + +PathMatch returns true if `name` matches the file name `pattern` ([see +"patterns"]). The difference between Match and PathMatch is that PathMatch will +automatically use your system's path separator to split `name` and `pattern`. +On systems where the path separator is `'\'`, escaping will be disabled. + +Note: this is meant as a drop-in replacement for `filepath.Match()`. It assumes +that both `pattern` and `name` are using the system's path separator. If you +can't be sure of that, use `filepath.ToSlash()` on both `pattern` and `name`, +and then use the `Match()` function instead. + + +### PathMatchUnvalidated + +```go +func PathMatchUnvalidated(pattern, name string) bool +``` + +PathMatchUnvalidated can provide a small performance improvement if you don't +care about whether or not the pattern is valid (perhaps because you already ran +`ValidatePattern`). Note that there's really only one case where this +performance improvement is realized: when pattern matching reaches the end of +`name` before reaching the end of `pattern`, such as `Match("a/b/c", "a")`. + + +### GlobOption + +Options that may be passed to `Glob`, `GlobWalk`, or `FilepathGlob`. Any number +of options may be passed to these functions, and in any order, as the last +argument(s). + +```go +WithFailOnIOErrors() +``` + +If passed, doublestar will abort and return IO errors when encountered. Note +that if the glob pattern references a path that does not exist (such as +`nonexistent/path/*`), this is _not_ considered an IO error: it is considered a +pattern with no matches. + +```go +WithFailOnPatternNotExist() +``` + +If passed, doublestar will abort and return `doublestar.ErrPatternNotExist` if +the pattern references a path that does not exist before any meta characters +such as `nonexistent/path/*`. Note that alts (ie, `{...}`) are expanded before +this check. In other words, a pattern such as `{a,b}/*` may fail if either `a` +or `b` do not exist but `*/{a,b}` will never fail because the star may match +nothing. + +```go +WithFilesOnly() +``` + +If passed, doublestar will only return "files" from `Glob`, `GlobWalk`, or +`FilepathGlob`. In this context, "files" are anything that is not a directory +or a symlink to a directory. + +Note: if combined with the WithNoFollow option, symlinks to directories _will_ +be included in the result since no attempt is made to follow the symlink. + +```go +WithNoFollow() +``` + +If passed, doublestar will not follow symlinks while traversing the filesystem. +However, due to io/fs's _very_ poor support for querying the filesystem about +symlinks, there's a caveat here: if part of the pattern before any meta +characters contains a reference to a symlink, it will be followed. For example, +a pattern such as `path/to/symlink/*` will be followed assuming it is a valid +symlink to a directory. However, from this same example, a pattern such as +`path/to/**` will not traverse the `symlink`, nor would `path/*/symlink/*` + +Note: if combined with the WithFilesOnly option, symlinks to directories _will_ +be included in the result since no attempt is made to follow the symlink. + +### Glob + +```go +func Glob(fsys fs.FS, pattern string, opts ...GlobOption) ([]string, error) +``` + +Glob returns the names of all files matching pattern or nil if there is no +matching file. The syntax of patterns is the same as in `Match()`. The pattern +may describe hierarchical names such as `usr/*/bin/ed`. + +Glob ignores file system errors such as I/O errors reading directories by +default. The only possible returned error is `ErrBadPattern`, reporting that +the pattern is malformed. + +To enable aborting on I/O errors, the `WithFailOnIOErrors` option can be +passed. + +Note: this is meant as a drop-in replacement for `io/fs.Glob()`. Like +`io/fs.Glob()`, this function assumes that your pattern uses `/` as the path +separator even if that's not correct for your OS (like Windows). If you aren't +sure if that's the case, you can use `filepath.ToSlash()` on your pattern +before calling `Glob()`. + +Like `io/fs.Glob()`, patterns containing `/./`, `/../`, or starting with `/` +will return no results and no errors. This seems to be a [conscious +decision](https://github.com/golang/go/issues/44092#issuecomment-774132549), +even if counter-intuitive. You can use [SplitPattern] to divide a pattern into +a base path (to initialize an `FS` object) and pattern. + +Note: users should _not_ count on the returned error, +`doublestar.ErrBadPattern`, being equal to `path.ErrBadPattern`. + +### GlobWalk + +```go +type GlobWalkFunc func(path string, d fs.DirEntry) error + +func GlobWalk(fsys fs.FS, pattern string, fn GlobWalkFunc, opts ...GlobOption) error +``` + +GlobWalk calls the callback function `fn` for every file matching pattern. The +syntax of pattern is the same as in Match() and the behavior is the same as +Glob(), with regard to limitations (such as patterns containing `/./`, `/../`, +or starting with `/`). The pattern may describe hierarchical names such as +usr/*/bin/ed. + +GlobWalk may have a small performance benefit over Glob if you do not need a +slice of matches because it can avoid allocating memory for the matches. +Additionally, GlobWalk gives you access to the `fs.DirEntry` objects for each +match, and lets you quit early by returning a non-nil error from your callback +function. Like `io/fs.WalkDir`, if your callback returns `SkipDir`, GlobWalk +will skip the current directory. This means that if the current path _is_ a +directory, GlobWalk will not recurse into it. If the current path is not a +directory, the rest of the parent directory will be skipped. + +GlobWalk ignores file system errors such as I/O errors reading directories by +default. GlobWalk may return `ErrBadPattern`, reporting that the pattern is +malformed. + +To enable aborting on I/O errors, the `WithFailOnIOErrors` option can be +passed. + +Additionally, if the callback function `fn` returns an error, GlobWalk will +exit immediately and return that error. + +Like Glob(), this function assumes that your pattern uses `/` as the path +separator even if that's not correct for your OS (like Windows). If you aren't +sure if that's the case, you can use filepath.ToSlash() on your pattern before +calling GlobWalk(). + +Note: users should _not_ count on the returned error, +`doublestar.ErrBadPattern`, being equal to `path.ErrBadPattern`. + +### FilepathGlob + +```go +func FilepathGlob(pattern string, opts ...GlobOption) (matches []string, err error) +``` + +FilepathGlob returns the names of all files matching pattern or nil if there is +no matching file. The syntax of pattern is the same as in Match(). The pattern +may describe hierarchical names such as usr/*/bin/ed. + +FilepathGlob ignores file system errors such as I/O errors reading directories +by default. The only possible returned error is `ErrBadPattern`, reporting that +the pattern is malformed. + +To enable aborting on I/O errors, the `WithFailOnIOErrors` option can be +passed. + +Note: FilepathGlob is a convenience function that is meant as a drop-in +replacement for `path/filepath.Glob()` for users who don't need the +complication of io/fs. Basically, it: + +* Runs `filepath.Clean()` and `ToSlash()` on the pattern +* Runs `SplitPattern()` to get a base path and a pattern to Glob +* Creates an FS object from the base path and `Glob()s` on the pattern +* Joins the base path with all of the matches from `Glob()` + +Returned paths will use the system's path separator, just like +`filepath.Glob()`. + +Note: the returned error `doublestar.ErrBadPattern` is not equal to +`filepath.ErrBadPattern`. + +### SplitPattern + +```go +func SplitPattern(p string) (base, pattern string) +``` + +SplitPattern is a utility function. Given a pattern, SplitPattern will return +two strings: the first string is everything up to the last slash (`/`) that +appears _before_ any unescaped "meta" characters (ie, `*?[{`). The second +string is everything after that slash. For example, given the pattern: + +``` +../../path/to/meta*/** + ^----------- split here +``` + +SplitPattern returns "../../path/to" and "meta*/**". This is useful for +initializing os.DirFS() to call Glob() because Glob() will silently fail if +your pattern includes `/./` or `/../`. For example: + +```go +base, pattern := SplitPattern("../../path/to/meta*/**") +fsys := os.DirFS(base) +matches, err := Glob(fsys, pattern) +``` + +If SplitPattern cannot find somewhere to split the pattern (for example, +`meta*/**`), it will return "." and the unaltered pattern (`meta*/**` in this +example). + +Of course, it is your responsibility to decide if the returned base path is +"safe" in the context of your application. Perhaps you could use Match() to +validate against a list of approved base directories? + +### ValidatePattern + +```go +func ValidatePattern(s string) bool +``` + +Validate a pattern. Patterns are validated while they run in Match(), +PathMatch(), and Glob(), so, you normally wouldn't need to call this. However, +there are cases where this might be useful: for example, if your program allows +a user to enter a pattern that you'll run at a later time, you might want to +validate it. + +ValidatePattern assumes your pattern uses '/' as the path separator. + +### ValidatePathPattern + +```go +func ValidatePathPattern(s string) bool +``` + +Like ValidatePattern, only uses your OS path separator. In other words, use +ValidatePattern if you would normally use Match() or Glob(). Use +ValidatePathPattern if you would normally use PathMatch(). Keep in mind, Glob() +requires '/' separators, even if your OS uses something else. + +### Patterns + +**doublestar** supports the following special terms in the patterns: + +Special Terms | Meaning +------------- | ------- +`*` | matches any sequence of non-path-separators +`/**/` | matches zero or more directories +`?` | matches any single non-path-separator character +`[class]` | matches any single non-path-separator character against a class of characters ([see "character classes"]) +`{alt1,...}` | matches a sequence of characters if one of the comma-separated alternatives matches + +Any character with a special meaning can be escaped with a backslash (`\`). + +A doublestar (`**`) should appear surrounded by path separators such as `/**/`. +A mid-pattern doublestar (`**`) behaves like bash's globstar option: a pattern +such as `path/to/**.txt` would return the same results as `path/to/*.txt`. The +pattern you're looking for is `path/to/**/*.txt`. + +#### Character Classes + +Character classes support the following: + +Class | Meaning +---------- | ------- +`[abc]` | matches any single character within the set +`[a-z]` | matches any single character in the range +`[^class]` | matches any single character which does *not* match the class +`[!class]` | same as `^`: negates the class + +## Performance + +``` +goos: darwin +goarch: amd64 +pkg: github.com/bmatcuk/doublestar/v4 +cpu: Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz +BenchmarkMatch-8 285639 3868 ns/op 0 B/op 0 allocs/op +BenchmarkGoMatch-8 286945 3726 ns/op 0 B/op 0 allocs/op +BenchmarkPathMatch-8 320511 3493 ns/op 0 B/op 0 allocs/op +BenchmarkGoPathMatch-8 304236 3434 ns/op 0 B/op 0 allocs/op +BenchmarkGlob-8 466 2501123 ns/op 190225 B/op 2849 allocs/op +BenchmarkGlobWalk-8 476 2536293 ns/op 184017 B/op 2750 allocs/op +BenchmarkGoGlob-8 463 2574836 ns/op 194249 B/op 2929 allocs/op +``` + +These benchmarks (in `doublestar_test.go`) compare Match() to path.Match(), +PathMath() to filepath.Match(), and Glob() + GlobWalk() to io/fs.Glob(). They +only run patterns that the standard go packages can understand as well (so, no +`{alts}` or `**`) for a fair comparison. Of course, alts and doublestars will +be less performant than the other pattern meta characters. + +Alts are essentially like running multiple patterns, the number of which can +get large if your pattern has alts nested inside alts. This affects both +matching (ie, Match()) and globbing (Glob()). + +`**` performance in matching is actually pretty similar to a regular `*`, but +can cause a large number of reads when globbing as it will need to recursively +traverse your filesystem. + +## Sponsors +I started this project in 2014 in my spare time and have been maintaining it +ever since. In that time, it has grown into one of the most popular globbing +libraries in the Go ecosystem. So, if **doublestar** is a useful library in +your project, consider [sponsoring] my work! I'd really appreciate it! + +[![MASV](../sponsors/MASV.png?raw=true)](https://massive.io/) + +Thanks for sponsoring me! + +## License + +[MIT License](LICENSE) + +[SplitPattern]: #splitpattern +[doublestar]: https://github.com/bmatcuk/doublestar +[golang]: http://golang.org/ +[io/fs]: https://pkg.go.dev/io/fs +[see "character classes"]: #character-classes +[see "patterns"]: #patterns +[sponsoring]: https://github.com/sponsors/bmatcuk diff --git a/vendor/github.com/bmatcuk/doublestar/v4/UPGRADING.md b/vendor/github.com/bmatcuk/doublestar/v4/UPGRADING.md new file mode 100644 index 0000000000..25aace3db0 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/UPGRADING.md @@ -0,0 +1,63 @@ +# Upgrading from v3 to v4 + +v4 is a complete rewrite with a focus on performance. Additionally, +[doublestar] has been updated to use the new [io/fs] package for filesystem +access. As a result, it is only supported by [golang] v1.16+. + +`Match()` and `PathMatch()` mostly did not change, besides big performance +improvements. Their API is the same. However, note the following corner cases: + +* In previous versions of [doublestar], `PathMatch()` could accept patterns + that used either platform-specific path separators, or `/`. This was + undocumented and didn't match `filepath.Match()`. In v4, both `pattern` and + `name` must be using appropriate path separators for the platform. You can + use `filepath.FromSlash()` to change `/` to platform-specific separators if + you aren't sure. +* In previous versions of [doublestar], a pattern such as `path/to/a/**` would + _not_ match `path/to/a`. In v4, this pattern _will_ match because if `a` was + a directory, `Glob()` would return it. In other words, the following returns + true: `Match("path/to/a/**", "path/to/a")` + +`Glob()` changed from using a [doublestar]-specific filesystem abstraction (the +`OS` interface) to the [io/fs] package. As a result, it now takes a `fs.FS` as +its first argument. This change has a couple ramifications: + +* Like `io/fs.Glob`, `pattern` must use a `/` as path separator, even on + platforms that use something else. You can use `filepath.ToSlash()` on your + patterns if you aren't sure. +* Patterns that contain `/./` or `/../` are invalid. The [io/fs] package + rejects them, returning an IO error. Since `Glob()` ignores IO errors, it'll + end up being silently rejected. You can run `path.Clean()` to ensure they are + removed from the pattern. + +v4 also added a `GlobWalk()` function that is slightly more performant than +`Glob()` if you just need to iterate over the results and don't need a string +slice. You also get `fs.DirEntry` objects for each result, and can quit early +if your callback returns an error. + +# Upgrading from v2 to v3 + +v3 introduced using `!` to negate character classes, in addition to `^`. If any +of your patterns include a character class that starts with an exclamation mark +(ie, `[!...]`), you'll need to update the pattern to escape or move the +exclamation mark. Note that, like the caret (`^`), it only negates the +character class if it is the first character in the character class. + +# Upgrading from v1 to v2 + +The change from v1 to v2 was fairly minor: the return type of the `Open` method +on the `OS` interface was changed from `*os.File` to `File`, a new interface +exported by doublestar. The new `File` interface only defines the functionality +doublestar actually needs (`io.Closer` and `Readdir`), making it easier to use +doublestar with [go-billy], [afero], or something similar. If you were using +this functionality, updating should be as easy as updating `Open's` return +type, since `os.File` already implements `doublestar.File`. + +If you weren't using this functionality, updating should be as easy as changing +your dependencies to point to v2. + +[afero]: https://github.com/spf13/afero +[doublestar]: https://github.com/bmatcuk/doublestar +[go-billy]: https://github.com/src-d/go-billy +[golang]: http://golang.org/ +[io/fs]: https://golang.org/pkg/io/fs/ diff --git a/vendor/github.com/bmatcuk/doublestar/v4/doublestar.go b/vendor/github.com/bmatcuk/doublestar/v4/doublestar.go new file mode 100644 index 0000000000..210fd40ceb --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/doublestar.go @@ -0,0 +1,13 @@ +package doublestar + +import ( + "errors" + "path" +) + +// ErrBadPattern indicates a pattern was malformed. +var ErrBadPattern = path.ErrBadPattern + +// ErrPatternNotExist indicates that the pattern passed to Glob, GlobWalk, or +// FilepathGlob references a path that does not exist. +var ErrPatternNotExist = errors.New("pattern does not exist") diff --git a/vendor/github.com/bmatcuk/doublestar/v4/glob.go b/vendor/github.com/bmatcuk/doublestar/v4/glob.go new file mode 100644 index 0000000000..519601b15c --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/glob.go @@ -0,0 +1,473 @@ +package doublestar + +import ( + "errors" + "io/fs" + "path" +) + +// Glob returns the names of all files matching pattern or nil if there is no +// matching file. The syntax of pattern is the same as in Match(). The pattern +// may describe hierarchical names such as usr/*/bin/ed. +// +// Glob ignores file system errors such as I/O errors reading directories by +// default. The only possible returned error is ErrBadPattern, reporting that +// the pattern is malformed. +// +// To enable aborting on I/O errors, the WithFailOnIOErrors option can be +// passed. +// +// Note: this is meant as a drop-in replacement for io/fs.Glob(). Like +// io/fs.Glob(), this function assumes that your pattern uses `/` as the path +// separator even if that's not correct for your OS (like Windows). If you +// aren't sure if that's the case, you can use filepath.ToSlash() on your +// pattern before calling Glob(). +// +// Like `io/fs.Glob()`, patterns containing `/./`, `/../`, or starting with `/` +// will return no results and no errors. You can use SplitPattern to divide a +// pattern into a base path (to initialize an `FS` object) and pattern. +// +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +// +func Glob(fsys fs.FS, pattern string, opts ...GlobOption) ([]string, error) { + if !ValidatePattern(pattern) { + return nil, ErrBadPattern + } + + g := newGlob(opts...) + + if hasMidDoubleStar(pattern) { + // If the pattern has a `**` anywhere but the very end, GlobWalk is more + // performant because it can get away with less allocations. If the pattern + // ends in a `**`, both methods are pretty much the same, but Glob has a + // _very_ slight advantage because of lower function call overhead. + var matches []string + err := g.doGlobWalk(fsys, pattern, true, true, func(p string, d fs.DirEntry) error { + matches = append(matches, p) + return nil + }) + return matches, err + } + return g.doGlob(fsys, pattern, nil, true, true) +} + +// Does the actual globbin' +// - firstSegment is true if we're in the first segment of the pattern, ie, +// the right-most part where we can match files. If it's false, we're +// somewhere in the middle (or at the beginning) and can only match +// directories since there are path segments above us. +// - beforeMeta is true if we're exploring segments before any meta +// characters, ie, in a pattern such as `path/to/file*.txt`, the `path/to/` +// bit does not contain any meta characters. +func (g *glob) doGlob(fsys fs.FS, pattern string, m []string, firstSegment, beforeMeta bool) (matches []string, err error) { + matches = m + patternStart := indexMeta(pattern) + if patternStart == -1 { + // pattern doesn't contain any meta characters - does a file matching the + // pattern exist? + // The pattern may contain escaped wildcard characters for an exact path match. + path := unescapeMeta(pattern) + pathInfo, pathExists, pathErr := g.exists(fsys, path, beforeMeta) + if pathErr != nil { + return nil, pathErr + } + + if pathExists && (!firstSegment || !g.filesOnly || !pathInfo.IsDir()) { + matches = append(matches, path) + } + + return + } + + dir := "." + splitIdx := lastIndexSlashOrAlt(pattern) + if splitIdx != -1 { + if pattern[splitIdx] == '}' { + openingIdx := indexMatchedOpeningAlt(pattern[:splitIdx]) + if openingIdx == -1 { + // if there's no matching opening index, technically Match() will treat + // an unmatched `}` as nothing special, so... we will, too! + splitIdx = lastIndexSlash(pattern[:splitIdx]) + if splitIdx != -1 { + dir = pattern[:splitIdx] + pattern = pattern[splitIdx+1:] + } + } else { + // otherwise, we have to handle the alts: + return g.globAlts(fsys, pattern, openingIdx, splitIdx, matches, firstSegment, beforeMeta) + } + } else { + dir = pattern[:splitIdx] + pattern = pattern[splitIdx+1:] + } + } + + // if `splitIdx` is less than `patternStart`, we know `dir` has no meta + // characters. They would be equal if they are both -1, which means `dir` + // will be ".", and we know that doesn't have meta characters either. + if splitIdx <= patternStart { + return g.globDir(fsys, dir, pattern, matches, firstSegment, beforeMeta) + } + + var dirs []string + dirs, err = g.doGlob(fsys, dir, matches, false, beforeMeta) + if err != nil { + return + } + for _, d := range dirs { + matches, err = g.globDir(fsys, d, pattern, matches, firstSegment, false) + if err != nil { + return + } + } + + return +} + +// handle alts in the glob pattern - `openingIdx` and `closingIdx` are the +// indexes of `{` and `}`, respectively +func (g *glob) globAlts(fsys fs.FS, pattern string, openingIdx, closingIdx int, m []string, firstSegment, beforeMeta bool) (matches []string, err error) { + matches = m + + var dirs []string + startIdx := 0 + afterIdx := closingIdx + 1 + splitIdx := lastIndexSlashOrAlt(pattern[:openingIdx]) + if splitIdx == -1 || pattern[splitIdx] == '}' { + // no common prefix + dirs = []string{""} + } else { + // our alts have a common prefix that we can process first + dirs, err = g.doGlob(fsys, pattern[:splitIdx], matches, false, beforeMeta) + if err != nil { + return + } + + startIdx = splitIdx + 1 + } + + for _, d := range dirs { + patIdx := openingIdx + 1 + altResultsStartIdx := len(matches) + thisResultStartIdx := altResultsStartIdx + for patIdx < closingIdx { + nextIdx := indexNextAlt(pattern[patIdx:closingIdx], true) + if nextIdx == -1 { + nextIdx = closingIdx + } else { + nextIdx += patIdx + } + + alt := buildAlt(d, pattern, startIdx, openingIdx, patIdx, nextIdx, afterIdx) + matches, err = g.doGlob(fsys, alt, matches, firstSegment, beforeMeta) + if err != nil { + return + } + + matchesLen := len(matches) + if altResultsStartIdx != thisResultStartIdx && thisResultStartIdx != matchesLen { + // Alts can result in matches that aren't sorted, or, worse, duplicates + // (consider the trivial pattern `path/to/{a,*}`). Since doGlob returns + // sorted results, we can do a sort of in-place merge and remove + // duplicates. But, we only need to do this if this isn't the first alt + // (ie, `altResultsStartIdx != thisResultsStartIdx`) and if the latest + // alt actually added some matches (`thisResultStartIdx != + // len(matches)`) + matches = sortAndRemoveDups(matches, altResultsStartIdx, thisResultStartIdx, matchesLen) + + // length of matches may have changed + thisResultStartIdx = len(matches) + } else { + thisResultStartIdx = matchesLen + } + + patIdx = nextIdx + 1 + } + } + + return +} + +// find files/subdirectories in the given `dir` that match `pattern` +func (g *glob) globDir(fsys fs.FS, dir, pattern string, matches []string, canMatchFiles, beforeMeta bool) (m []string, e error) { + m = matches + + if pattern == "" { + if !canMatchFiles || !g.filesOnly { + // pattern can be an empty string if the original pattern ended in a + // slash, in which case, we should just return dir, but only if it + // actually exists and it's a directory (or a symlink to a directory) + _, isDir, err := g.isPathDir(fsys, dir, beforeMeta) + if err != nil { + return nil, err + } + if isDir { + m = append(m, dir) + } + } + return + } + + if pattern == "**" { + return g.globDoubleStar(fsys, dir, m, canMatchFiles, beforeMeta) + } + + dirs, err := fs.ReadDir(fsys, dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + e = g.handlePatternNotExist(beforeMeta) + } else { + e = g.forwardErrIfFailOnIOErrors(err) + } + return + } + + var matched bool + for _, info := range dirs { + name := info.Name() + matched, e = matchWithSeparator(pattern, name, '/', false) + if e != nil { + return + } + if matched { + matched = canMatchFiles + if !matched || g.filesOnly { + matched, e = g.isDir(fsys, dir, name, info) + if e != nil { + return + } + if canMatchFiles { + // if we're here, it's because g.filesOnly + // is set and we don't want directories + matched = !matched + } + } + if matched { + m = append(m, path.Join(dir, name)) + } + } + } + + return +} + +func (g *glob) globDoubleStar(fsys fs.FS, dir string, matches []string, canMatchFiles, beforeMeta bool) ([]string, error) { + dirs, err := fs.ReadDir(fsys, dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return matches, g.handlePatternNotExist(beforeMeta) + } else { + return matches, g.forwardErrIfFailOnIOErrors(err) + } + } + + if !g.filesOnly { + // `**` can match *this* dir, so add it + matches = append(matches, dir) + } + + for _, info := range dirs { + name := info.Name() + isDir, err := g.isDir(fsys, dir, name, info) + if err != nil { + return nil, err + } + if isDir { + matches, err = g.globDoubleStar(fsys, path.Join(dir, name), matches, canMatchFiles, false) + if err != nil { + return nil, err + } + } else if canMatchFiles { + matches = append(matches, path.Join(dir, name)) + } + } + + return matches, nil +} + +// Returns true if the pattern has a doublestar in the middle of the pattern. +// In this case, GlobWalk is faster because it can get away with less +// allocations. However, Glob has a _very_ slight edge if the pattern ends in +// `**`. +func hasMidDoubleStar(p string) bool { + // subtract 3: 2 because we want to return false if the pattern ends in `**` + // (Glob is _very_ slightly faster in that case), and the extra 1 because our + // loop checks p[i] and p[i+1]. + l := len(p) - 3 + for i := 0; i < l; i++ { + if p[i] == '\\' { + // escape next byte + i++ + } else if p[i] == '*' && p[i+1] == '*' { + return true + } + } + return false +} + +// Returns the index of the first unescaped meta character, or negative 1. +func indexMeta(s string) int { + var c byte + l := len(s) + for i := 0; i < l; i++ { + c = s[i] + if c == '*' || c == '?' || c == '[' || c == '{' { + return i + } else if c == '\\' { + // skip next byte + i++ + } + } + return -1 +} + +// Returns the index of the last unescaped slash or closing alt (`}`) in the +// string, or negative 1. +func lastIndexSlashOrAlt(s string) int { + for i := len(s) - 1; i >= 0; i-- { + if (s[i] == '/' || s[i] == '}') && (i == 0 || s[i-1] != '\\') { + return i + } + } + return -1 +} + +// Returns the index of the last unescaped slash in the string, or negative 1. +func lastIndexSlash(s string) int { + for i := len(s) - 1; i >= 0; i-- { + if s[i] == '/' && (i == 0 || s[i-1] != '\\') { + return i + } + } + return -1 +} + +// Assuming the byte after the end of `s` is a closing `}`, this function will +// find the index of the matching `{`. That is, it'll skip over any nested `{}` +// and account for escaping. +func indexMatchedOpeningAlt(s string) int { + alts := 1 + for i := len(s) - 1; i >= 0; i-- { + if s[i] == '}' && (i == 0 || s[i-1] != '\\') { + alts++ + } else if s[i] == '{' && (i == 0 || s[i-1] != '\\') { + if alts--; alts == 0 { + return i + } + } + } + return -1 +} + +// Returns true if the path exists +func (g *glob) exists(fsys fs.FS, name string, beforeMeta bool) (fs.FileInfo, bool, error) { + // name might end in a slash, but Stat doesn't like that + namelen := len(name) + if namelen > 1 && name[namelen-1] == '/' { + name = name[:namelen-1] + } + + info, err := fs.Stat(fsys, name) + if errors.Is(err, fs.ErrNotExist) { + return nil, false, g.handlePatternNotExist(beforeMeta) + } + return info, err == nil, g.forwardErrIfFailOnIOErrors(err) +} + +// Returns true if the path exists and is a directory or a symlink to a +// directory +func (g *glob) isPathDir(fsys fs.FS, name string, beforeMeta bool) (fs.FileInfo, bool, error) { + info, err := fs.Stat(fsys, name) + if errors.Is(err, fs.ErrNotExist) { + return nil, false, g.handlePatternNotExist(beforeMeta) + } + return info, err == nil && info.IsDir(), g.forwardErrIfFailOnIOErrors(err) +} + +// Returns whether or not the given DirEntry is a directory. If the DirEntry +// represents a symbolic link, the link is followed by running fs.Stat() on +// `path.Join(dir, name)` (if dir is "", name will be used without joining) +func (g *glob) isDir(fsys fs.FS, dir, name string, info fs.DirEntry) (bool, error) { + if !g.noFollow && (info.Type()&fs.ModeSymlink) > 0 { + p := name + if dir != "" { + p = path.Join(dir, name) + } + finfo, err := fs.Stat(fsys, p) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + // this function is only ever called while expanding a glob, so it can + // never return ErrPatternNotExist + return false, nil + } + return false, g.forwardErrIfFailOnIOErrors(err) + } + return finfo.IsDir(), nil + } + return info.IsDir(), nil +} + +// Builds a string from an alt +func buildAlt(prefix, pattern string, startIdx, openingIdx, currentIdx, nextIdx, afterIdx int) string { + // pattern: + // ignored/start{alts,go,here}remaining - len = 36 + // | | | | ^--- afterIdx = 27 + // | | | \--------- nextIdx = 21 + // | | \----------- currentIdx = 19 + // | \----------------- openingIdx = 13 + // \---------------------- startIdx = 8 + // + // result: + // prefix/startgoremaining - len = 7 + 5 + 2 + 9 = 23 + var buf []byte + patLen := len(pattern) + size := (openingIdx - startIdx) + (nextIdx - currentIdx) + (patLen - afterIdx) + if prefix != "" && prefix != "." { + buf = make([]byte, 0, size+len(prefix)+1) + buf = append(buf, prefix...) + buf = append(buf, '/') + } else { + buf = make([]byte, 0, size) + } + buf = append(buf, pattern[startIdx:openingIdx]...) + buf = append(buf, pattern[currentIdx:nextIdx]...) + if afterIdx < patLen { + buf = append(buf, pattern[afterIdx:]...) + } + return string(buf) +} + +// Running alts can produce results that are not sorted, and, worse, can cause +// duplicates (consider the trivial pattern `path/to/{a,*}`). Since we know +// each run of doGlob is sorted, we can basically do the "merge" step of a +// merge sort in-place. +func sortAndRemoveDups(matches []string, idx1, idx2, l int) []string { + var tmp string + for ; idx1 < idx2; idx1++ { + if matches[idx1] < matches[idx2] { + // order is correct + continue + } else if matches[idx1] > matches[idx2] { + // need to swap and then re-sort matches above idx2 + tmp = matches[idx1] + matches[idx1] = matches[idx2] + + shft := idx2 + 1 + for ; shft < l && matches[shft] < tmp; shft++ { + matches[shft-1] = matches[shft] + } + matches[shft-1] = tmp + } else { + // duplicate - shift matches above idx2 down one and decrement l + for shft := idx2 + 1; shft < l; shft++ { + matches[shft-1] = matches[shft] + } + if l--; idx2 == l { + // nothing left to do... matches[idx2:] must have been full of dups + break + } + } + } + return matches[:l] +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/globoptions.go b/vendor/github.com/bmatcuk/doublestar/v4/globoptions.go new file mode 100644 index 0000000000..9483c4bb00 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/globoptions.go @@ -0,0 +1,144 @@ +package doublestar + +import "strings" + +// glob is an internal type to store options during globbing. +type glob struct { + failOnIOErrors bool + failOnPatternNotExist bool + filesOnly bool + noFollow bool +} + +// GlobOption represents a setting that can be passed to Glob, GlobWalk, and +// FilepathGlob. +type GlobOption func(*glob) + +// Construct a new glob object with the given options +func newGlob(opts ...GlobOption) *glob { + g := &glob{} + for _, opt := range opts { + opt(g) + } + return g +} + +// WithFailOnIOErrors is an option that can be passed to Glob, GlobWalk, or +// FilepathGlob. If passed, doublestar will abort and return IO errors when +// encountered. Note that if the glob pattern references a path that does not +// exist (such as `nonexistent/path/*`), this is _not_ considered an IO error: +// it is considered a pattern with no matches. +// +func WithFailOnIOErrors() GlobOption { + return func(g *glob) { + g.failOnIOErrors = true + } +} + +// WithFailOnPatternNotExist is an option that can be passed to Glob, GlobWalk, +// or FilepathGlob. If passed, doublestar will abort and return +// ErrPatternNotExist if the pattern references a path that does not exist +// before any meta charcters such as `nonexistent/path/*`. Note that alts (ie, +// `{...}`) are expanded before this check. In other words, a pattern such as +// `{a,b}/*` may fail if either `a` or `b` do not exist but `*/{a,b}` will +// never fail because the star may match nothing. +// +func WithFailOnPatternNotExist() GlobOption { + return func(g *glob) { + g.failOnPatternNotExist = true + } +} + +// WithFilesOnly is an option that can be passed to Glob, GlobWalk, or +// FilepathGlob. If passed, doublestar will only return files that match the +// pattern, not directories. +// +// Note: if combined with the WithNoFollow option, symlinks to directories +// _will_ be included in the result since no attempt is made to follow the +// symlink. +// +func WithFilesOnly() GlobOption { + return func(g *glob) { + g.filesOnly = true + } +} + +// WithNoFollow is an option that can be passed to Glob, GlobWalk, or +// FilepathGlob. If passed, doublestar will not follow symlinks while +// traversing the filesystem. However, due to io/fs's _very_ poor support for +// querying the filesystem about symlinks, there's a caveat here: if part of +// the pattern before any meta characters contains a reference to a symlink, it +// will be followed. For example, a pattern such as `path/to/symlink/*` will be +// followed assuming it is a valid symlink to a directory. However, from this +// same example, a pattern such as `path/to/**` will not traverse the +// `symlink`, nor would `path/*/symlink/*` +// +// Note: if combined with the WithFilesOnly option, symlinks to directories +// _will_ be included in the result since no attempt is made to follow the +// symlink. +// +func WithNoFollow() GlobOption { + return func(g *glob) { + g.noFollow = true + } +} + +// forwardErrIfFailOnIOErrors is used to wrap the return values of I/O +// functions. When failOnIOErrors is enabled, it will return err; otherwise, it +// always returns nil. +// +func (g *glob) forwardErrIfFailOnIOErrors(err error) error { + if g.failOnIOErrors { + return err + } + return nil +} + +// handleErrNotExist handles fs.ErrNotExist errors. If +// WithFailOnPatternNotExist has been enabled and canFail is true, this will +// return ErrPatternNotExist. Otherwise, it will return nil. +// +func (g *glob) handlePatternNotExist(canFail bool) error { + if canFail && g.failOnPatternNotExist { + return ErrPatternNotExist + } + return nil +} + +// Format options for debugging/testing purposes +func (g *glob) GoString() string { + var b strings.Builder + b.WriteString("opts: ") + + hasOpts := false + if g.failOnIOErrors { + b.WriteString("WithFailOnIOErrors") + hasOpts = true + } + if g.failOnPatternNotExist { + if hasOpts { + b.WriteString(", ") + } + b.WriteString("WithFailOnPatternNotExist") + hasOpts = true + } + if g.filesOnly { + if hasOpts { + b.WriteString(", ") + } + b.WriteString("WithFilesOnly") + hasOpts = true + } + if g.noFollow { + if hasOpts { + b.WriteString(", ") + } + b.WriteString("WithNoFollow") + hasOpts = true + } + + if !hasOpts { + b.WriteString("nil") + } + return b.String() +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go b/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go new file mode 100644 index 0000000000..84e764f0e2 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go @@ -0,0 +1,414 @@ +package doublestar + +import ( + "errors" + "io/fs" + "path" + "path/filepath" + "strings" +) + +// If returned from GlobWalkFunc, will cause GlobWalk to skip the current +// directory. In other words, if the current path is a directory, GlobWalk will +// not recurse into it. Otherwise, GlobWalk will skip the rest of the current +// directory. +var SkipDir = fs.SkipDir + +// Callback function for GlobWalk(). If the function returns an error, GlobWalk +// will end immediately and return the same error. +type GlobWalkFunc func(path string, d fs.DirEntry) error + +// GlobWalk calls the callback function `fn` for every file matching pattern. +// The syntax of pattern is the same as in Match() and the behavior is the same +// as Glob(), with regard to limitations (such as patterns containing `/./`, +// `/../`, or starting with `/`). The pattern may describe hierarchical names +// such as usr/*/bin/ed. +// +// GlobWalk may have a small performance benefit over Glob if you do not need a +// slice of matches because it can avoid allocating memory for the matches. +// Additionally, GlobWalk gives you access to the `fs.DirEntry` objects for +// each match, and lets you quit early by returning a non-nil error from your +// callback function. Like `io/fs.WalkDir`, if your callback returns `SkipDir`, +// GlobWalk will skip the current directory. This means that if the current +// path _is_ a directory, GlobWalk will not recurse into it. If the current +// path is not a directory, the rest of the parent directory will be skipped. +// +// GlobWalk ignores file system errors such as I/O errors reading directories +// by default. GlobWalk may return ErrBadPattern, reporting that the pattern is +// malformed. +// +// To enable aborting on I/O errors, the WithFailOnIOErrors option can be +// passed. +// +// Additionally, if the callback function `fn` returns an error, GlobWalk will +// exit immediately and return that error. +// +// Like Glob(), this function assumes that your pattern uses `/` as the path +// separator even if that's not correct for your OS (like Windows). If you +// aren't sure if that's the case, you can use filepath.ToSlash() on your +// pattern before calling GlobWalk(). +// +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +// +func GlobWalk(fsys fs.FS, pattern string, fn GlobWalkFunc, opts ...GlobOption) error { + if !ValidatePattern(pattern) { + return ErrBadPattern + } + + g := newGlob(opts...) + return g.doGlobWalk(fsys, pattern, true, true, fn) +} + +// Actually execute GlobWalk +// - firstSegment is true if we're in the first segment of the pattern, ie, +// the right-most part where we can match files. If it's false, we're +// somewhere in the middle (or at the beginning) and can only match +// directories since there are path segments above us. +// - beforeMeta is true if we're exploring segments before any meta +// characters, ie, in a pattern such as `path/to/file*.txt`, the `path/to/` +// bit does not contain any meta characters. +func (g *glob) doGlobWalk(fsys fs.FS, pattern string, firstSegment, beforeMeta bool, fn GlobWalkFunc) error { + patternStart := indexMeta(pattern) + if patternStart == -1 { + // pattern doesn't contain any meta characters - does a file matching the + // pattern exist? + // The pattern may contain escaped wildcard characters for an exact path match. + path := unescapeMeta(pattern) + info, pathExists, err := g.exists(fsys, path, beforeMeta) + if pathExists && (!firstSegment || !g.filesOnly || !info.IsDir()) { + err = fn(path, dirEntryFromFileInfo(info)) + if err == SkipDir { + err = nil + } + } + return err + } + + dir := "." + splitIdx := lastIndexSlashOrAlt(pattern) + if splitIdx != -1 { + if pattern[splitIdx] == '}' { + openingIdx := indexMatchedOpeningAlt(pattern[:splitIdx]) + if openingIdx == -1 { + // if there's no matching opening index, technically Match() will treat + // an unmatched `}` as nothing special, so... we will, too! + splitIdx = lastIndexSlash(pattern[:splitIdx]) + if splitIdx != -1 { + dir = pattern[:splitIdx] + pattern = pattern[splitIdx+1:] + } + } else { + // otherwise, we have to handle the alts: + return g.globAltsWalk(fsys, pattern, openingIdx, splitIdx, firstSegment, beforeMeta, fn) + } + } else { + dir = pattern[:splitIdx] + pattern = pattern[splitIdx+1:] + } + } + + // if `splitIdx` is less than `patternStart`, we know `dir` has no meta + // characters. They would be equal if they are both -1, which means `dir` + // will be ".", and we know that doesn't have meta characters either. + if splitIdx <= patternStart { + return g.globDirWalk(fsys, dir, pattern, firstSegment, beforeMeta, fn) + } + + return g.doGlobWalk(fsys, dir, false, beforeMeta, func(p string, d fs.DirEntry) error { + if err := g.globDirWalk(fsys, p, pattern, firstSegment, false, fn); err != nil { + return err + } + return nil + }) +} + +// handle alts in the glob pattern - `openingIdx` and `closingIdx` are the +// indexes of `{` and `}`, respectively +func (g *glob) globAltsWalk(fsys fs.FS, pattern string, openingIdx, closingIdx int, firstSegment, beforeMeta bool, fn GlobWalkFunc) (err error) { + var matches []DirEntryWithFullPath + startIdx := 0 + afterIdx := closingIdx + 1 + splitIdx := lastIndexSlashOrAlt(pattern[:openingIdx]) + if splitIdx == -1 || pattern[splitIdx] == '}' { + // no common prefix + matches, err = g.doGlobAltsWalk(fsys, "", pattern, startIdx, openingIdx, closingIdx, afterIdx, firstSegment, beforeMeta, matches) + if err != nil { + return + } + } else { + // our alts have a common prefix that we can process first + startIdx = splitIdx + 1 + innerBeforeMeta := beforeMeta && !hasMetaExceptAlts(pattern[:splitIdx]) + err = g.doGlobWalk(fsys, pattern[:splitIdx], false, beforeMeta, func(p string, d fs.DirEntry) (e error) { + matches, e = g.doGlobAltsWalk(fsys, p, pattern, startIdx, openingIdx, closingIdx, afterIdx, firstSegment, innerBeforeMeta, matches) + return e + }) + if err != nil { + return + } + } + + skip := "" + for _, m := range matches { + if skip != "" { + // Because matches are sorted, we know that descendants of the skipped + // item must come immediately after the skipped item. If we find an item + // that does not have a prefix matching the skipped item, we know we're + // done skipping. I'm using strings.HasPrefix here because + // filepath.HasPrefix has been marked deprecated (and just calls + // strings.HasPrefix anyway). The reason it's deprecated is because it + // doesn't handle case-insensitive paths, nor does it guarantee that the + // prefix is actually a parent directory. Neither is an issue here: the + // paths come from the system so their cases will match, and we guarantee + // a parent directory by appending a slash to the prefix. + // + // NOTE: m.Path will always use slashes as path separators. + if strings.HasPrefix(m.Path, skip) { + continue + } + skip = "" + } + if err = fn(m.Path, m.Entry); err != nil { + if err == SkipDir { + isDir, err := g.isDir(fsys, "", m.Path, m.Entry) + if err != nil { + return err + } + if isDir { + // append a slash to guarantee `skip` will be treated as a parent dir + skip = m.Path + "/" + } else { + // Dir() calls Clean() which calls FromSlash(), so we need to convert + // back to slashes + skip = filepath.ToSlash(filepath.Dir(m.Path)) + "/" + } + err = nil + continue + } + return + } + } + + return +} + +// runs actual matching for alts +func (g *glob) doGlobAltsWalk(fsys fs.FS, d, pattern string, startIdx, openingIdx, closingIdx, afterIdx int, firstSegment, beforeMeta bool, m []DirEntryWithFullPath) (matches []DirEntryWithFullPath, err error) { + matches = m + matchesLen := len(m) + patIdx := openingIdx + 1 + for patIdx < closingIdx { + nextIdx := indexNextAlt(pattern[patIdx:closingIdx], true) + if nextIdx == -1 { + nextIdx = closingIdx + } else { + nextIdx += patIdx + } + + alt := buildAlt(d, pattern, startIdx, openingIdx, patIdx, nextIdx, afterIdx) + err = g.doGlobWalk(fsys, alt, firstSegment, beforeMeta, func(p string, d fs.DirEntry) error { + // insertion sort, ignoring dups + insertIdx := matchesLen + for insertIdx > 0 && matches[insertIdx-1].Path > p { + insertIdx-- + } + if insertIdx > 0 && matches[insertIdx-1].Path == p { + // dup + return nil + } + + // append to grow the slice, then insert + entry := DirEntryWithFullPath{d, p} + matches = append(matches, entry) + for i := matchesLen; i > insertIdx; i-- { + matches[i] = matches[i-1] + } + matches[insertIdx] = entry + matchesLen++ + + return nil + }) + if err != nil { + return + } + + patIdx = nextIdx + 1 + } + + return +} + +func (g *glob) globDirWalk(fsys fs.FS, dir, pattern string, canMatchFiles, beforeMeta bool, fn GlobWalkFunc) (e error) { + if pattern == "" { + if !canMatchFiles || !g.filesOnly { + // pattern can be an empty string if the original pattern ended in a + // slash, in which case, we should just return dir, but only if it + // actually exists and it's a directory (or a symlink to a directory) + info, isDir, err := g.isPathDir(fsys, dir, beforeMeta) + if err != nil { + return err + } + if isDir { + e = fn(dir, dirEntryFromFileInfo(info)) + if e == SkipDir { + e = nil + } + } + } + return + } + + if pattern == "**" { + // `**` can match *this* dir + info, dirExists, err := g.exists(fsys, dir, beforeMeta) + if err != nil { + return err + } + if !dirExists || !info.IsDir() { + return nil + } + if !canMatchFiles || !g.filesOnly { + if e = fn(dir, dirEntryFromFileInfo(info)); e != nil { + if e == SkipDir { + e = nil + } + return + } + } + return g.globDoubleStarWalk(fsys, dir, canMatchFiles, fn) + } + + dirs, err := fs.ReadDir(fsys, dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return g.handlePatternNotExist(beforeMeta) + } + return g.forwardErrIfFailOnIOErrors(err) + } + + var matched bool + for _, info := range dirs { + name := info.Name() + matched, e = matchWithSeparator(pattern, name, '/', false) + if e != nil { + return + } + if matched { + matched = canMatchFiles + if !matched || g.filesOnly { + matched, e = g.isDir(fsys, dir, name, info) + if e != nil { + return e + } + if canMatchFiles { + // if we're here, it's because g.filesOnly + // is set and we don't want directories + matched = !matched + } + } + if matched { + if e = fn(path.Join(dir, name), info); e != nil { + if e == SkipDir { + e = nil + } + return + } + } + } + } + + return +} + +// recursively walk files/directories in a directory +func (g *glob) globDoubleStarWalk(fsys fs.FS, dir string, canMatchFiles bool, fn GlobWalkFunc) (e error) { + dirs, err := fs.ReadDir(fsys, dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + // This function is only ever called after we know the top-most directory + // exists, so, if we ever get here, we know we'll never return + // ErrPatternNotExist. + return nil + } + return g.forwardErrIfFailOnIOErrors(err) + } + + for _, info := range dirs { + name := info.Name() + isDir, err := g.isDir(fsys, dir, name, info) + if err != nil { + return err + } + + if isDir { + p := path.Join(dir, name) + if !canMatchFiles || !g.filesOnly { + // `**` can match *this* dir, so add it + if e = fn(p, info); e != nil { + if e == SkipDir { + e = nil + continue + } + return + } + } + if e = g.globDoubleStarWalk(fsys, p, canMatchFiles, fn); e != nil { + return + } + } else if canMatchFiles { + if e = fn(path.Join(dir, name), info); e != nil { + if e == SkipDir { + e = nil + } + return + } + } + } + + return +} + +type DirEntryFromFileInfo struct { + fi fs.FileInfo +} + +func (d *DirEntryFromFileInfo) Name() string { + return d.fi.Name() +} + +func (d *DirEntryFromFileInfo) IsDir() bool { + return d.fi.IsDir() +} + +func (d *DirEntryFromFileInfo) Type() fs.FileMode { + return d.fi.Mode().Type() +} + +func (d *DirEntryFromFileInfo) Info() (fs.FileInfo, error) { + return d.fi, nil +} + +func dirEntryFromFileInfo(fi fs.FileInfo) fs.DirEntry { + return &DirEntryFromFileInfo{fi} +} + +type DirEntryWithFullPath struct { + Entry fs.DirEntry + Path string +} + +func hasMetaExceptAlts(s string) bool { + var c byte + l := len(s) + for i := 0; i < l; i++ { + c = s[i] + if c == '*' || c == '?' || c == '[' { + return true + } else if c == '\\' { + // skip next byte + i++ + } + } + return false +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/match.go b/vendor/github.com/bmatcuk/doublestar/v4/match.go new file mode 100644 index 0000000000..c0f20afa43 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/match.go @@ -0,0 +1,403 @@ +package doublestar + +import ( + "path/filepath" + "unicode/utf8" +) + +// Match reports whether name matches the shell pattern. +// The pattern syntax is: +// +// pattern: +// { term } +// term: +// '*' matches any sequence of non-path-separators +// '/**/' matches zero or more directories +// '?' matches any single non-path-separator character +// '[' [ '^' '!' ] { character-range } ']' +// character class (must be non-empty) +// starting with `^` or `!` negates the class +// '{' { term } [ ',' { term } ... ] '}' +// alternatives +// c matches character c (c != '*', '?', '\\', '[') +// '\\' c matches character c +// +// character-range: +// c matches character c (c != '\\', '-', ']') +// '\\' c matches character c +// lo '-' hi matches character c for lo <= c <= hi +// +// Match returns true if `name` matches the file name `pattern`. `name` and +// `pattern` are split on forward slash (`/`) characters and may be relative or +// absolute. +// +// Match requires pattern to match all of name, not just a substring. +// The only possible returned error is ErrBadPattern, when pattern +// is malformed. +// +// A doublestar (`**`) should appear surrounded by path separators such as +// `/**/`. A mid-pattern doublestar (`**`) behaves like bash's globstar +// option: a pattern such as `path/to/**.txt` would return the same results as +// `path/to/*.txt`. The pattern you're looking for is `path/to/**/*.txt`. +// +// Note: this is meant as a drop-in replacement for path.Match() which +// always uses '/' as the path separator. If you want to support systems +// which use a different path separator (such as Windows), what you want +// is PathMatch(). Alternatively, you can run filepath.ToSlash() on both +// pattern and name and then use this function. +// +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +// +func Match(pattern, name string) (bool, error) { + return matchWithSeparator(pattern, name, '/', true) +} + +// MatchUnvalidated can provide a small performance improvement if you don't +// care about whether or not the pattern is valid (perhaps because you already +// ran `ValidatePattern`). Note that there's really only one case where this +// performance improvement is realized: when pattern matching reaches the end +// of `name` before reaching the end of `pattern`, such as `Match("a/b/c", +// "a")`. +func MatchUnvalidated(pattern, name string) bool { + matched, _ := matchWithSeparator(pattern, name, '/', false) + return matched +} + +// PathMatch returns true if `name` matches the file name `pattern`. The +// difference between Match and PathMatch is that PathMatch will automatically +// use your system's path separator to split `name` and `pattern`. On systems +// where the path separator is `'\'`, escaping will be disabled. +// +// Note: this is meant as a drop-in replacement for filepath.Match(). It +// assumes that both `pattern` and `name` are using the system's path +// separator. If you can't be sure of that, use filepath.ToSlash() on both +// `pattern` and `name`, and then use the Match() function instead. +// +func PathMatch(pattern, name string) (bool, error) { + return matchWithSeparator(pattern, name, filepath.Separator, true) +} + +// PathMatchUnvalidated can provide a small performance improvement if you +// don't care about whether or not the pattern is valid (perhaps because you +// already ran `ValidatePattern`). Note that there's really only one case where +// this performance improvement is realized: when pattern matching reaches the +// end of `name` before reaching the end of `pattern`, such as `Match("a/b/c", +// "a")`. +func PathMatchUnvalidated(pattern, name string) bool { + matched, _ := matchWithSeparator(pattern, name, filepath.Separator, false) + return matched +} + +func matchWithSeparator(pattern, name string, separator rune, validate bool) (matched bool, err error) { + return doMatchWithSeparator(pattern, name, separator, validate, -1, -1, -1, -1, 0, 0) +} + +func doMatchWithSeparator(pattern, name string, separator rune, validate bool, doublestarPatternBacktrack, doublestarNameBacktrack, starPatternBacktrack, starNameBacktrack, patIdx, nameIdx int) (matched bool, err error) { + patLen := len(pattern) + nameLen := len(name) + startOfSegment := true +MATCH: + for nameIdx < nameLen { + if patIdx < patLen { + switch pattern[patIdx] { + case '*': + if patIdx++; patIdx < patLen && pattern[patIdx] == '*' { + // doublestar - must begin with a path separator, otherwise we'll + // treat it like a single star like bash + patIdx++ + if startOfSegment { + if patIdx >= patLen { + // pattern ends in `/**`: return true + return true, nil + } + + // doublestar must also end with a path separator, otherwise we're + // just going to treat the doublestar as a single star like bash + patRune, patRuneLen := utf8.DecodeRuneInString(pattern[patIdx:]) + if patRune == separator { + patIdx += patRuneLen + + doublestarPatternBacktrack = patIdx + doublestarNameBacktrack = nameIdx + starPatternBacktrack = -1 + starNameBacktrack = -1 + continue + } + } + } + startOfSegment = false + + starPatternBacktrack = patIdx + starNameBacktrack = nameIdx + continue + + case '?': + startOfSegment = false + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + if nameRune == separator { + // `?` cannot match the separator + break + } + + patIdx++ + nameIdx += nameRuneLen + continue + + case '[': + startOfSegment = false + if patIdx++; patIdx >= patLen { + // class didn't end + return false, ErrBadPattern + } + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + + matched := false + negate := pattern[patIdx] == '!' || pattern[patIdx] == '^' + if negate { + patIdx++ + } + + if patIdx >= patLen || pattern[patIdx] == ']' { + // class didn't end or empty character class + return false, ErrBadPattern + } + + last := utf8.MaxRune + for patIdx < patLen && pattern[patIdx] != ']' { + patRune, patRuneLen := utf8.DecodeRuneInString(pattern[patIdx:]) + patIdx += patRuneLen + + // match a range + if last < utf8.MaxRune && patRune == '-' && patIdx < patLen && pattern[patIdx] != ']' { + if pattern[patIdx] == '\\' { + // next character is escaped + patIdx++ + } + patRune, patRuneLen = utf8.DecodeRuneInString(pattern[patIdx:]) + patIdx += patRuneLen + + if last <= nameRune && nameRune <= patRune { + matched = true + break + } + + // didn't match range - reset `last` + last = utf8.MaxRune + continue + } + + // not a range - check if the next rune is escaped + if patRune == '\\' { + patRune, patRuneLen = utf8.DecodeRuneInString(pattern[patIdx:]) + patIdx += patRuneLen + } + + // check if the rune matches + if patRune == nameRune { + matched = true + break + } + + // no matches yet + last = patRune + } + + if matched == negate { + // failed to match - if we reached the end of the pattern, that means + // we never found a closing `]` + if patIdx >= patLen { + return false, ErrBadPattern + } + break + } + + closingIdx := indexUnescapedByte(pattern[patIdx:], ']', true) + if closingIdx == -1 { + // no closing `]` + return false, ErrBadPattern + } + + patIdx += closingIdx + 1 + nameIdx += nameRuneLen + continue + + case '{': + startOfSegment = false + beforeIdx := patIdx + patIdx++ + closingIdx := indexMatchedClosingAlt(pattern[patIdx:], separator != '\\') + if closingIdx == -1 { + // no closing `}` + return false, ErrBadPattern + } + closingIdx += patIdx + + for { + commaIdx := indexNextAlt(pattern[patIdx:closingIdx], separator != '\\') + if commaIdx == -1 { + break + } + commaIdx += patIdx + + result, err := doMatchWithSeparator(pattern[:beforeIdx]+pattern[patIdx:commaIdx]+pattern[closingIdx+1:], name, separator, validate, doublestarPatternBacktrack, doublestarNameBacktrack, starPatternBacktrack, starNameBacktrack, beforeIdx, nameIdx) + if result || err != nil { + return result, err + } + + patIdx = commaIdx + 1 + } + return doMatchWithSeparator(pattern[:beforeIdx]+pattern[patIdx:closingIdx]+pattern[closingIdx+1:], name, separator, validate, doublestarPatternBacktrack, doublestarNameBacktrack, starPatternBacktrack, starNameBacktrack, beforeIdx, nameIdx) + + case '\\': + if separator != '\\' { + // next rune is "escaped" in the pattern - literal match + if patIdx++; patIdx >= patLen { + // pattern ended + return false, ErrBadPattern + } + } + fallthrough + + default: + patRune, patRuneLen := utf8.DecodeRuneInString(pattern[patIdx:]) + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + if patRune != nameRune { + if separator != '\\' && patIdx > 0 && pattern[patIdx-1] == '\\' { + // if this rune was meant to be escaped, we need to move patIdx + // back to the backslash before backtracking or validating below + patIdx-- + } + break + } + + patIdx += patRuneLen + nameIdx += nameRuneLen + startOfSegment = patRune == separator + continue + } + } + + if starPatternBacktrack >= 0 { + // `*` backtrack, but only if the `name` rune isn't the separator + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[starNameBacktrack:]) + if nameRune != separator { + starNameBacktrack += nameRuneLen + patIdx = starPatternBacktrack + nameIdx = starNameBacktrack + startOfSegment = false + continue + } + } + + if doublestarPatternBacktrack >= 0 { + // `**` backtrack, advance `name` past next separator + nameIdx = doublestarNameBacktrack + for nameIdx < nameLen { + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + nameIdx += nameRuneLen + if nameRune == separator { + doublestarNameBacktrack = nameIdx + patIdx = doublestarPatternBacktrack + startOfSegment = true + continue MATCH + } + } + } + + if validate && patIdx < patLen && !doValidatePattern(pattern[patIdx:], separator) { + return false, ErrBadPattern + } + return false, nil + } + + if nameIdx < nameLen { + // we reached the end of `pattern` before the end of `name` + return false, nil + } + + // we've reached the end of `name`; we've successfully matched if we've also + // reached the end of `pattern`, or if the rest of `pattern` can match a + // zero-length string + return isZeroLengthPattern(pattern[patIdx:], separator) +} + +func isZeroLengthPattern(pattern string, separator rune) (ret bool, err error) { + // `/**`, `**/`, and `/**/` are special cases - a pattern such as `path/to/a/**` or `path/to/a/**/` + // *should* match `path/to/a` because `a` might be a directory + if pattern == "" || + pattern == "*" || + pattern == "**" || + pattern == string(separator)+"**" || + pattern == "**"+string(separator) || + pattern == string(separator)+"**"+string(separator) { + return true, nil + } + + if pattern[0] == '{' { + closingIdx := indexMatchedClosingAlt(pattern[1:], separator != '\\') + if closingIdx == -1 { + // no closing '}' + return false, ErrBadPattern + } + closingIdx += 1 + + patIdx := 1 + for { + commaIdx := indexNextAlt(pattern[patIdx:closingIdx], separator != '\\') + if commaIdx == -1 { + break + } + commaIdx += patIdx + + ret, err = isZeroLengthPattern(pattern[patIdx:commaIdx]+pattern[closingIdx+1:], separator) + if ret || err != nil { + return + } + + patIdx = commaIdx + 1 + } + return isZeroLengthPattern(pattern[patIdx:closingIdx]+pattern[closingIdx+1:], separator) + } + + // no luck - validate the rest of the pattern + if !doValidatePattern(pattern, separator) { + return false, ErrBadPattern + } + return false, nil +} + +// Finds the index of the first unescaped byte `c`, or negative 1. +func indexUnescapedByte(s string, c byte, allowEscaping bool) int { + l := len(s) + for i := 0; i < l; i++ { + if allowEscaping && s[i] == '\\' { + // skip next byte + i++ + } else if s[i] == c { + return i + } + } + return -1 +} + +// Assuming the byte before the beginning of `s` is an opening `{`, this +// function will find the index of the matching `}`. That is, it'll skip over +// any nested `{}` and account for escaping +func indexMatchedClosingAlt(s string, allowEscaping bool) int { + alts := 1 + l := len(s) + for i := 0; i < l; i++ { + if allowEscaping && s[i] == '\\' { + // skip next byte + i++ + } else if s[i] == '{' { + alts++ + } else if s[i] == '}' { + if alts--; alts == 0 { + return i + } + } + } + return -1 +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/utils.go b/vendor/github.com/bmatcuk/doublestar/v4/utils.go new file mode 100644 index 0000000000..6b8df9a389 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/utils.go @@ -0,0 +1,157 @@ +package doublestar + +import ( + "errors" + "os" + "path" + "path/filepath" + "strings" +) + +// SplitPattern is a utility function. Given a pattern, SplitPattern will +// return two strings: the first string is everything up to the last slash +// (`/`) that appears _before_ any unescaped "meta" characters (ie, `*?[{`). +// The second string is everything after that slash. For example, given the +// pattern: +// +// ../../path/to/meta*/** +// ^----------- split here +// +// SplitPattern returns "../../path/to" and "meta*/**". This is useful for +// initializing os.DirFS() to call Glob() because Glob() will silently fail if +// your pattern includes `/./` or `/../`. For example: +// +// base, pattern := SplitPattern("../../path/to/meta*/**") +// fsys := os.DirFS(base) +// matches, err := Glob(fsys, pattern) +// +// If SplitPattern cannot find somewhere to split the pattern (for example, +// `meta*/**`), it will return "." and the unaltered pattern (`meta*/**` in +// this example). +// +// Of course, it is your responsibility to decide if the returned base path is +// "safe" in the context of your application. Perhaps you could use Match() to +// validate against a list of approved base directories? +// +func SplitPattern(p string) (base, pattern string) { + base = "." + pattern = p + + splitIdx := -1 + for i := 0; i < len(p); i++ { + c := p[i] + if c == '\\' { + i++ + } else if c == '/' { + splitIdx = i + } else if c == '*' || c == '?' || c == '[' || c == '{' { + break + } + } + + if splitIdx == 0 { + return "/", p[1:] + } else if splitIdx > 0 { + return p[:splitIdx], p[splitIdx+1:] + } + + return +} + +// FilepathGlob returns the names of all files matching pattern or nil if there +// is no matching file. The syntax of pattern is the same as in Match(). The +// pattern may describe hierarchical names such as usr/*/bin/ed. +// +// FilepathGlob ignores file system errors such as I/O errors reading +// directories by default. The only possible returned error is ErrBadPattern, +// reporting that the pattern is malformed. +// +// To enable aborting on I/O errors, the WithFailOnIOErrors option can be +// passed. +// +// Note: FilepathGlob is a convenience function that is meant as a drop-in +// replacement for `path/filepath.Glob()` for users who don't need the +// complication of io/fs. Basically, it: +// - Runs `filepath.Clean()` and `ToSlash()` on the pattern +// - Runs `SplitPattern()` to get a base path and a pattern to Glob +// - Creates an FS object from the base path and `Glob()s` on the pattern +// - Joins the base path with all of the matches from `Glob()` +// +// Returned paths will use the system's path separator, just like +// `filepath.Glob()`. +// +// Note: the returned error doublestar.ErrBadPattern is not equal to +// filepath.ErrBadPattern. +// +func FilepathGlob(pattern string, opts ...GlobOption) (matches []string, err error) { + if pattern == "" { + // special case to match filepath.Glob behavior + g := newGlob(opts...) + if g.failOnIOErrors { + // match doublestar.Glob behavior here + return nil, os.ErrInvalid + } + return nil, nil + } + + pattern = filepath.Clean(pattern) + pattern = filepath.ToSlash(pattern) + base, f := SplitPattern(pattern) + if f == "" || f == "." || f == ".." { + // some special cases to match filepath.Glob behavior + if !ValidatePathPattern(pattern) { + return nil, ErrBadPattern + } + + if filepath.Separator != '\\' { + pattern = unescapeMeta(pattern) + } + + if _, err = os.Lstat(pattern); err != nil { + g := newGlob(opts...) + if errors.Is(err, os.ErrNotExist) { + return nil, g.handlePatternNotExist(true) + } + return nil, g.forwardErrIfFailOnIOErrors(err) + } + return []string{filepath.FromSlash(pattern)}, nil + } + + fs := os.DirFS(base) + if matches, err = Glob(fs, f, opts...); err != nil { + return nil, err + } + for i := range matches { + // use path.Join because we used ToSlash above to ensure our paths are made + // of forward slashes, no matter what the system uses + matches[i] = filepath.FromSlash(path.Join(base, matches[i])) + } + return +} + +// Finds the next comma, but ignores any commas that appear inside nested `{}`. +// Assumes that each opening bracket has a corresponding closing bracket. +func indexNextAlt(s string, allowEscaping bool) int { + alts := 1 + l := len(s) + for i := 0; i < l; i++ { + if allowEscaping && s[i] == '\\' { + // skip next byte + i++ + } else if s[i] == '{' { + alts++ + } else if s[i] == '}' { + alts-- + } else if s[i] == ',' && alts == 1 { + return i + } + } + return -1 +} + +var metaReplacer = strings.NewReplacer("\\*", "*", "\\?", "?", "\\[", "[", "\\]", "]", "\\{", "{", "\\}", "}") + +// Unescapes meta characters (*?[]{}) +func unescapeMeta(pattern string) string { + return metaReplacer.Replace(pattern) +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/validate.go b/vendor/github.com/bmatcuk/doublestar/v4/validate.go new file mode 100644 index 0000000000..c689b9ebab --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/validate.go @@ -0,0 +1,82 @@ +package doublestar + +import "path/filepath" + +// Validate a pattern. Patterns are validated while they run in Match(), +// PathMatch(), and Glob(), so, you normally wouldn't need to call this. +// However, there are cases where this might be useful: for example, if your +// program allows a user to enter a pattern that you'll run at a later time, +// you might want to validate it. +// +// ValidatePattern assumes your pattern uses '/' as the path separator. +// +func ValidatePattern(s string) bool { + return doValidatePattern(s, '/') +} + +// Like ValidatePattern, only uses your OS path separator. In other words, use +// ValidatePattern if you would normally use Match() or Glob(). Use +// ValidatePathPattern if you would normally use PathMatch(). Keep in mind, +// Glob() requires '/' separators, even if your OS uses something else. +// +func ValidatePathPattern(s string) bool { + return doValidatePattern(s, filepath.Separator) +} + +func doValidatePattern(s string, separator rune) bool { + altDepth := 0 + l := len(s) +VALIDATE: + for i := 0; i < l; i++ { + switch s[i] { + case '\\': + if separator != '\\' { + // skip the next byte - return false if there is no next byte + if i++; i >= l { + return false + } + } + continue + + case '[': + if i++; i >= l { + // class didn't end + return false + } + if s[i] == '^' || s[i] == '!' { + i++ + } + if i >= l || s[i] == ']' { + // class didn't end or empty character class + return false + } + + for ; i < l; i++ { + if separator != '\\' && s[i] == '\\' { + i++ + } else if s[i] == ']' { + // looks good + continue VALIDATE + } + } + + // class didn't end + return false + + case '{': + altDepth++ + continue + + case '}': + if altDepth == 0 { + // alt end without a corresponding start + return false + } + altDepth-- + continue + } + } + + // valid as long as all alts are closed + return altDepth == 0 +} diff --git a/vendor/github.com/imacks/bitflags-go/LICENSE b/vendor/github.com/brunoga/deep/LICENSE similarity index 100% rename from vendor/github.com/imacks/bitflags-go/LICENSE rename to vendor/github.com/brunoga/deep/LICENSE diff --git a/vendor/github.com/brunoga/deep/README.md b/vendor/github.com/brunoga/deep/README.md new file mode 100644 index 0000000000..ad37b09595 --- /dev/null +++ b/vendor/github.com/brunoga/deep/README.md @@ -0,0 +1,29 @@ +# deep +Support for doing deep copies of (almost all) Go types. + +This is a from scratch implementation of the ideas from https://github.com/barkimedes/go-deepcopy (which, unfortunatelly appears to be dead) but it is faster, simpler to use for callers and supports copying unexported fields. + +It should support most Go types. Specificaly, it does not support functions, channels and unsafe.Pointers unless they are nil. Also it might have weird interactions with structs that include any synchronization primitives (mutexes, for example. They should still be copied but if they are usable after that is left as an exercise to the reader). + +One possible usage scenario would be, for example, to negate the use of the deepcopy-gen tool described in [Kubernetes code generation](https://www.redhat.com/en/blog/kubernetes-deep-dive-code-generation-customresources). For any type T, the DeepEqual method can be implemented more or less like this: + +``` +func (t* T) DeepCopy() *T { + return deep.MustCopy(t) // This would panic on errors. +} +``` + +## Benchmarks + +| Benchmark | Iterations | Time | Bytes Allocated | Allocations | +|------------------------------------|------------|----------------|-----------------|------------------| +| **BenchmarkCopy_Deep-16** | **830553** | **1273 ns/op** | **1264 B/op** | **21 allocs/op** | +| BenchmarkCopy_DeepCopy-16 (1) | 458072 | 2466 ns/op | 1912 B/op | 50 allocs/op | +| BenchmarkCopy_CopyStructure-16 (2) | 149685 | 7836 ns/op | 6392 B/op | 168 allocs/op | +| BenchmarkCopy_Clone-16 (3) | 510760 | 2188 ns/op | 1656 B/op | 22 allocs/op | + +(1) https://github.com/barkimedes/go-deepcopy (does not support unexported fields) + +(2) https://github.com/mitchellh/copystructure (does not support cycles) + +(3) https://github.com/huandu/go-clone diff --git a/vendor/github.com/brunoga/deep/deep.go b/vendor/github.com/brunoga/deep/deep.go new file mode 100644 index 0000000000..1b1c14a13c --- /dev/null +++ b/vendor/github.com/brunoga/deep/deep.go @@ -0,0 +1,239 @@ +package deep + +import ( + "fmt" + "reflect" +) + +// Copy creates a deep copy of src. It returns the copy and a nil error in case +// of success and the zero value for the type and a non-nil error on failure. +func Copy[T any](src T) (T, error) { + return copy(src, false) +} + +// CopySkipUnsupported creates a deep copy of src. It returns the copy and a nil +// errorin case of success and the zero value for the type and a non-nil error +// on failure. Unsupported types are skipped (the copy will have the zero value +// for the type) instead of returning an error. +func CopySkipUnsupported[T any](src T) (T, error) { + return copy(src, true) +} + +// MustCopy creates a deep copy of src. It returns the copy on success or panics +// in case of any failure. +func MustCopy[T any](src T) T { + dst, err := copy(src, false) + if err != nil { + panic(err) + } + + return dst +} + +type pointersMap map[uintptr]map[string]reflect.Value + +func copy[T any](src T, skipUnsupported bool) (T, error) { + v := reflect.ValueOf(src) + + // We might have a zero value, so we check for this here otherwise + // calling interface below will panic. + if v.Kind() == reflect.Invalid { + // This amounts to returning the zero value for T. + var t T + return t, nil + } + + dst, err := recursiveCopy(v, make(pointersMap), + skipUnsupported) + if err != nil { + var t T + return t, err + } + + return dst.Interface().(T), nil +} + +func recursiveCopy(v reflect.Value, pointers pointersMap, + skipUnsupported bool) (reflect.Value, error) { + switch v.Kind() { + case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64, + reflect.Complex64, reflect.Complex128, reflect.String: + // Direct type, just copy it. + return v, nil + case reflect.Array: + return recursiveCopyArray(v, pointers, skipUnsupported) + case reflect.Interface: + return recursiveCopyInterface(v, pointers, skipUnsupported) + case reflect.Map: + return recursiveCopyMap(v, pointers, skipUnsupported) + case reflect.Ptr: + return recursiveCopyPtr(v, pointers, skipUnsupported) + case reflect.Slice: + return recursiveCopySlice(v, pointers, skipUnsupported) + case reflect.Struct: + return recursiveCopyStruct(v, pointers, skipUnsupported) + case reflect.Func, reflect.Chan, reflect.UnsafePointer: + if v.IsNil() { + // If we have a nil function, unsafe pointer or channel, then we + // can copy it. + return v, nil + } else { + if skipUnsupported { + return reflect.Zero(v.Type()), nil + } else { + return reflect.Value{}, fmt.Errorf("unsuported non-nil value for type: %s", v.Type()) + } + } + default: + if skipUnsupported { + return reflect.Zero(v.Type()), nil + } else { + return reflect.Value{}, fmt.Errorf("unsuported type: %s", v.Type()) + } + } +} + +func recursiveCopyArray(v reflect.Value, pointers pointersMap, + skipUnsupported bool) (reflect.Value, error) { + dst := reflect.New(v.Type()).Elem() + + for i := 0; i < v.Len(); i++ { + elem := v.Index(i) + elemDst, err := recursiveCopy(elem, pointers, skipUnsupported) + if err != nil { + return reflect.Value{}, err + } + + dst.Index(i).Set(elemDst) + } + + return dst, nil +} + +func recursiveCopyInterface(v reflect.Value, pointers pointersMap, + skipUnsupported bool) (reflect.Value, error) { + if v.IsNil() { + // If the interface is nil, just return it. + return v, nil + } + + return recursiveCopy(v.Elem(), pointers, skipUnsupported) +} + +func recursiveCopyMap(v reflect.Value, pointers pointersMap, + skipUnsupported bool) (reflect.Value, error) { + if v.IsNil() { + // If the slice is nil, just return it. + return v, nil + } + + dst := reflect.MakeMap(v.Type()) + + for _, key := range v.MapKeys() { + elem := v.MapIndex(key) + elemDst, err := recursiveCopy(elem, pointers, + skipUnsupported) + if err != nil { + return reflect.Value{}, err + } + + dst.SetMapIndex(key, elemDst) + } + + return dst, nil +} + +func recursiveCopyPtr(v reflect.Value, pointers pointersMap, + skipUnsupported bool) (reflect.Value, error) { + // If the pointer is nil, just return it. + if v.IsNil() { + return v, nil + } + + typeName := v.Type().String() + + // If the pointer is already in the pointers map, return it. + ptr := v.Pointer() + if dstMap, ok := pointers[ptr]; ok { + if dst, ok := dstMap[typeName]; ok { + return dst, nil + } + } + + // Otherwise, create a new pointer and add it to the pointers map. + dst := reflect.New(v.Type().Elem()) + + if pointers[ptr] == nil { + pointers[ptr] = make(map[string]reflect.Value) + } + + pointers[ptr][typeName] = dst + + // Proceed with the copy. + elem := v.Elem() + elemDst, err := recursiveCopy(elem, pointers, skipUnsupported) + if err != nil { + return reflect.Value{}, err + } + + dst.Elem().Set(elemDst) + + return dst, nil +} + +func recursiveCopySlice(v reflect.Value, pointers pointersMap, + skipUnsupported bool) (reflect.Value, error) { + if v.IsNil() { + // If the slice is nil, just return it. + return v, nil + } + + dst := reflect.MakeSlice(v.Type(), v.Len(), v.Cap()) + + for i := 0; i < v.Len(); i++ { + elem := v.Index(i) + elemDst, err := recursiveCopy(elem, pointers, + skipUnsupported) + if err != nil { + return reflect.Value{}, err + } + + dst.Index(i).Set(elemDst) + } + + return dst, nil +} + +func recursiveCopyStruct(v reflect.Value, pointers pointersMap, + skipUnsupported bool) (reflect.Value, error) { + dst := reflect.New(v.Type()).Elem() + + for i := 0; i < v.NumField(); i++ { + elem := v.Field(i) + + // If the field is unexported, we need to disable read-only mode. If it + // is exported, doing this changes nothing so we just do it. We need to + // do this here not because we are writting to the field (this is the + // source), but because Interface() does not work if the read-only bits + // are set. + disableRO(&elem) + + elemDst, err := recursiveCopy(elem, pointers, + skipUnsupported) + if err != nil { + return reflect.Value{}, err + } + + dstField := dst.Field(i) + + // If the field is unexported, we need to disable read-only mode so we + // can actually write to it. + disableRO(&dstField) + + dstField.Set(elemDst) + } + + return dst, nil +} diff --git a/vendor/github.com/brunoga/deep/disable_ro.go b/vendor/github.com/brunoga/deep/disable_ro.go new file mode 100644 index 0000000000..8800545367 --- /dev/null +++ b/vendor/github.com/brunoga/deep/disable_ro.go @@ -0,0 +1,56 @@ +package deep + +import ( + "reflect" + "unsafe" +) + +func init() { + // Try to make sure we can use the trick in this file. It is still possible + // that things will break but we should be able to detect most of them. + t := reflect.TypeOf(reflect.Value{}) + if t.Kind() != reflect.Struct { + panic("deep: reflect.Value is not a struct") + } + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Name == "flag" { + // Check that the field is a uintptr. + if f.Type.Kind() != reflect.Uintptr { + panic("deep: reflect.Value.flag is not a uintptr") + } + + flagOffset = f.Offset + + return + } + } + + panic("deep: reflect.Value has no flag field") +} + +var flagOffset uintptr + +const ( + // Lifted from go/src/reflect/value.go. + flagStickyRO uintptr = 1 << 5 + flagEmbedRO uintptr = 1 << 6 + flagRO uintptr = flagStickyRO | flagEmbedRO +) + +// disableRO disables the read-only flag of a reflect.Value object. We use this +// to allow the reflect package to access the value of an unexported field as +// if it was exported (so we can copy it). +// +// DANGER! HERE BE DRAGONS! This is brittle and depends on internal state of a +// reflect.Value object. It is not guaranteed to work in future (or previous) +// versions of Go although we try to detect changes and panic immediatelly +// during initialization. +func disableRO(v *reflect.Value) { + // Get pointer to flags. + flags := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagOffset)) + + // Clear the read-only flags. + *flags &^= flagRO +} diff --git a/vendor/github.com/cespare/xxhash/LICENSE.txt b/vendor/github.com/cespare/xxhash/LICENSE.txt new file mode 100644 index 0000000000..24b53065f4 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2016 Caleb Spare + +MIT License + +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. diff --git a/vendor/github.com/cespare/xxhash/README.md b/vendor/github.com/cespare/xxhash/README.md new file mode 100644 index 0000000000..0982fd25e5 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/README.md @@ -0,0 +1,50 @@ +# xxhash + +[![GoDoc](https://godoc.org/github.com/cespare/xxhash?status.svg)](https://godoc.org/github.com/cespare/xxhash) + +xxhash is a Go implementation of the 64-bit +[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a +high-quality hashing algorithm that is much faster than anything in the Go +standard library. + +The API is very small, taking its cue from the other hashing packages in the +standard library: + + $ go doc github.com/cespare/xxhash ! + package xxhash // import "github.com/cespare/xxhash" + + Package xxhash implements the 64-bit variant of xxHash (XXH64) as described + at http://cyan4973.github.io/xxHash/. + + func New() hash.Hash64 + func Sum64(b []byte) uint64 + func Sum64String(s string) uint64 + +This implementation provides a fast pure-Go implementation and an even faster +assembly implementation for amd64. + +## Benchmarks + +Here are some quick benchmarks comparing the pure-Go and assembly +implementations of Sum64 against another popular Go XXH64 implementation, +[github.com/OneOfOne/xxhash](https://github.com/OneOfOne/xxhash): + +| input size | OneOfOne | cespare (purego) | cespare | +| --- | --- | --- | --- | +| 5 B | 416 MB/s | 720 MB/s | 872 MB/s | +| 100 B | 3980 MB/s | 5013 MB/s | 5252 MB/s | +| 4 KB | 12727 MB/s | 12999 MB/s | 13026 MB/s | +| 10 MB | 9879 MB/s | 10775 MB/s | 10913 MB/s | + +These numbers were generated with: + +``` +$ go test -benchtime 10s -bench '/OneOfOne,' +$ go test -tags purego -benchtime 10s -bench '/xxhash,' +$ go test -benchtime 10s -bench '/xxhash,' +``` + +## Projects using this package + +- [InfluxDB](https://github.com/influxdata/influxdb) +- [Prometheus](https://github.com/prometheus/prometheus) diff --git a/vendor/github.com/cespare/xxhash/rotate.go b/vendor/github.com/cespare/xxhash/rotate.go new file mode 100644 index 0000000000..f3eac5ebc0 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/rotate.go @@ -0,0 +1,14 @@ +// +build !go1.9 + +package xxhash + +// TODO(caleb): After Go 1.10 comes out, remove this fallback code. + +func rol1(x uint64) uint64 { return (x << 1) | (x >> (64 - 1)) } +func rol7(x uint64) uint64 { return (x << 7) | (x >> (64 - 7)) } +func rol11(x uint64) uint64 { return (x << 11) | (x >> (64 - 11)) } +func rol12(x uint64) uint64 { return (x << 12) | (x >> (64 - 12)) } +func rol18(x uint64) uint64 { return (x << 18) | (x >> (64 - 18)) } +func rol23(x uint64) uint64 { return (x << 23) | (x >> (64 - 23)) } +func rol27(x uint64) uint64 { return (x << 27) | (x >> (64 - 27)) } +func rol31(x uint64) uint64 { return (x << 31) | (x >> (64 - 31)) } diff --git a/vendor/github.com/cespare/xxhash/rotate19.go b/vendor/github.com/cespare/xxhash/rotate19.go new file mode 100644 index 0000000000..b99612bab8 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/rotate19.go @@ -0,0 +1,14 @@ +// +build go1.9 + +package xxhash + +import "math/bits" + +func rol1(x uint64) uint64 { return bits.RotateLeft64(x, 1) } +func rol7(x uint64) uint64 { return bits.RotateLeft64(x, 7) } +func rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) } +func rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) } +func rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) } +func rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) } +func rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) } +func rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) } diff --git a/vendor/github.com/cespare/xxhash/xxhash.go b/vendor/github.com/cespare/xxhash/xxhash.go new file mode 100644 index 0000000000..f896bd28f0 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/xxhash.go @@ -0,0 +1,168 @@ +// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described +// at http://cyan4973.github.io/xxHash/. +package xxhash + +import ( + "encoding/binary" + "hash" +) + +const ( + prime1 uint64 = 11400714785074694791 + prime2 uint64 = 14029467366897019727 + prime3 uint64 = 1609587929392839161 + prime4 uint64 = 9650029242287828579 + prime5 uint64 = 2870177450012600261 +) + +// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where +// possible in the Go code is worth a small (but measurable) performance boost +// by avoiding some MOVQs. Vars are needed for the asm and also are useful for +// convenience in the Go code in a few places where we need to intentionally +// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the +// result overflows a uint64). +var ( + prime1v = prime1 + prime2v = prime2 + prime3v = prime3 + prime4v = prime4 + prime5v = prime5 +) + +type xxh struct { + v1 uint64 + v2 uint64 + v3 uint64 + v4 uint64 + total int + mem [32]byte + n int // how much of mem is used +} + +// New creates a new hash.Hash64 that implements the 64-bit xxHash algorithm. +func New() hash.Hash64 { + var x xxh + x.Reset() + return &x +} + +func (x *xxh) Reset() { + x.n = 0 + x.total = 0 + x.v1 = prime1v + prime2 + x.v2 = prime2 + x.v3 = 0 + x.v4 = -prime1v +} + +func (x *xxh) Size() int { return 8 } +func (x *xxh) BlockSize() int { return 32 } + +// Write adds more data to x. It always returns len(b), nil. +func (x *xxh) Write(b []byte) (n int, err error) { + n = len(b) + x.total += len(b) + + if x.n+len(b) < 32 { + // This new data doesn't even fill the current block. + copy(x.mem[x.n:], b) + x.n += len(b) + return + } + + if x.n > 0 { + // Finish off the partial block. + copy(x.mem[x.n:], b) + x.v1 = round(x.v1, u64(x.mem[0:8])) + x.v2 = round(x.v2, u64(x.mem[8:16])) + x.v3 = round(x.v3, u64(x.mem[16:24])) + x.v4 = round(x.v4, u64(x.mem[24:32])) + b = b[32-x.n:] + x.n = 0 + } + + if len(b) >= 32 { + // One or more full blocks left. + b = writeBlocks(x, b) + } + + // Store any remaining partial block. + copy(x.mem[:], b) + x.n = len(b) + + return +} + +func (x *xxh) Sum(b []byte) []byte { + s := x.Sum64() + return append( + b, + byte(s>>56), + byte(s>>48), + byte(s>>40), + byte(s>>32), + byte(s>>24), + byte(s>>16), + byte(s>>8), + byte(s), + ) +} + +func (x *xxh) Sum64() uint64 { + var h uint64 + + if x.total >= 32 { + v1, v2, v3, v4 := x.v1, x.v2, x.v3, x.v4 + h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4) + h = mergeRound(h, v1) + h = mergeRound(h, v2) + h = mergeRound(h, v3) + h = mergeRound(h, v4) + } else { + h = x.v3 + prime5 + } + + h += uint64(x.total) + + i, end := 0, x.n + for ; i+8 <= end; i += 8 { + k1 := round(0, u64(x.mem[i:i+8])) + h ^= k1 + h = rol27(h)*prime1 + prime4 + } + if i+4 <= end { + h ^= uint64(u32(x.mem[i:i+4])) * prime1 + h = rol23(h)*prime2 + prime3 + i += 4 + } + for i < end { + h ^= uint64(x.mem[i]) * prime5 + h = rol11(h) * prime1 + i++ + } + + h ^= h >> 33 + h *= prime2 + h ^= h >> 29 + h *= prime3 + h ^= h >> 32 + + return h +} + +func u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) } +func u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) } + +func round(acc, input uint64) uint64 { + acc += input * prime2 + acc = rol31(acc) + acc *= prime1 + return acc +} + +func mergeRound(acc, val uint64) uint64 { + val = round(0, val) + acc ^= val + acc = acc*prime1 + prime4 + return acc +} diff --git a/vendor/github.com/cespare/xxhash/xxhash_amd64.go b/vendor/github.com/cespare/xxhash/xxhash_amd64.go new file mode 100644 index 0000000000..d617652680 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/xxhash_amd64.go @@ -0,0 +1,12 @@ +// +build !appengine +// +build gc +// +build !purego + +package xxhash + +// Sum64 computes the 64-bit xxHash digest of b. +// +//go:noescape +func Sum64(b []byte) uint64 + +func writeBlocks(x *xxh, b []byte) []byte diff --git a/vendor/github.com/cespare/xxhash/xxhash_amd64.s b/vendor/github.com/cespare/xxhash/xxhash_amd64.s new file mode 100644 index 0000000000..757f2011f0 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/xxhash_amd64.s @@ -0,0 +1,233 @@ +// +build !appengine +// +build gc +// +build !purego + +#include "textflag.h" + +// Register allocation: +// AX h +// CX pointer to advance through b +// DX n +// BX loop end +// R8 v1, k1 +// R9 v2 +// R10 v3 +// R11 v4 +// R12 tmp +// R13 prime1v +// R14 prime2v +// R15 prime4v + +// round reads from and advances the buffer pointer in CX. +// It assumes that R13 has prime1v and R14 has prime2v. +#define round(r) \ + MOVQ (CX), R12 \ + ADDQ $8, CX \ + IMULQ R14, R12 \ + ADDQ R12, r \ + ROLQ $31, r \ + IMULQ R13, r + +// mergeRound applies a merge round on the two registers acc and val. +// It assumes that R13 has prime1v, R14 has prime2v, and R15 has prime4v. +#define mergeRound(acc, val) \ + IMULQ R14, val \ + ROLQ $31, val \ + IMULQ R13, val \ + XORQ val, acc \ + IMULQ R13, acc \ + ADDQ R15, acc + +// func Sum64(b []byte) uint64 +TEXT ·Sum64(SB), NOSPLIT, $0-32 + // Load fixed primes. + MOVQ ·prime1v(SB), R13 + MOVQ ·prime2v(SB), R14 + MOVQ ·prime4v(SB), R15 + + // Load slice. + MOVQ b_base+0(FP), CX + MOVQ b_len+8(FP), DX + LEAQ (CX)(DX*1), BX + + // The first loop limit will be len(b)-32. + SUBQ $32, BX + + // Check whether we have at least one block. + CMPQ DX, $32 + JLT noBlocks + + // Set up initial state (v1, v2, v3, v4). + MOVQ R13, R8 + ADDQ R14, R8 + MOVQ R14, R9 + XORQ R10, R10 + XORQ R11, R11 + SUBQ R13, R11 + + // Loop until CX > BX. +blockLoop: + round(R8) + round(R9) + round(R10) + round(R11) + + CMPQ CX, BX + JLE blockLoop + + MOVQ R8, AX + ROLQ $1, AX + MOVQ R9, R12 + ROLQ $7, R12 + ADDQ R12, AX + MOVQ R10, R12 + ROLQ $12, R12 + ADDQ R12, AX + MOVQ R11, R12 + ROLQ $18, R12 + ADDQ R12, AX + + mergeRound(AX, R8) + mergeRound(AX, R9) + mergeRound(AX, R10) + mergeRound(AX, R11) + + JMP afterBlocks + +noBlocks: + MOVQ ·prime5v(SB), AX + +afterBlocks: + ADDQ DX, AX + + // Right now BX has len(b)-32, and we want to loop until CX > len(b)-8. + ADDQ $24, BX + + CMPQ CX, BX + JG fourByte + +wordLoop: + // Calculate k1. + MOVQ (CX), R8 + ADDQ $8, CX + IMULQ R14, R8 + ROLQ $31, R8 + IMULQ R13, R8 + + XORQ R8, AX + ROLQ $27, AX + IMULQ R13, AX + ADDQ R15, AX + + CMPQ CX, BX + JLE wordLoop + +fourByte: + ADDQ $4, BX + CMPQ CX, BX + JG singles + + MOVL (CX), R8 + ADDQ $4, CX + IMULQ R13, R8 + XORQ R8, AX + + ROLQ $23, AX + IMULQ R14, AX + ADDQ ·prime3v(SB), AX + +singles: + ADDQ $4, BX + CMPQ CX, BX + JGE finalize + +singlesLoop: + MOVBQZX (CX), R12 + ADDQ $1, CX + IMULQ ·prime5v(SB), R12 + XORQ R12, AX + + ROLQ $11, AX + IMULQ R13, AX + + CMPQ CX, BX + JL singlesLoop + +finalize: + MOVQ AX, R12 + SHRQ $33, R12 + XORQ R12, AX + IMULQ R14, AX + MOVQ AX, R12 + SHRQ $29, R12 + XORQ R12, AX + IMULQ ·prime3v(SB), AX + MOVQ AX, R12 + SHRQ $32, R12 + XORQ R12, AX + + MOVQ AX, ret+24(FP) + RET + +// writeBlocks uses the same registers as above except that it uses AX to store +// the x pointer. + +// func writeBlocks(x *xxh, b []byte) []byte +TEXT ·writeBlocks(SB), NOSPLIT, $0-56 + // Load fixed primes needed for round. + MOVQ ·prime1v(SB), R13 + MOVQ ·prime2v(SB), R14 + + // Load slice. + MOVQ b_base+8(FP), CX + MOVQ CX, ret_base+32(FP) // initialize return base pointer; see NOTE below + MOVQ b_len+16(FP), DX + LEAQ (CX)(DX*1), BX + SUBQ $32, BX + + // Load vN from x. + MOVQ x+0(FP), AX + MOVQ 0(AX), R8 // v1 + MOVQ 8(AX), R9 // v2 + MOVQ 16(AX), R10 // v3 + MOVQ 24(AX), R11 // v4 + + // We don't need to check the loop condition here; this function is + // always called with at least one block of data to process. +blockLoop: + round(R8) + round(R9) + round(R10) + round(R11) + + CMPQ CX, BX + JLE blockLoop + + // Copy vN back to x. + MOVQ R8, 0(AX) + MOVQ R9, 8(AX) + MOVQ R10, 16(AX) + MOVQ R11, 24(AX) + + // Construct return slice. + // NOTE: It's important that we don't construct a slice that has a base + // pointer off the end of the original slice, as in Go 1.7+ this will + // cause runtime crashes. (See discussion in, for example, + // https://github.com/golang/go/issues/16772.) + // Therefore, we calculate the length/cap first, and if they're zero, we + // keep the old base. This is what the compiler does as well if you + // write code like + // b = b[len(b):] + + // New length is 32 - (CX - BX) -> BX+32 - CX. + ADDQ $32, BX + SUBQ CX, BX + JZ afterSetBase + + MOVQ CX, ret_base+32(FP) + +afterSetBase: + MOVQ BX, ret_len+40(FP) + MOVQ BX, ret_cap+48(FP) // set cap == len + + RET diff --git a/vendor/github.com/cespare/xxhash/xxhash_other.go b/vendor/github.com/cespare/xxhash/xxhash_other.go new file mode 100644 index 0000000000..c68d13f89e --- /dev/null +++ b/vendor/github.com/cespare/xxhash/xxhash_other.go @@ -0,0 +1,75 @@ +// +build !amd64 appengine !gc purego + +package xxhash + +// Sum64 computes the 64-bit xxHash digest of b. +func Sum64(b []byte) uint64 { + // A simpler version would be + // x := New() + // x.Write(b) + // return x.Sum64() + // but this is faster, particularly for small inputs. + + n := len(b) + var h uint64 + + if n >= 32 { + v1 := prime1v + prime2 + v2 := prime2 + v3 := uint64(0) + v4 := -prime1v + for len(b) >= 32 { + v1 = round(v1, u64(b[0:8:len(b)])) + v2 = round(v2, u64(b[8:16:len(b)])) + v3 = round(v3, u64(b[16:24:len(b)])) + v4 = round(v4, u64(b[24:32:len(b)])) + b = b[32:len(b):len(b)] + } + h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4) + h = mergeRound(h, v1) + h = mergeRound(h, v2) + h = mergeRound(h, v3) + h = mergeRound(h, v4) + } else { + h = prime5 + } + + h += uint64(n) + + i, end := 0, len(b) + for ; i+8 <= end; i += 8 { + k1 := round(0, u64(b[i:i+8:len(b)])) + h ^= k1 + h = rol27(h)*prime1 + prime4 + } + if i+4 <= end { + h ^= uint64(u32(b[i:i+4:len(b)])) * prime1 + h = rol23(h)*prime2 + prime3 + i += 4 + } + for ; i < end; i++ { + h ^= uint64(b[i]) * prime5 + h = rol11(h) * prime1 + } + + h ^= h >> 33 + h *= prime2 + h ^= h >> 29 + h *= prime3 + h ^= h >> 32 + + return h +} + +func writeBlocks(x *xxh, b []byte) []byte { + v1, v2, v3, v4 := x.v1, x.v2, x.v3, x.v4 + for len(b) >= 32 { + v1 = round(v1, u64(b[0:8:len(b)])) + v2 = round(v2, u64(b[8:16:len(b)])) + v3 = round(v3, u64(b[16:24:len(b)])) + v4 = round(v4, u64(b[24:32:len(b)])) + b = b[32:len(b):len(b)] + } + x.v1, x.v2, x.v3, x.v4 = v1, v2, v3, v4 + return b +} diff --git a/vendor/github.com/cespare/xxhash/xxhash_safe.go b/vendor/github.com/cespare/xxhash/xxhash_safe.go new file mode 100644 index 0000000000..dfa15ab7e2 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/xxhash_safe.go @@ -0,0 +1,10 @@ +// +build appengine + +// This file contains the safe implementations of otherwise unsafe-using code. + +package xxhash + +// Sum64String computes the 64-bit xxHash digest of s. +func Sum64String(s string) uint64 { + return Sum64([]byte(s)) +} diff --git a/vendor/github.com/cespare/xxhash/xxhash_unsafe.go b/vendor/github.com/cespare/xxhash/xxhash_unsafe.go new file mode 100644 index 0000000000..d2b64e8bb0 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/xxhash_unsafe.go @@ -0,0 +1,30 @@ +// +build !appengine + +// This file encapsulates usage of unsafe. +// xxhash_safe.go contains the safe implementations. + +package xxhash + +import ( + "reflect" + "unsafe" +) + +// Sum64String computes the 64-bit xxHash digest of s. +// It may be faster than Sum64([]byte(s)) by avoiding a copy. +// +// TODO(caleb): Consider removing this if an optimization is ever added to make +// it unnecessary: https://golang.org/issue/2205. +// +// TODO(caleb): We still have a function call; we could instead write Go/asm +// copies of Sum64 for strings to squeeze out a bit more speed. +func Sum64String(s string) uint64 { + // See https://groups.google.com/d/msg/golang-nuts/dcjzJy-bSpw/tcZYBzQqAQAJ + // for some discussion about this unsafe conversion. + var b []byte + bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) + bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data + bh.Len = len(s) + bh.Cap = len(s) + return Sum64(b) +} diff --git a/vendor/github.com/faiface/mainthread/README.md b/vendor/github.com/faiface/mainthread/README.md deleted file mode 100644 index 20c834f22a..0000000000 --- a/vendor/github.com/faiface/mainthread/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# mainthread [![GoDoc](https://godoc.org/github.com/faiface/mainthread?status.svg)](http://godoc.org/github.com/faiface/mainthread) [![Report card](https://goreportcard.com/badge/github.com/faiface/mainthread)](https://goreportcard.com/report/github.com/faiface/mainthread) - -Package mainthread allows you to run code on the main operating system thread. - -`go get github.com/faiface/mainthread` - -Operating systems often require, that code which deals with windows and graphics has to run on the -main thread. This is however somehow challenging in Go due to Go's concurrent nature. - -This package makes it easily possible. - -All you need to do is put your main code into a separate function and call `mainthread.Run` from -your real main, like this: - -```go -package main - -import ( - "fmt" - - "github.com/faiface/mainthread" -) - -func run() { - // now we can run stuff on the main thread like this - mainthread.Call(func() { - fmt.Println("printing from the main thread") - }) - fmt.Println("printing from another thread") -} - -func main() { - mainthread.Run(run) // enables mainthread package and runs run in a separate goroutine -} -``` - -## More functions - -If you don't wish to wait until a function finishes running on the main thread, use -`mainthread.CallNonBlock`: - -```go -mainthread.CallNonBlock(func() { - fmt.Println("i'm in the main thread") -}) -fmt.Println("but imma be likely printed first, cuz i don't wait") -``` - -If you want to get some value returned from the main thread, you can use `mainthread.CallErr` or -`mainthread.CallVal`: - -```go -err := mainthread.CallErr(func() error { - return nil // i don't do nothing wrong -}) -val := mainthread.CallVal(func() interface{} { - return 42 // the meaning of life, universe and everything -}) -``` - -If `mainthread.CallErr` or `mainthread.CallVal` aren't sufficient for you, you can just assign -variables from within the main thread: - -```go -var x, y int -mainthread.Call(func() { - x, y = 1, 2 -}) -``` - -However, be careful with `mainthread.CallNonBlock` when dealing with local variables. diff --git a/vendor/github.com/faiface/mainthread/mainthread.go b/vendor/github.com/faiface/mainthread/mainthread.go deleted file mode 100644 index 7964520032..0000000000 --- a/vendor/github.com/faiface/mainthread/mainthread.go +++ /dev/null @@ -1,87 +0,0 @@ -package mainthread - -import ( - "errors" - "runtime" -) - -// CallQueueCap is the capacity of the call queue. This means how many calls to CallNonBlock will not -// block until some call finishes. -// -// The default value is 16 and should be good for 99% usecases. -var CallQueueCap = 16 - -var ( - callQueue chan func() -) - -func init() { - runtime.LockOSThread() -} - -func checkRun() { - if callQueue == nil { - panic(errors.New("mainthread: did not call Run")) - } -} - -// Run enables mainthread package functionality. To use mainthread package, put your main function -// code into the run function (the argument to Run) and simply call Run from the real main function. -// -// Run returns when run (argument) function finishes. -func Run(run func()) { - callQueue = make(chan func(), CallQueueCap) - - done := make(chan struct{}) - go func() { - run() - done <- struct{}{} - }() - - for { - select { - case f := <-callQueue: - f() - case <-done: - return - } - } -} - -// CallNonBlock queues function f on the main thread and returns immediately. Does not wait until f -// finishes. -func CallNonBlock(f func()) { - checkRun() - callQueue <- f -} - -// Call queues function f on the main thread and blocks until the function f finishes. -func Call(f func()) { - checkRun() - done := make(chan struct{}) - callQueue <- func() { - f() - done <- struct{}{} - } - <-done -} - -// CallErr queues function f on the main thread and returns an error returned by f. -func CallErr(f func() error) error { - checkRun() - errChan := make(chan error) - callQueue <- func() { - errChan <- f() - } - return <-errChan -} - -// CallVal queues function f on the main thread and returns a value returned by f. -func CallVal(f func() interface{}) interface{} { - checkRun() - respChan := make(chan interface{}) - callQueue <- func() { - respChan <- f() - } - return <-respChan -} diff --git a/vendor/github.com/fatih/color/README.md b/vendor/github.com/fatih/color/README.md index d62e4024aa..be82827cac 100644 --- a/vendor/github.com/fatih/color/README.md +++ b/vendor/github.com/fatih/color/README.md @@ -7,7 +7,6 @@ suits you. ![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg) - ## Install ```bash @@ -78,7 +77,7 @@ notice("Don't forget this...") ### Custom fprint functions (FprintFunc) ```go -blue := color.New(FgBlue).FprintfFunc() +blue := color.New(color.FgBlue).FprintfFunc() blue(myWriter, "important notice: %s", stars) // Mix up with multiple attributes @@ -124,17 +123,19 @@ fmt.Println("All text will now be bold magenta.") ``` ### Disable/Enable color - + There might be a case where you want to explicitly disable/enable color output. the `go-isatty` package will automatically disable color output for non-tty output streams -(for example if the output were piped directly to `less`) +(for example if the output were piped directly to `less`). -`Color` has support to disable/enable colors both globally and for single color -definitions. For example suppose you have a CLI app and a `--no-color` bool flag. You -can easily disable the color output with: +The `color` package also disables color output if the [`NO_COLOR`](https://no-color.org) environment +variable is set to a non-empty string. -```go +`Color` has support to disable/enable colors programmatically both globally and +for single color definitions. For example suppose you have a CLI app and a +`-no-color` bool flag. You can easily disable the color output with: +```go var flagNoColor = flag.Bool("no-color", false, "Disable color output") if *flagNoColor { @@ -156,18 +157,20 @@ c.EnableColor() c.Println("This prints again cyan...") ``` +## GitHub Actions + +To output color in GitHub Actions (or other CI systems that support ANSI colors), make sure to set `color.NoColor = false` so that it bypasses the check for non-tty output streams. + ## Todo * Save/Return previous values * Evaluate fmt.Formatter interface - ## Credits - * [Fatih Arslan](https://github.com/fatih) - * Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) +* [Fatih Arslan](https://github.com/fatih) +* Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) ## License The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details - diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go index 91c8e9f062..c4234287dc 100644 --- a/vendor/github.com/fatih/color/color.go +++ b/vendor/github.com/fatih/color/color.go @@ -15,12 +15,14 @@ import ( var ( // NoColor defines if the output is colorized or not. It's dynamically set to // false or true based on the stdout's file descriptor referring to a terminal - // or not. This is a global option and affects all colors. For more control - // over each color block use the methods DisableColor() individually. - NoColor = os.Getenv("TERM") == "dumb" || + // or not. It's also set to true if the NO_COLOR environment variable is + // set (regardless of its value). This is a global option and affects all + // colors. For more control over each color block use the methods + // DisableColor() individually. + NoColor = noColorIsSet() || os.Getenv("TERM") == "dumb" || (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) - // Output defines the standard output of the print functions. By default + // Output defines the standard output of the print functions. By default, // os.Stdout is used. Output = colorable.NewColorableStdout() @@ -33,6 +35,11 @@ var ( colorsCacheMu sync.Mutex // protects colorsCache ) +// noColorIsSet returns true if the environment variable NO_COLOR is set to a non-empty string. +func noColorIsSet() bool { + return os.Getenv("NO_COLOR") != "" +} + // Color defines a custom color object which is defined by SGR parameters. type Color struct { params []Attribute @@ -58,6 +65,29 @@ const ( CrossedOut ) +const ( + ResetBold Attribute = iota + 22 + ResetItalic + ResetUnderline + ResetBlinking + _ + ResetReversed + ResetConcealed + ResetCrossedOut +) + +var mapResetAttributes map[Attribute]Attribute = map[Attribute]Attribute{ + Bold: ResetBold, + Faint: ResetBold, + Italic: ResetItalic, + Underline: ResetUnderline, + BlinkSlow: ResetBlinking, + BlinkRapid: ResetBlinking, + ReverseVideo: ResetReversed, + Concealed: ResetConcealed, + CrossedOut: ResetCrossedOut, +} + // Foreground text colors const ( FgBlack Attribute = iota + 30 @@ -108,7 +138,14 @@ const ( // New returns a newly created color object. func New(value ...Attribute) *Color { - c := &Color{params: make([]Attribute, 0)} + c := &Color{ + params: make([]Attribute, 0), + } + + if noColorIsSet() { + c.noColor = boolPtr(true) + } + c.Add(value...) return c } @@ -137,7 +174,7 @@ func (c *Color) Set() *Color { return c } - fmt.Fprintf(Output, c.format()) + fmt.Fprint(Output, c.format()) return c } @@ -149,16 +186,21 @@ func (c *Color) unset() { Unset() } -func (c *Color) setWriter(w io.Writer) *Color { +// SetWriter is used to set the SGR sequence with the given io.Writer. This is +// a low-level function, and users should use the higher-level functions, such +// as color.Fprint, color.Print, etc. +func (c *Color) SetWriter(w io.Writer) *Color { if c.isNoColorSet() { return c } - fmt.Fprintf(w, c.format()) + fmt.Fprint(w, c.format()) return c } -func (c *Color) unsetWriter(w io.Writer) { +// UnsetWriter resets all escape attributes and clears the output with the give +// io.Writer. Usually should be called after SetWriter(). +func (c *Color) UnsetWriter(w io.Writer) { if c.isNoColorSet() { return } @@ -177,20 +219,14 @@ func (c *Color) Add(value ...Attribute) *Color { return c } -func (c *Color) prepend(value Attribute) { - c.params = append(c.params, 0) - copy(c.params[1:], c.params[0:]) - c.params[0] = value -} - // Fprint formats using the default formats for its operands and writes to w. // Spaces are added between operands when neither is a string. // It returns the number of bytes written and any write error encountered. // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) + c.SetWriter(w) + defer c.UnsetWriter(w) return fmt.Fprint(w, a...) } @@ -212,8 +248,8 @@ func (c *Color) Print(a ...interface{}) (n int, err error) { // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) + c.SetWriter(w) + defer c.UnsetWriter(w) return fmt.Fprintf(w, format, a...) } @@ -233,10 +269,7 @@ func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) - - return fmt.Fprintln(w, a...) + return fmt.Fprintln(w, c.wrap(fmt.Sprint(a...))) } // Println formats using the default formats for its operands and writes to @@ -245,10 +278,7 @@ func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { // encountered. This is the standard fmt.Print() method wrapped with the given // color. func (c *Color) Println(a ...interface{}) (n int, err error) { - c.Set() - defer c.unset() - - return fmt.Fprintln(Output, a...) + return fmt.Fprintln(Output, c.wrap(fmt.Sprint(a...))) } // Sprint is just like Print, but returns a string instead of printing it. @@ -258,7 +288,7 @@ func (c *Color) Sprint(a ...interface{}) string { // Sprintln is just like Println, but returns a string instead of printing it. func (c *Color) Sprintln(a ...interface{}) string { - return c.wrap(fmt.Sprintln(a...)) + return fmt.Sprintln(c.Sprint(a...)) } // Sprintf is just like Printf, but returns a string instead of printing it. @@ -340,7 +370,7 @@ func (c *Color) SprintfFunc() func(format string, a ...interface{}) string { // string. Windows users should use this in conjunction with color.Output. func (c *Color) SprintlnFunc() func(a ...interface{}) string { return func(a ...interface{}) string { - return c.wrap(fmt.Sprintln(a...)) + return fmt.Sprintln(c.Sprint(a...)) } } @@ -370,7 +400,18 @@ func (c *Color) format() string { } func (c *Color) unformat() string { - return fmt.Sprintf("%s[%dm", escape, Reset) + //return fmt.Sprintf("%s[%dm", escape, Reset) + //for each element in sequence let's use the speficic reset escape, ou the generic one if not found + format := make([]string, len(c.params)) + for i, v := range c.params { + format[i] = strconv.Itoa(int(Reset)) + ra, ok := mapResetAttributes[v] + if ok { + format[i] = strconv.Itoa(int(ra)) + } + } + + return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";")) } // DisableColor disables the color output. Useful to not change any existing @@ -381,13 +422,13 @@ func (c *Color) DisableColor() { } // EnableColor enables the color output. Use it in conjunction with -// DisableColor(). Otherwise this method has no side effects. +// DisableColor(). Otherwise, this method has no side effects. func (c *Color) EnableColor() { c.noColor = boolPtr(false) } func (c *Color) isNoColorSet() bool { - // check first if we have user setted action + // check first if we have user set action if c.noColor != nil { return *c.noColor } @@ -398,6 +439,12 @@ func (c *Color) isNoColorSet() bool { // Equals returns a boolean value indicating whether two colors are equal. func (c *Color) Equals(c2 *Color) bool { + if c == nil && c2 == nil { + return true + } + if c == nil || c2 == nil { + return false + } if len(c.params) != len(c2.params) { return false } diff --git a/vendor/github.com/fatih/color/color_windows.go b/vendor/github.com/fatih/color/color_windows.go new file mode 100644 index 0000000000..be01c558e5 --- /dev/null +++ b/vendor/github.com/fatih/color/color_windows.go @@ -0,0 +1,19 @@ +package color + +import ( + "os" + + "golang.org/x/sys/windows" +) + +func init() { + // Opt-in for ansi color support for current process. + // https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#output-sequences + var outMode uint32 + out := windows.Handle(os.Stdout.Fd()) + if err := windows.GetConsoleMode(out, &outMode); err != nil { + return + } + outMode |= windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING + _ = windows.SetConsoleMode(out, outMode) +} diff --git a/vendor/github.com/fatih/color/doc.go b/vendor/github.com/fatih/color/doc.go index cf1e96500f..9491ad5413 100644 --- a/vendor/github.com/fatih/color/doc.go +++ b/vendor/github.com/fatih/color/doc.go @@ -5,106 +5,105 @@ that suits you. Use simple and default helper functions with predefined foreground colors: - color.Cyan("Prints text in cyan.") + color.Cyan("Prints text in cyan.") - // a newline will be appended automatically - color.Blue("Prints %s in blue.", "text") + // a newline will be appended automatically + color.Blue("Prints %s in blue.", "text") - // More default foreground colors.. - color.Red("We have red") - color.Yellow("Yellow color too!") - color.Magenta("And many others ..") + // More default foreground colors.. + color.Red("We have red") + color.Yellow("Yellow color too!") + color.Magenta("And many others ..") - // Hi-intensity colors - color.HiGreen("Bright green color.") - color.HiBlack("Bright black means gray..") - color.HiWhite("Shiny white color!") + // Hi-intensity colors + color.HiGreen("Bright green color.") + color.HiBlack("Bright black means gray..") + color.HiWhite("Shiny white color!") -However there are times where custom color mixes are required. Below are some +However, there are times when custom color mixes are required. Below are some examples to create custom color objects and use the print functions of each separate color object. - // Create a new color object - c := color.New(color.FgCyan).Add(color.Underline) - c.Println("Prints cyan text with an underline.") + // Create a new color object + c := color.New(color.FgCyan).Add(color.Underline) + c.Println("Prints cyan text with an underline.") - // Or just add them to New() - d := color.New(color.FgCyan, color.Bold) - d.Printf("This prints bold cyan %s\n", "too!.") + // Or just add them to New() + d := color.New(color.FgCyan, color.Bold) + d.Printf("This prints bold cyan %s\n", "too!.") - // Mix up foreground and background colors, create new mixes! - red := color.New(color.FgRed) + // Mix up foreground and background colors, create new mixes! + red := color.New(color.FgRed) - boldRed := red.Add(color.Bold) - boldRed.Println("This will print text in bold red.") + boldRed := red.Add(color.Bold) + boldRed.Println("This will print text in bold red.") - whiteBackground := red.Add(color.BgWhite) - whiteBackground.Println("Red text with White background.") + whiteBackground := red.Add(color.BgWhite) + whiteBackground.Println("Red text with White background.") - // Use your own io.Writer output - color.New(color.FgBlue).Fprintln(myWriter, "blue color!") + // Use your own io.Writer output + color.New(color.FgBlue).Fprintln(myWriter, "blue color!") - blue := color.New(color.FgBlue) - blue.Fprint(myWriter, "This will print text in blue.") + blue := color.New(color.FgBlue) + blue.Fprint(myWriter, "This will print text in blue.") You can create PrintXxx functions to simplify even more: - // Create a custom print function for convenient - red := color.New(color.FgRed).PrintfFunc() - red("warning") - red("error: %s", err) + // Create a custom print function for convenient + red := color.New(color.FgRed).PrintfFunc() + red("warning") + red("error: %s", err) - // Mix up multiple attributes - notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() - notice("don't forget this...") + // Mix up multiple attributes + notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() + notice("don't forget this...") You can also FprintXxx functions to pass your own io.Writer: - blue := color.New(FgBlue).FprintfFunc() - blue(myWriter, "important notice: %s", stars) - - // Mix up with multiple attributes - success := color.New(color.Bold, color.FgGreen).FprintlnFunc() - success(myWriter, don't forget this...") + blue := color.New(FgBlue).FprintfFunc() + blue(myWriter, "important notice: %s", stars) + // Mix up with multiple attributes + success := color.New(color.Bold, color.FgGreen).FprintlnFunc() + success(myWriter, don't forget this...") Or create SprintXxx functions to mix strings with other non-colorized strings: - yellow := New(FgYellow).SprintFunc() - red := New(FgRed).SprintFunc() + yellow := New(FgYellow).SprintFunc() + red := New(FgRed).SprintFunc() - fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) + fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Printf("this %s rocks!\n", info("package")) + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Printf("this %s rocks!\n", info("package")) Windows support is enabled by default. All Print functions work as intended. -However only for color.SprintXXX functions, user should use fmt.FprintXXX and +However, only for color.SprintXXX functions, user should use fmt.FprintXXX and set the output to color.Output: - fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) + fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) Using with existing code is possible. Just use the Set() method to set the standard output to the given parameters. That way a rewrite of an existing code is not required. - // Use handy standard colors. - color.Set(color.FgYellow) + // Use handy standard colors. + color.Set(color.FgYellow) - fmt.Println("Existing text will be now in Yellow") - fmt.Printf("This one %s\n", "too") + fmt.Println("Existing text will be now in Yellow") + fmt.Printf("This one %s\n", "too") - color.Unset() // don't forget to unset + color.Unset() // don't forget to unset - // You can mix up parameters - color.Set(color.FgMagenta, color.Bold) - defer color.Unset() // use it in your function + // You can mix up parameters + color.Set(color.FgMagenta, color.Bold) + defer color.Unset() // use it in your function - fmt.Println("All text will be now bold magenta.") + fmt.Println("All text will be now bold magenta.") There might be a case where you want to disable color output (for example to pipe the standard output of your app to somewhere else). `Color` has support to @@ -112,22 +111,24 @@ disable colors both globally and for single color definition. For example suppose you have a CLI app and a `--no-color` bool flag. You can easily disable the color output with: - var flagNoColor = flag.Bool("no-color", false, "Disable color output") + var flagNoColor = flag.Bool("no-color", false, "Disable color output") + + if *flagNoColor { + color.NoColor = true // disables colorized output + } - if *flagNoColor { - color.NoColor = true // disables colorized output - } +You can also disable the color by setting the NO_COLOR environment variable to any value. It also has support for single color definitions (local). You can disable/enable color output on the fly: - c := color.New(color.FgCyan) - c.Println("Prints cyan text") + c := color.New(color.FgCyan) + c.Println("Prints cyan text") - c.DisableColor() - c.Println("This is printed without any color") + c.DisableColor() + c.Println("This is printed without any color") - c.EnableColor() - c.Println("This prints again cyan...") + c.EnableColor() + c.Println("This prints again cyan...") */ package color diff --git a/vendor/github.com/google/uuid/.travis.yml b/vendor/github.com/google/uuid/.travis.yml deleted file mode 100644 index d8156a60ba..0000000000 --- a/vendor/github.com/google/uuid/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - 1.4.3 - - 1.5.3 - - tip - -script: - - go test -v ./... diff --git a/vendor/github.com/google/uuid/CHANGELOG.md b/vendor/github.com/google/uuid/CHANGELOG.md new file mode 100644 index 0000000000..7ec5ac7ea9 --- /dev/null +++ b/vendor/github.com/google/uuid/CHANGELOG.md @@ -0,0 +1,41 @@ +# Changelog + +## [1.6.0](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) (2024-01-16) + + +### Features + +* add Max UUID constant ([#149](https://github.com/google/uuid/issues/149)) ([c58770e](https://github.com/google/uuid/commit/c58770eb495f55fe2ced6284f93c5158a62e53e3)) + + +### Bug Fixes + +* fix typo in version 7 uuid documentation ([#153](https://github.com/google/uuid/issues/153)) ([016b199](https://github.com/google/uuid/commit/016b199544692f745ffc8867b914129ecb47ef06)) +* Monotonicity in UUIDv7 ([#150](https://github.com/google/uuid/issues/150)) ([a2b2b32](https://github.com/google/uuid/commit/a2b2b32373ff0b1a312b7fdf6d38a977099698a6)) + +## [1.5.0](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) (2023-12-12) + + +### Features + +* Validate UUID without creating new UUID ([#141](https://github.com/google/uuid/issues/141)) ([9ee7366](https://github.com/google/uuid/commit/9ee7366e66c9ad96bab89139418a713dc584ae29)) + +## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26) + + +### Features + +* UUIDs slice type with Strings() convenience method ([#133](https://github.com/google/uuid/issues/133)) ([cd5fbbd](https://github.com/google/uuid/commit/cd5fbbdd02f3e3467ac18940e07e062be1f864b4)) + +### Fixes + +* Clarify that Parse's job is to parse but not necessarily validate strings. (Documents current behavior) + +## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18) + + +### Bug Fixes + +* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0)) + +## Changelog diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md index 04fdf09f13..a502fdc515 100644 --- a/vendor/github.com/google/uuid/CONTRIBUTING.md +++ b/vendor/github.com/google/uuid/CONTRIBUTING.md @@ -2,6 +2,22 @@ We definitely welcome patches and contribution to this project! +### Tips + +Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org). + +Always try to include a test case! If it is not possible or not necessary, +please explain why in the pull request description. + +### Releasing + +Commits that would precipitate a SemVer change, as described in the Conventional +Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action) +to create a release candidate pull request. Once submitted, `release-please` +will create a release. + +For tips on how to work with `release-please`, see its documentation. + ### Legal requirements In order to protect both you and ourselves, you will need to sign the diff --git a/vendor/github.com/google/uuid/README.md b/vendor/github.com/google/uuid/README.md index f765a46f91..3e9a61889d 100644 --- a/vendor/github.com/google/uuid/README.md +++ b/vendor/github.com/google/uuid/README.md @@ -1,6 +1,6 @@ -# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master) +# uuid The uuid package generates and inspects UUIDs based on -[RFC 4122](http://tools.ietf.org/html/rfc4122) +[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) and DCE 1.1: Authentication and Security Services. This package is based on the github.com/pborman/uuid package (previously named @@ -9,10 +9,12 @@ a UUID is a 16 byte array rather than a byte slice. One loss due to this change is the ability to represent an invalid UUID (vs a NIL UUID). ###### Install -`go get github.com/google/uuid` +```sh +go get github.com/google/uuid +``` ###### Documentation -[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid) +[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid) Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here: diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go index b404f4bec2..dc60082d3b 100644 --- a/vendor/github.com/google/uuid/hash.go +++ b/vendor/github.com/google/uuid/hash.go @@ -17,6 +17,12 @@ var ( NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) Nil UUID // empty UUID, all zeros + + // The Max UUID is special form of UUID that is specified to have all 128 bits set to 1. + Max = UUID{ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + } ) // NewHash returns a new UUID derived from the hash of space concatenated with diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go index 24b78edc90..b2a0bc8711 100644 --- a/vendor/github.com/google/uuid/node_js.go +++ b/vendor/github.com/google/uuid/node_js.go @@ -7,6 +7,6 @@ package uuid // getHardwareInterface returns nil values for the JS version of the code. -// This remvoves the "net" dependency, because it is not used in the browser. +// This removes the "net" dependency, because it is not used in the browser. // Using the "net" library inflates the size of the transpiled JS code by 673k bytes. func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go index e6ef06cdc8..c351129279 100644 --- a/vendor/github.com/google/uuid/time.go +++ b/vendor/github.com/google/uuid/time.go @@ -108,12 +108,23 @@ func setClockSequence(seq int) { } // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in -// uuid. The time is only defined for version 1 and 2 UUIDs. +// uuid. The time is only defined for version 1, 2, 6 and 7 UUIDs. func (uuid UUID) Time() Time { - time := int64(binary.BigEndian.Uint32(uuid[0:4])) - time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 - time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 - return Time(time) + var t Time + switch uuid.Version() { + case 6: + time := binary.BigEndian.Uint64(uuid[:8]) // Ignore uuid[6] version b0110 + t = Time(time) + case 7: + time := binary.BigEndian.Uint64(uuid[:8]) + t = Time((time>>16)*10000 + g1582ns100) + default: // forward compatible + time := int64(binary.BigEndian.Uint32(uuid[0:4])) + time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 + time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 + t = Time(time) + } + return t } // ClockSequence returns the clock sequence encoded in uuid. diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index a57207aeb6..5232b48678 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -56,11 +56,15 @@ func IsInvalidLengthError(err error) bool { return ok } -// Parse decodes s into a UUID or returns an error. Both the standard UUID -// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the -// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex -// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. +// Parse decodes s into a UUID or returns an error if it cannot be parsed. Both +// the standard UUID forms defined in RFC 4122 +// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded. In addition, +// Parse accepts non-standard strings such as the raw hex encoding +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte "Microsoft style" encodings, +// e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Only the middle 36 bytes are +// examined in the latter case. Parse should not be used to validate strings as +// it parses non-standard encodings as indicated above. func Parse(s string) (UUID, error) { var uuid UUID switch len(s) { @@ -69,7 +73,7 @@ func Parse(s string) (UUID, error) { // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: - if strings.ToLower(s[:9]) != "urn:uuid:" { + if !strings.EqualFold(s[:9], "urn:uuid:") { return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) } s = s[9:] @@ -101,7 +105,8 @@ func Parse(s string) (UUID, error) { 9, 11, 14, 16, 19, 21, - 24, 26, 28, 30, 32, 34} { + 24, 26, 28, 30, 32, 34, + } { v, ok := xtob(s[x], s[x+1]) if !ok { return uuid, errors.New("invalid UUID format") @@ -117,7 +122,7 @@ func ParseBytes(b []byte) (UUID, error) { switch len(b) { case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { + if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) { return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) } b = b[9:] @@ -145,7 +150,8 @@ func ParseBytes(b []byte) (UUID, error) { 9, 11, 14, 16, 19, 21, - 24, 26, 28, 30, 32, 34} { + 24, 26, 28, 30, 32, 34, + } { v, ok := xtob(b[x], b[x+1]) if !ok { return uuid, errors.New("invalid UUID format") @@ -180,6 +186,59 @@ func Must(uuid UUID, err error) UUID { return uuid } +// Validate returns an error if s is not a properly formatted UUID in one of the following formats: +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} +// It returns an error if the format is invalid, otherwise nil. +func Validate(s string) error { + switch len(s) { + // Standard UUID format + case 36: + + // UUID with "urn:uuid:" prefix + case 36 + 9: + if !strings.EqualFold(s[:9], "urn:uuid:") { + return fmt.Errorf("invalid urn prefix: %q", s[:9]) + } + s = s[9:] + + // UUID enclosed in braces + case 36 + 2: + if s[0] != '{' || s[len(s)-1] != '}' { + return fmt.Errorf("invalid bracketed UUID format") + } + s = s[1 : len(s)-1] + + // UUID without hyphens + case 32: + for i := 0; i < len(s); i += 2 { + _, ok := xtob(s[i], s[i+1]) + if !ok { + return errors.New("invalid UUID format") + } + } + + default: + return invalidLengthError{len(s)} + } + + // Check for standard UUID format + if len(s) == 36 { + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return errors.New("invalid UUID format") + } + for _, x := range []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { + if _, ok := xtob(s[x], s[x+1]); !ok { + return errors.New("invalid UUID format") + } + } + } + + return nil +} + // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // , or "" if uuid is invalid. func (uuid UUID) String() string { @@ -292,3 +351,15 @@ func DisableRandPool() { poolMu.Lock() poolPos = randPoolSize } + +// UUIDs is a slice of UUID types. +type UUIDs []UUID + +// Strings returns a string slice containing the string form of each UUID in uuids. +func (uuids UUIDs) Strings() []string { + var uuidStrs = make([]string, len(uuids)) + for i, uuid := range uuids { + uuidStrs[i] = uuid.String() + } + return uuidStrs +} diff --git a/vendor/github.com/google/uuid/version6.go b/vendor/github.com/google/uuid/version6.go new file mode 100644 index 0000000000..339a959a7a --- /dev/null +++ b/vendor/github.com/google/uuid/version6.go @@ -0,0 +1,56 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "encoding/binary" + +// UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality. +// It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs. +// Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6 +// +// NewV6 returns a Version 6 UUID based on the current NodeID and clock +// sequence, and the current time. If the NodeID has not been set by SetNodeID +// or SetNodeInterface then it will be set automatically. If the NodeID cannot +// be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by +// SetClockSequence then it will be set automatically. If GetTime fails to +// return the current NewV6 returns Nil and an error. +func NewV6() (UUID, error) { + var uuid UUID + now, seq, err := GetTime() + if err != nil { + return uuid, err + } + + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_high | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_mid | time_low_and_version | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |clk_seq_hi_res | clk_seq_low | node (0-1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | node (2-5) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + binary.BigEndian.PutUint64(uuid[0:], uint64(now)) + binary.BigEndian.PutUint16(uuid[8:], seq) + + uuid[6] = 0x60 | (uuid[6] & 0x0F) + uuid[8] = 0x80 | (uuid[8] & 0x3F) + + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + copy(uuid[10:], nodeID[:]) + nodeMu.Unlock() + + return uuid, nil +} diff --git a/vendor/github.com/google/uuid/version7.go b/vendor/github.com/google/uuid/version7.go new file mode 100644 index 0000000000..3167b643d4 --- /dev/null +++ b/vendor/github.com/google/uuid/version7.go @@ -0,0 +1,104 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "io" +) + +// UUID version 7 features a time-ordered value field derived from the widely +// implemented and well known Unix Epoch timestamp source, +// the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded. +// As well as improved entropy characteristics over versions 1 or 6. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#name-uuid-version-7 +// +// Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible. +// +// NewV7 returns a Version 7 UUID based on the current time(Unix Epoch). +// Uses the randomness pool if it was enabled with EnableRandPool. +// On error, NewV7 returns Nil and an error +func NewV7() (UUID, error) { + uuid, err := NewRandom() + if err != nil { + return uuid, err + } + makeV7(uuid[:]) + return uuid, nil +} + +// NewV7FromReader returns a Version 7 UUID based on the current time(Unix Epoch). +// it use NewRandomFromReader fill random bits. +// On error, NewV7FromReader returns Nil and an error. +func NewV7FromReader(r io.Reader) (UUID, error) { + uuid, err := NewRandomFromReader(r) + if err != nil { + return uuid, err + } + + makeV7(uuid[:]) + return uuid, nil +} + +// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6]) +// uuid[8] already has the right version number (Variant is 10) +// see function NewV7 and NewV7FromReader +func makeV7(uuid []byte) { + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | ver | rand_a (12 bit seq) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |var| rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + _ = uuid[15] // bounds check + + t, s := getV7Time() + + uuid[0] = byte(t >> 40) + uuid[1] = byte(t >> 32) + uuid[2] = byte(t >> 24) + uuid[3] = byte(t >> 16) + uuid[4] = byte(t >> 8) + uuid[5] = byte(t) + + uuid[6] = 0x70 | (0x0F & byte(s>>8)) + uuid[7] = byte(s) +} + +// lastV7time is the last time we returned stored as: +// +// 52 bits of time in milliseconds since epoch +// 12 bits of (fractional nanoseconds) >> 8 +var lastV7time int64 + +const nanoPerMilli = 1000000 + +// getV7Time returns the time in milliseconds and nanoseconds / 256. +// The returned (milli << 12 + seq) is guarenteed to be greater than +// (milli << 12 + seq) returned by any previous call to getV7Time. +func getV7Time() (milli, seq int64) { + timeMu.Lock() + defer timeMu.Unlock() + + nano := timeNow().UnixNano() + milli = nano / nanoPerMilli + // Sequence number is between 0 and 3906 (nanoPerMilli>>8) + seq = (nano - milli*nanoPerMilli) >> 8 + now := milli<<12 + seq + if now <= lastV7time { + now = lastV7time + 1 + milli = now >> 12 + seq = now & 0xfff + } + lastV7time = now + return milli, seq +} diff --git a/vendor/github.com/imacks/bitflags-go/.gitignore b/vendor/github.com/gowebpki/jcs/.gitignore similarity index 53% rename from vendor/github.com/imacks/bitflags-go/.gitignore rename to vendor/github.com/gowebpki/jcs/.gitignore index 3b735ec4a8..a692565e11 100644 --- a/vendor/github.com/imacks/bitflags-go/.gitignore +++ b/vendor/github.com/gowebpki/jcs/.gitignore @@ -1,6 +1,8 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + # Binaries for programs and plugins *.exe *.exe~ @@ -13,9 +15,20 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out +coverageout +coverage.html +goreportcard.db # Dependency directories (remove the comment below to include it) # vendor/ -# Go workspace file -go.work +# vscode +*/.vscode +*.code-workspace + +# sublime text +*.sublime-workspace +*.sublime-project + +# Mac files +.DS_Store diff --git a/vendor/github.com/gowebpki/jcs/LICENSE b/vendor/github.com/gowebpki/jcs/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/vendor/github.com/gowebpki/jcs/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/gowebpki/jcs/README.md b/vendor/github.com/gowebpki/jcs/README.md new file mode 100644 index 0000000000..c2c976784e --- /dev/null +++ b/vendor/github.com/gowebpki/jcs/README.md @@ -0,0 +1,72 @@ +![JCS](https://cyberphone.github.io/doc/security/jcs.svg) + +# JSON Canonicalization + +[![Go Report Card](https://goreportcard.com/badge/github.com/gowebpki/jcs)](https://goreportcard.com/report/github.com/gowebpki/jcs) +[![godoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://pkg.go.dev/github.com/gowebpki/jcs) +[![GitHub license](https://img.shields.io/github/license/gowebpki/jcs.svg?style=flat)](https://github.com/gowebpki/jcs/blob/master/LICENSE) +[![GitHub go.mod Go version of a Go module](https://img.shields.io/github/go-mod/go-version/gowebpki/jcs.svg?style=flat)](https://github.com/gowebpki/jcs) + +Cryptographic operations like hashing and signing depend on that the target +data does not change during serialization, transport, or parsing. +By applying the rules defined by JCS (JSON Canonicalization Scheme), +data provided in the JSON [[RFC8259](https://tools.ietf.org/html/rfc8259)] +format can be exchanged "as is", while still being subject to secure cryptographic operations. +JCS achieves this by building on the serialization formats for JSON +primitives as defined by ECMAScript [[ES](https://ecma-international.org/ecma-262/)], +constraining JSON data to the I-JSON [[RFC7493](https://tools.ietf.org/html//rfc7493)] subset, +and through a platform independent property sorting scheme. + +Public RFC: https://tools.ietf.org/html/rfc8785 + +The JSON Canonicalization Scheme concept in a nutshell: +- Serialization of primitive JSON data types using methods compatible with ECMAScript's `JSON.stringify()` +- Lexicographic sorting of JSON `Object` properties in a *recursive* process +- JSON `Array` data is also subject to canonicalization, *but element order remains untouched* + +### Original Work + +This code was originally created by Anders Rundgren aka cyberphone and can be found here: +https://github.com/cyberphone/json-canonicalization. This fork and work is done with Anders' +permission and is an attempt to clean up the Golang version. + + +### Sample Input +```code +{ + "numbers": [333333333.33333329, 1E30, 4.50, 2e-3, 0.000000000000000000000000001], + "string": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/", + "literals": [null, true, false] +} +``` +### Expected Output +```code +{"literals":[null,true,false],"numbers":[333333333.3333333,1e+30,4.5,0.002,1e-27],"string":"€$\u000f\nA'B\"\\\\\"/"} +``` + +Note: for platform interoperable canonicalization, the output must be converted to UTF-8 +as well, here shown in hexadecimal notation: + +```code +7b 22 6c 69 74 65 72 61 6c 73 22 3a 5b 6e 75 6c 6c 2c 74 72 75 65 2c 66 61 6c 73 65 5d 2c 22 6e +75 6d 62 65 72 73 22 3a 5b 33 33 33 33 33 33 33 33 33 2e 33 33 33 33 33 33 33 2c 31 65 2b 33 30 +2c 34 2e 35 2c 30 2e 30 30 32 2c 31 65 2d 32 37 5d 2c 22 73 74 72 69 6e 67 22 3a 22 e2 82 ac 24 +5c 75 30 30 30 66 5c 6e 41 27 42 5c 22 5c 5c 5c 5c 5c 22 2f 22 7d +``` +### Combining JCS and JWS (RFC7515) +[JWS-JCS](https://github.com/cyberphone/jws-jcs#combining-detached-jws-with-jcs-json-canonicalization-scheme) + +### On-line Browser JCS Test +https://cyberphone.github.io/doc/security/browser-json-canonicalization.html + +### ECMAScript Proposal: JSON.canonify() +[JSON.canonify()](https://github.com/cyberphone/json-canonicalization/blob/master/JSON.canonify.md) + +### Other Canonicalization Efforts +https://tools.ietf.org/html/draft-staykov-hu-json-canonical-form-00 + +http://wiki.laptop.org/go/Canonical_JSON + +https://gibson042.github.io/canonicaljson-spec/ + +https://gist.github.com/mikesamuel/20710f94a53e440691f04bf79bc3d756 diff --git a/vendor/github.com/gowebpki/jcs/es6numfmt.go b/vendor/github.com/gowebpki/jcs/es6numfmt.go new file mode 100644 index 0000000000..011e1df554 --- /dev/null +++ b/vendor/github.com/gowebpki/jcs/es6numfmt.go @@ -0,0 +1,59 @@ +// Copyright 2021 Bret Jordan & Benedikt Thoma, All rights reserved. +// Copyright 2006-2019 WebPKI.org (http://webpki.org). +// +// Use of this source code is governed by an Apache 2.0 license that can be +// found in the LICENSE file in the root of the source tree. + +package jcs + +import ( + "errors" + "math" + "strconv" + "strings" +) + +const invalidPattern uint64 = 0x7ff0000000000000 + +// NumberToJSON converts numbers in IEEE-754 double precision into the +// format specified for JSON in EcmaScript Version 6 and forward. +// The core application for this is canonicalization per RFC 8785: +func NumberToJSON(ieeeF64 float64) (res string, err error) { + ieeeU64 := math.Float64bits(ieeeF64) + + // Special case: NaN and Infinity are invalid in JSON + if (ieeeU64 & invalidPattern) == invalidPattern { + return "null", errors.New("Invalid JSON number: " + strconv.FormatUint(ieeeU64, 16)) + } + + // Special case: eliminate "-0" as mandated by the ES6-JSON/JCS specifications + if ieeeF64 == 0 { // Right, this line takes both -0 and 0 + return "0", nil + } + + // Deal with the sign separately + var sign string = "" + if ieeeF64 < 0 { + ieeeF64 = -ieeeF64 + sign = "-" + } + + // ES6 has a unique "g" format + var format byte = 'e' + if ieeeF64 < 1e+21 && ieeeF64 >= 1e-6 { + format = 'f' + } + + // The following should (in "theory") do the trick: + es6Formatted := strconv.FormatFloat(ieeeF64, format, -1, 64) + + // Ryu version + exponent := strings.IndexByte(es6Formatted, 'e') + if exponent > 0 { + // Go outputs "1e+09" which must be rewritten as "1e+9" + if es6Formatted[exponent+2] == '0' { + es6Formatted = es6Formatted[:exponent+2] + es6Formatted[exponent+3:] + } + } + return sign + es6Formatted, nil +} diff --git a/vendor/github.com/gowebpki/jcs/jcs.go b/vendor/github.com/gowebpki/jcs/jcs.go new file mode 100644 index 0000000000..f67524c544 --- /dev/null +++ b/vendor/github.com/gowebpki/jcs/jcs.go @@ -0,0 +1,489 @@ +// Copyright 2021 Bret Jordan & Benedikt Thoma, All rights reserved. +// Copyright 2006-2019 WebPKI.org (http://webpki.org). +// +// Use of this source code is governed by an Apache 2.0 license that can be +// found in the LICENSE file in the root of the source tree. + +// Package jcs transforms UTF-8 JSON data into a canonicalized version according RFC 8785 +package jcs + +import ( + "container/list" + "errors" + "fmt" + "strconv" + "strings" + "unicode/utf16" +) + +type nameValueType struct { + name string + sortKey []uint16 + value string +} + +type jcsData struct { + // JSON data MUST be UTF-8 encoded + jsonData []byte + // Current pointer in jsonData + index int +} + +// JSON standard escapes (modulo \u) +var ( + asciiEscapes = []byte{'\\', '"', 'b', 'f', 'n', 'r', 't'} + binaryEscapes = []byte{'\\', '"', '\b', '\f', '\n', '\r', '\t'} +) + +// JSON literals +var literals = []string{"true", "false", "null"} + +// Transform converts raw JSON data from a []byte array into a canonicalized version according RFC 8785 +func Transform(jsonData []byte) ([]byte, error) { + if jsonData == nil { + return nil, errors.New("No JSON data provided") + } + + // Create a JCS Data struct to store the JSON Data and the index. + var jd jcsData + jd.jsonData = jsonData + j := &jd + + transformed, err := j.parseEntry() + if err != nil { + return nil, err + } + + for j.index < len(j.jsonData) { + if !j.isWhiteSpace(j.jsonData[j.index]) { + return nil, errors.New("Improperly terminated JSON object") + } + j.index++ + } + return []byte(transformed), err +} + +func (j *jcsData) isWhiteSpace(c byte) bool { + return c == 0x20 || c == 0x0a || c == 0x0d || c == 0x09 +} + +func (j *jcsData) nextChar() (byte, error) { + if j.index < len(j.jsonData) { + c := j.jsonData[j.index] + if c > 0x7f { + return 0, errors.New("Unexpected non-ASCII character") + } + j.index++ + return c, nil + } + return 0, errors.New("Unexpected EOF reached") +} + +// scan advances index on jsonData to the first non whitespace character and returns it. +func (j *jcsData) scan() (byte, error) { + for { + c, err := j.nextChar() + if err != nil { + return 0, err + } + + if j.isWhiteSpace(c) { + continue + } + + return c, nil + } +} + +func (j *jcsData) scanFor(expected byte) error { + c, err := j.scan() + if err != nil { + return err + } + if c != expected { + return fmt.Errorf("Expected %s but got %s", string(expected), string(c)) + } + return nil +} + +func (j *jcsData) getUEscape() (rune, error) { + start := j.index + for i := 0; i < 4; i++ { + _, err := j.nextChar() + if err != nil { + return 0, err + } + } + + u16, err := strconv.ParseUint(string(j.jsonData[start:j.index]), 16, 64) + if err != nil { + return 0, err + } + return rune(u16), nil +} + +func (j *jcsData) decorateString(rawUTF8 string) string { + var quotedString strings.Builder + quotedString.WriteByte('"') + +CoreLoop: + for _, c := range []byte(rawUTF8) { + // Is this within the JSON standard escapes? + for i, esc := range binaryEscapes { + if esc == c { + quotedString.WriteByte('\\') + quotedString.WriteByte(asciiEscapes[i]) + + continue CoreLoop + } + } + if c < 0x20 { + // Other ASCII control characters must be escaped with \uhhhh + quotedString.WriteString(fmt.Sprintf("\\u%04x", c)) + } else { + quotedString.WriteByte(c) + } + } + quotedString.WriteByte('"') + + return quotedString.String() +} + +// parseEntry is the entrypoint into the parsing control flow +func (j *jcsData) parseEntry() (string, error) { + c, err := j.scan() + if err != nil { + return "", err + } + j.index-- + + switch c { + case '{', '"', '[': + return j.parseElement() + default: + value, err := parseLiteral(string(j.jsonData)) + if err != nil { + return "", err + } + + j.index = len(j.jsonData) + return value, nil + } +} + +func (j *jcsData) parseQuotedString() (string, error) { + var rawString strings.Builder + +CoreLoop: + for { + var c byte + if j.index < len(j.jsonData) { + c = j.jsonData[j.index] + j.index++ + } else { + return "", errors.New("Unexpected EOF reached") + } + + if c == '"' { + break + } + + if c < ' ' { + return "", errors.New("Unterminated string literal") + } else if c == '\\' { + // Escape sequence + c, err := j.nextChar() + if err != nil { + return "", err + } + + if c == 'u' { + // The \u escape + firstUTF16, err := j.getUEscape() + if err != nil { + return "", err + } + + if utf16.IsSurrogate(firstUTF16) { + // If the first UTF-16 code unit has a certain value there must be + // another succeeding UTF-16 code unit as well + backslash, err := j.nextChar() + if err != nil { + return "", err + } + u, err := j.nextChar() + if err != nil { + return "", err + } + + if backslash != '\\' || u != 'u' { + return "", errors.New("Missing surrogate") + } + + // Output the UTF-32 code point as UTF-8 + uEscape, err := j.getUEscape() + if err != nil { + return "", err + } + rawString.WriteRune(utf16.DecodeRune(firstUTF16, uEscape)) + + } else { + // Single UTF-16 code identical to UTF-32. Output as UTF-8 + rawString.WriteRune(firstUTF16) + } + } else if c == '/' { + // Benign but useless escape + rawString.WriteByte('/') + } else { + // The JSON standard escapes + for i, esc := range asciiEscapes { + if esc == c { + rawString.WriteByte(binaryEscapes[i]) + continue CoreLoop + } + } + return "", fmt.Errorf("Unexpected escape: \\%s", string(c)) + } + } else { + // Just an ordinary ASCII character alternatively a UTF-8 byte + // outside of ASCII. + // Note that properly formatted UTF-8 never clashes with ASCII + // making byte per byte search for ASCII break characters work + // as expected. + rawString.WriteByte(c) + } + } + + return rawString.String(), nil +} + +func (j *jcsData) parseSimpleType() (string, error) { + var token strings.Builder + + j.index-- + + // no condition is needed here. + // if the buffer reaches EOF scan returns an error, or we terminate because the + // json simple type terminates + for { + c, err := j.scan() + if err != nil { + return "", err + } + + if c == ',' || c == ']' || c == '}' { + j.index-- + break + } + + token.WriteByte(c) + } + + if token.Len() == 0 { + return "", errors.New("Missing argument") + } + + return parseLiteral(token.String()) +} + +func parseLiteral(value string) (string, error) { + // Is it a JSON literal? + for _, literal := range literals { + if literal == value { + return literal, nil + } + } + + // Apparently not so we assume that it is a I-JSON number + ieeeF64, err := strconv.ParseFloat(value, 64) + if err != nil { + return "", err + } + + value, err = NumberToJSON(ieeeF64) + if err != nil { + return "", err + } + + return value, nil +} + +func (j *jcsData) parseElement() (string, error) { + c, err := j.scan() + if err != nil { + return "", err + } + + switch c { + case '{': + return j.parseObject() + case '"': + str, err := j.parseQuotedString() + if err != nil { + return "", err + } + return j.decorateString(str), nil + case '[': + return j.parseArray() + default: + return j.parseSimpleType() + } +} + +func (j *jcsData) peek() (byte, error) { + c, err := j.scan() + if err != nil { + return 0, err + } + + j.index-- + return c, nil +} + +func (j *jcsData) parseArray() (string, error) { + var arrayData strings.Builder + var next bool + + arrayData.WriteByte('[') + + for { + c, err := j.peek() + if err != nil { + return "", err + } + + if c == ']' { + j.index++ + break + } + + if next { + err = j.scanFor(',') + if err != nil { + return "", err + } + arrayData.WriteByte(',') + } else { + next = true + } + + element, err := j.parseElement() + if err != nil { + return "", err + } + arrayData.WriteString(element) + } + + arrayData.WriteByte(']') + return arrayData.String(), nil +} + +func (j *jcsData) lexicographicallyPrecedes(sortKey []uint16, e *list.Element) (bool, error) { + // Find the minimum length of the sortKeys + oldSortKey := e.Value.(nameValueType).sortKey + minLength := len(oldSortKey) + if minLength > len(sortKey) { + minLength = len(sortKey) + } + for q := 0; q < minLength; q++ { + diff := int(sortKey[q]) - int(oldSortKey[q]) + if diff < 0 { + // Smaller => Precedes + return true, nil + } else if diff > 0 { + // Bigger => No match + return false, nil + } + // Still equal => Continue + } + // The sortKeys compared equal up to minLength + if len(sortKey) < len(oldSortKey) { + // Shorter => Precedes + return true, nil + } + if len(sortKey) == len(oldSortKey) { + return false, fmt.Errorf("Duplicate key: %s", e.Value.(nameValueType).name) + } + // Longer => No match + return false, nil +} + +func (j *jcsData) parseObject() (string, error) { + nameValueList := list.New() + var next bool = false +CoreLoop: + for { + c, err := j.peek() + if err != nil { + return "", err + } + + if c == '}' { + // advance index because of peeked '}' + j.index++ + break + } + + if next { + err = j.scanFor(',') + if err != nil { + return "", err + } + } + next = true + + err = j.scanFor('"') + if err != nil { + return "", err + } + rawUTF8, err := j.parseQuotedString() + if err != nil { + break + } + // Sort keys on UTF-16 code units + // Since UTF-8 doesn't have endianess this is just a value transformation + // In the Go case the transformation is UTF-8 => UTF-32 => UTF-16 + sortKey := utf16.Encode([]rune(rawUTF8)) + err = j.scanFor(':') + if err != nil { + return "", err + } + + element, err := j.parseElement() + if err != nil { + return "", err + } + nameValue := nameValueType{rawUTF8, sortKey, element} + for e := nameValueList.Front(); e != nil; e = e.Next() { + // Check if the key is smaller than a previous key + if precedes, err := j.lexicographicallyPrecedes(sortKey, e); err != nil { + return "", err + } else if precedes { + // Precedes => Insert before and exit sorting + nameValueList.InsertBefore(nameValue, e) + continue CoreLoop + } + // Continue searching for a possibly succeeding sortKey + // (which is straightforward since the list is ordered) + } + // The sortKey is either the first or is succeeding all previous sortKeys + nameValueList.PushBack(nameValue) + } + + // Now everything is sorted so we can properly serialize the object + var objectData strings.Builder + objectData.WriteByte('{') + next = false + for e := nameValueList.Front(); e != nil; e = e.Next() { + if next { + objectData.WriteByte(',') + } + next = true + nameValue := e.Value.(nameValueType) + objectData.WriteString(j.decorateString(nameValue.name)) + objectData.WriteByte(':') + objectData.WriteString(nameValue.value) + } + objectData.WriteByte('}') + return objectData.String(), nil +} diff --git a/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go b/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go index 8d306bf513..fe28d15b6f 100644 --- a/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go +++ b/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go @@ -32,6 +32,7 @@ func DefaultPooledTransport() *http.Transport { IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, + ForceAttemptHTTP2: true, MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1, } return transport diff --git a/vendor/github.com/hashicorp/go-retryablehttp/.go-version b/vendor/github.com/hashicorp/go-retryablehttp/.go-version new file mode 100644 index 0000000000..6fee2fedb0 --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/.go-version @@ -0,0 +1 @@ +1.22.2 diff --git a/vendor/github.com/hashicorp/go-retryablehttp/CHANGELOG.md b/vendor/github.com/hashicorp/go-retryablehttp/CHANGELOG.md new file mode 100644 index 0000000000..68a627c6d9 --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/CHANGELOG.md @@ -0,0 +1,33 @@ +## 0.7.7 (May 30, 2024) + +BUG FIXES: + +- client: avoid potentially leaking URL-embedded basic authentication credentials in logs (#158) + +## 0.7.6 (May 9, 2024) + +ENHANCEMENTS: + +- client: support a `RetryPrepare` function for modifying the request before retrying (#216) +- client: support HTTP-date values for `Retry-After` header value (#138) +- client: avoid reading entire body when the body is a `*bytes.Reader` (#197) + +BUG FIXES: + +- client: fix a broken check for invalid server certificate in go 1.20+ (#210) + +## 0.7.5 (Nov 8, 2023) + +BUG FIXES: + +- client: fixes an issue where the request body is not preserved on temporary redirects or re-established HTTP/2 connections (#207) + +## 0.7.4 (Jun 6, 2023) + +BUG FIXES: + +- client: fixing an issue where the Content-Type header wouldn't be sent with an empty payload when using HTTP/2 (#194) + +## 0.7.3 (May 15, 2023) + +Initial release diff --git a/vendor/github.com/hashicorp/go-retryablehttp/CODEOWNERS b/vendor/github.com/hashicorp/go-retryablehttp/CODEOWNERS new file mode 100644 index 0000000000..d6dd78a2dd --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/CODEOWNERS @@ -0,0 +1 @@ +* @hashicorp/go-retryablehttp-maintainers diff --git a/vendor/github.com/hashicorp/go-retryablehttp/LICENSE b/vendor/github.com/hashicorp/go-retryablehttp/LICENSE index e87a115e46..f4f97ee585 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/LICENSE +++ b/vendor/github.com/hashicorp/go-retryablehttp/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2015 HashiCorp, Inc. + Mozilla Public License, version 2.0 1. Definitions diff --git a/vendor/github.com/hashicorp/go-retryablehttp/Makefile b/vendor/github.com/hashicorp/go-retryablehttp/Makefile index da17640e64..5255241961 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/Makefile +++ b/vendor/github.com/hashicorp/go-retryablehttp/Makefile @@ -2,7 +2,7 @@ default: test test: go vet ./... - go test -race ./... + go test -v -race ./... updatedeps: go get -f -t -u ./... diff --git a/vendor/github.com/hashicorp/go-retryablehttp/README.md b/vendor/github.com/hashicorp/go-retryablehttp/README.md index 30357c7566..145a62f218 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/README.md +++ b/vendor/github.com/hashicorp/go-retryablehttp/README.md @@ -26,6 +26,7 @@ fails so that the full request can be attempted again. See the details. Version 0.6.0 and before are compatible with Go prior to 1.12. From 0.6.1 onward, Go 1.12+ is required. +From 0.6.7 onward, Go 1.13+ is required. Example Use =========== @@ -58,4 +59,4 @@ standardClient := retryClient.StandardClient() // *http.Client ``` For more usage and examples see the -[godoc](http://godoc.org/github.com/hashicorp/go-retryablehttp). +[pkg.go.dev](https://pkg.go.dev/github.com/hashicorp/go-retryablehttp). diff --git a/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go119.go b/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go119.go new file mode 100644 index 0000000000..b2b27e8722 --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go119.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build !go1.20 +// +build !go1.20 + +package retryablehttp + +import "crypto/x509" + +func isCertError(err error) bool { + _, ok := err.(x509.UnknownAuthorityError) + return ok +} diff --git a/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go120.go b/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go120.go new file mode 100644 index 0000000000..a3cd315a28 --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go120.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build go1.20 +// +build go1.20 + +package retryablehttp + +import "crypto/tls" + +func isCertError(err error) bool { + _, ok := err.(*tls.CertificateVerificationError) + return ok +} diff --git a/vendor/github.com/hashicorp/go-retryablehttp/client.go b/vendor/github.com/hashicorp/go-retryablehttp/client.go index a23f9a93f2..efee53c400 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/client.go +++ b/vendor/github.com/hashicorp/go-retryablehttp/client.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + // Package retryablehttp provides a familiar HTTP client interface with // automatic retries and exponential backoff. It is a thin wrapper over the // standard net/http client library and exposes nearly the same public API. @@ -24,10 +27,8 @@ package retryablehttp import ( "bytes" "context" - "crypto/x509" "fmt" "io" - "io/ioutil" "log" "math" "math/rand" @@ -60,6 +61,10 @@ var ( // limit the size we consume to respReadLimit. respReadLimit = int64(4096) + // timeNow sets the function that returns the current time. + // This defaults to time.Now. Changes to this should only be done in tests. + timeNow = time.Now + // A regular expression to match the error returned by net/http when the // configured number of redirects is exhausted. This error isn't typed // specifically so we resort to matching on the error string. @@ -69,11 +74,33 @@ var ( // scheme specified in the URL is invalid. This error isn't typed // specifically so we resort to matching on the error string. schemeErrorRe = regexp.MustCompile(`unsupported protocol scheme`) + + // A regular expression to match the error returned by net/http when a + // request header or value is invalid. This error isn't typed + // specifically so we resort to matching on the error string. + invalidHeaderErrorRe = regexp.MustCompile(`invalid header`) + + // A regular expression to match the error returned by net/http when the + // TLS certificate is not trusted. This error isn't typed + // specifically so we resort to matching on the error string. + notTrustedErrorRe = regexp.MustCompile(`certificate is not trusted`) ) // ReaderFunc is the type of function that can be given natively to NewRequest type ReaderFunc func() (io.Reader, error) +// ResponseHandlerFunc is a type of function that takes in a Response, and does something with it. +// The ResponseHandlerFunc is called when the HTTP client successfully receives a response and the +// CheckRetry function indicates that a retry of the base request is not necessary. +// If an error is returned from this function, the CheckRetry policy will be used to determine +// whether to retry the whole request (including this handler). +// +// Make sure to check status codes! Even if the request was completed it may have a non-2xx status code. +// +// The response body is not automatically closed. It must be closed either by the ResponseHandlerFunc or +// by the caller out-of-band. Failure to do so will result in a memory leak. +type ResponseHandlerFunc func(*http.Response) error + // LenReader is an interface implemented by many in-memory io.Reader's. Used // for automatically sending the right Content-Length header when possible. type LenReader interface { @@ -86,6 +113,8 @@ type Request struct { // used to rewind the request data in between retries. body ReaderFunc + responseHandler ResponseHandlerFunc + // Embed an HTTP request directly. This makes a *Request act exactly // like an *http.Request so that all meta methods are supported. *http.Request @@ -94,8 +123,16 @@ type Request struct { // WithContext returns wrapped Request with a shallow copy of underlying *http.Request // with its context changed to ctx. The provided ctx must be non-nil. func (r *Request) WithContext(ctx context.Context) *Request { - r.Request = r.Request.WithContext(ctx) - return r + return &Request{ + body: r.body, + responseHandler: r.responseHandler, + Request: r.Request.WithContext(ctx), + } +} + +// SetResponseHandler allows setting the response handler. +func (r *Request) SetResponseHandler(fn ResponseHandlerFunc) { + r.responseHandler = fn } // BodyBytes allows accessing the request body. It is an analogue to @@ -130,6 +167,20 @@ func (r *Request) SetBody(rawBody interface{}) error { } r.body = bodyReader r.ContentLength = contentLength + if bodyReader != nil { + r.GetBody = func() (io.ReadCloser, error) { + body, err := bodyReader() + if err != nil { + return nil, err + } + if rc, ok := body.(io.ReadCloser); ok { + return rc, nil + } + return io.NopCloser(body), nil + } + } else { + r.GetBody = func() (io.ReadCloser, error) { return http.NoBody, nil } + } return nil } @@ -204,21 +255,19 @@ func getBodyReaderAndContentLength(rawBody interface{}) (ReaderFunc, int64, erro // deal with it seeking so want it to match here instead of the // io.ReadSeeker case. case *bytes.Reader: - buf, err := ioutil.ReadAll(body) - if err != nil { - return nil, 0, err - } + snapshot := *body bodyReader = func() (io.Reader, error) { - return bytes.NewReader(buf), nil + r := snapshot + return &r, nil } - contentLength = int64(len(buf)) + contentLength = int64(body.Len()) // Compat case case io.ReadSeeker: raw := body bodyReader = func() (io.Reader, error) { _, err := raw.Seek(0, 0) - return ioutil.NopCloser(raw), err + return io.NopCloser(raw), err } if lr, ok := raw.(LenReader); ok { contentLength = int64(lr.Len()) @@ -226,14 +275,21 @@ func getBodyReaderAndContentLength(rawBody interface{}) (ReaderFunc, int64, erro // Read all in so we can reset case io.Reader: - buf, err := ioutil.ReadAll(body) + buf, err := io.ReadAll(body) if err != nil { return nil, 0, err } - bodyReader = func() (io.Reader, error) { - return bytes.NewReader(buf), nil + if len(buf) == 0 { + bodyReader = func() (io.Reader, error) { + return http.NoBody, nil + } + contentLength = 0 + } else { + bodyReader = func() (io.Reader, error) { + return bytes.NewReader(buf), nil + } + contentLength = int64(len(buf)) } - contentLength = int64(len(buf)) // No body provided, nothing to do case nil: @@ -252,23 +308,32 @@ func FromRequest(r *http.Request) (*Request, error) { return nil, err } // Could assert contentLength == r.ContentLength - return &Request{bodyReader, r}, nil + return &Request{body: bodyReader, Request: r}, nil } // NewRequest creates a new wrapped request. func NewRequest(method, url string, rawBody interface{}) (*Request, error) { - bodyReader, contentLength, err := getBodyReaderAndContentLength(rawBody) + return NewRequestWithContext(context.Background(), method, url, rawBody) +} + +// NewRequestWithContext creates a new wrapped request with the provided context. +// +// The context controls the entire lifetime of a request and its response: +// obtaining a connection, sending the request, and reading the response headers and body. +func NewRequestWithContext(ctx context.Context, method, url string, rawBody interface{}) (*Request, error) { + httpReq, err := http.NewRequestWithContext(ctx, method, url, nil) if err != nil { return nil, err } - httpReq, err := http.NewRequest(method, url, nil) - if err != nil { + req := &Request{ + Request: httpReq, + } + if err := req.SetBody(rawBody); err != nil { return nil, err } - httpReq.ContentLength = contentLength - return &Request{bodyReader, httpReq}, nil + return req, nil } // Logger interface allows to use other loggers than @@ -333,6 +398,9 @@ type Backoff func(min, max time.Duration, attemptNum int, resp *http.Response) t // attempted. If overriding this, be sure to close the body if needed. type ErrorHandler func(resp *http.Response, err error, numTries int) (*http.Response, error) +// PrepareRetry is called before retry operation. It can be used for example to re-sign the request +type PrepareRetry func(req *http.Request) error + // Client is used to make HTTP requests. It adds additional functionality // like automatic retries to tolerate minor outages. type Client struct { @@ -361,6 +429,9 @@ type Client struct { // ErrorHandler specifies the custom error handler to use, if any ErrorHandler ErrorHandler + // PrepareRetry can prepare the request for retry operation, for example re-sign it + PrepareRetry PrepareRetry + loggerInit sync.Once clientInit sync.Once } @@ -404,44 +475,9 @@ func DefaultRetryPolicy(ctx context.Context, resp *http.Response, err error) (bo return false, ctx.Err() } - if err != nil { - if v, ok := err.(*url.Error); ok { - // Don't retry if the error was due to too many redirects. - if redirectsErrorRe.MatchString(v.Error()) { - return false, nil - } - - // Don't retry if the error was due to an invalid protocol scheme. - if schemeErrorRe.MatchString(v.Error()) { - return false, nil - } - - // Don't retry if the error was due to TLS cert verification failure. - if _, ok := v.Err.(x509.UnknownAuthorityError); ok { - return false, nil - } - } - - // The error is likely recoverable so retry. - return true, nil - } - - // 429 Too Many Requests is recoverable. Sometimes the server puts - // a Retry-After response header to indicate when the server is - // available to start processing request from client. - if resp.StatusCode == http.StatusTooManyRequests { - return true, nil - } - - // Check the response code. We retry on 500-range responses to allow - // the server time to recover, as 500's are typically not permanent - // errors and may relate to outages on the server side. This will catch - // invalid response codes as well, like 0 and 999. - if resp.StatusCode == 0 || (resp.StatusCode >= 500 && resp.StatusCode != 501) { - return true, nil - } - - return false, nil + // don't propagate other errors + shouldRetry, _ := baseRetryPolicy(resp, err) + return shouldRetry, nil } // ErrorPropagatedRetryPolicy is the same as DefaultRetryPolicy, except it @@ -453,6 +489,10 @@ func ErrorPropagatedRetryPolicy(ctx context.Context, resp *http.Response, err er return false, ctx.Err() } + return baseRetryPolicy(resp, err) +} + +func baseRetryPolicy(resp *http.Response, err error) (bool, error) { if err != nil { if v, ok := err.(*url.Error); ok { // Don't retry if the error was due to too many redirects. @@ -465,8 +505,16 @@ func ErrorPropagatedRetryPolicy(ctx context.Context, resp *http.Response, err er return false, v } + // Don't retry if the error was due to an invalid header. + if invalidHeaderErrorRe.MatchString(v.Error()) { + return false, v + } + // Don't retry if the error was due to TLS cert verification failure. - if _, ok := v.Err.(x509.UnknownAuthorityError); ok { + if notTrustedErrorRe.MatchString(v.Error()) { + return false, v + } + if isCertError(v.Err) { return false, v } } @@ -475,11 +523,18 @@ func ErrorPropagatedRetryPolicy(ctx context.Context, resp *http.Response, err er return true, nil } + // 429 Too Many Requests is recoverable. Sometimes the server puts + // a Retry-After response header to indicate when the server is + // available to start processing request from client. + if resp.StatusCode == http.StatusTooManyRequests { + return true, nil + } + // Check the response code. We retry on 500-range responses to allow // the server time to recover, as 500's are typically not permanent // errors and may relate to outages on the server side. This will catch // invalid response codes as well, like 0 and 999. - if resp.StatusCode == 0 || (resp.StatusCode >= 500 && resp.StatusCode != 501) { + if resp.StatusCode == 0 || (resp.StatusCode >= 500 && resp.StatusCode != http.StatusNotImplemented) { return true, fmt.Errorf("unexpected HTTP status %s", resp.Status) } @@ -495,11 +550,9 @@ func ErrorPropagatedRetryPolicy(ctx context.Context, resp *http.Response, err er // seconds the server states it may be ready to process more requests from this client. func DefaultBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { if resp != nil { - if resp.StatusCode == http.StatusTooManyRequests { - if s, ok := resp.Header["Retry-After"]; ok { - if sleep, err := strconv.ParseInt(s[0], 10, 64); err == nil { - return time.Second * time.Duration(sleep) - } + if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode == http.StatusServiceUnavailable { + if sleep, ok := parseRetryAfterHeader(resp.Header["Retry-After"]); ok { + return sleep } } } @@ -512,6 +565,41 @@ func DefaultBackoff(min, max time.Duration, attemptNum int, resp *http.Response) return sleep } +// parseRetryAfterHeader parses the Retry-After header and returns the +// delay duration according to the spec: https://httpwg.org/specs/rfc7231.html#header.retry-after +// The bool returned will be true if the header was successfully parsed. +// Otherwise, the header was either not present, or was not parseable according to the spec. +// +// Retry-After headers come in two flavors: Seconds or HTTP-Date +// +// Examples: +// * Retry-After: Fri, 31 Dec 1999 23:59:59 GMT +// * Retry-After: 120 +func parseRetryAfterHeader(headers []string) (time.Duration, bool) { + if len(headers) == 0 || headers[0] == "" { + return 0, false + } + header := headers[0] + // Retry-After: 120 + if sleep, err := strconv.ParseInt(header, 10, 64); err == nil { + if sleep < 0 { // a negative sleep doesn't make sense + return 0, false + } + return time.Second * time.Duration(sleep), true + } + + // Retry-After: Fri, 31 Dec 1999 23:59:59 GMT + retryTime, err := time.Parse(time.RFC1123, header) + if err != nil { + return 0, false + } + if until := retryTime.Sub(timeNow()); until > 0 { + return until, true + } + // date is in the past + return 0, true +} + // LinearJitterBackoff provides a callback for Client.Backoff which will // perform linear backoff based on the attempt number and with jitter to // prevent a thundering herd. @@ -539,13 +627,13 @@ func LinearJitterBackoff(min, max time.Duration, attemptNum int, resp *http.Resp } // Seed rand; doing this every time is fine - rand := rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) + source := rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) // Pick a random number that lies somewhere between the min and max and // multiply by the attemptNum. attemptNum starts at zero so we always // increment here. We first get a random percentage, then apply that to the // difference between min and max, and add to min. - jitter := rand.Float64() * float64(max-min) + jitter := source.Float64() * float64(max-min) jitterMin := int64(jitter) + int64(min) return time.Duration(jitterMin * int64(attemptNum)) } @@ -570,22 +658,21 @@ func (c *Client) Do(req *Request) (*http.Response, error) { if logger != nil { switch v := logger.(type) { case LeveledLogger: - v.Debug("performing request", "method", req.Method, "url", req.URL) + v.Debug("performing request", "method", req.Method, "url", redactURL(req.URL)) case Logger: - v.Printf("[DEBUG] %s %s", req.Method, req.URL) + v.Printf("[DEBUG] %s %s", req.Method, redactURL(req.URL)) } } var resp *http.Response var attempt int var shouldRetry bool - var doErr, checkErr error + var doErr, respErr, checkErr, prepareErr error for i := 0; ; i++ { + doErr, respErr, prepareErr = nil, nil, nil attempt++ - var code int // HTTP response code - // Always rewind the request body when non-nil. if req.body != nil { body, err := req.body() @@ -596,7 +683,7 @@ func (c *Client) Do(req *Request) (*http.Response, error) { if c, ok := body.(io.ReadCloser); ok { req.Body = c } else { - req.Body = ioutil.NopCloser(body) + req.Body = io.NopCloser(body) } } @@ -613,19 +700,24 @@ func (c *Client) Do(req *Request) (*http.Response, error) { // Attempt the request resp, doErr = c.HTTPClient.Do(req.Request) - if resp != nil { - code = resp.StatusCode - } // Check if we should continue with retries. shouldRetry, checkErr = c.CheckRetry(req.Context(), resp, doErr) + if !shouldRetry && doErr == nil && req.responseHandler != nil { + respErr = req.responseHandler(resp) + shouldRetry, checkErr = c.CheckRetry(req.Context(), resp, respErr) + } - if doErr != nil { + err := doErr + if respErr != nil { + err = respErr + } + if err != nil { switch v := logger.(type) { case LeveledLogger: - v.Error("request failed", "error", doErr, "method", req.Method, "url", req.URL) + v.Error("request failed", "error", err, "method", req.Method, "url", redactURL(req.URL)) case Logger: - v.Printf("[ERR] %s %s request failed: %v", req.Method, req.URL, doErr) + v.Printf("[ERR] %s %s request failed: %v", req.Method, redactURL(req.URL), err) } } else { // Call this here to maintain the behavior of logging all requests, @@ -660,11 +752,11 @@ func (c *Client) Do(req *Request) (*http.Response, error) { } wait := c.Backoff(c.RetryWaitMin, c.RetryWaitMax, i, resp) - desc := fmt.Sprintf("%s %s", req.Method, req.URL) - if code > 0 { - desc = fmt.Sprintf("%s (status: %d)", desc, code) - } if logger != nil { + desc := fmt.Sprintf("%s %s", req.Method, redactURL(req.URL)) + if resp != nil { + desc = fmt.Sprintf("%s (status: %d)", desc, resp.StatusCode) + } switch v := logger.(type) { case LeveledLogger: v.Debug("retrying request", "request", desc, "timeout", wait, "remaining", remain) @@ -672,29 +764,44 @@ func (c *Client) Do(req *Request) (*http.Response, error) { v.Printf("[DEBUG] %s: retrying in %s (%d left)", desc, wait, remain) } } + timer := time.NewTimer(wait) select { case <-req.Context().Done(): + timer.Stop() c.HTTPClient.CloseIdleConnections() return nil, req.Context().Err() - case <-time.After(wait): + case <-timer.C: } // Make shallow copy of http Request so that we can modify its body // without racing against the closeBody call in persistConn.writeLoop. httpreq := *req.Request req.Request = &httpreq + + if c.PrepareRetry != nil { + if err := c.PrepareRetry(req.Request); err != nil { + prepareErr = err + break + } + } } // this is the closest we have to success criteria - if doErr == nil && checkErr == nil && !shouldRetry { + if doErr == nil && respErr == nil && checkErr == nil && prepareErr == nil && !shouldRetry { return resp, nil } defer c.HTTPClient.CloseIdleConnections() - err := doErr - if checkErr != nil { + var err error + if prepareErr != nil { + err = prepareErr + } else if checkErr != nil { err = checkErr + } else if respErr != nil { + err = respErr + } else { + err = doErr } if c.ErrorHandler != nil { @@ -711,17 +818,17 @@ func (c *Client) Do(req *Request) (*http.Response, error) { // communicate why if err == nil { return nil, fmt.Errorf("%s %s giving up after %d attempt(s)", - req.Method, req.URL, attempt) + req.Method, redactURL(req.URL), attempt) } return nil, fmt.Errorf("%s %s giving up after %d attempt(s): %w", - req.Method, req.URL, attempt, err) + req.Method, redactURL(req.URL), attempt, err) } // Try to read the response body so we can reuse this connection. func (c *Client) drainBody(body io.ReadCloser) { defer body.Close() - _, err := io.Copy(ioutil.Discard, io.LimitReader(body, respReadLimit)) + _, err := io.Copy(io.Discard, io.LimitReader(body, respReadLimit)) if err != nil { if c.logger() != nil { switch v := c.logger().(type) { @@ -796,3 +903,17 @@ func (c *Client) StandardClient() *http.Client { Transport: &RoundTripper{Client: c}, } } + +// Taken from url.URL#Redacted() which was introduced in go 1.15. +// We can switch to using it directly if we'll bump the minimum required go version. +func redactURL(u *url.URL) string { + if u == nil { + return "" + } + + ru := *u + if _, has := ru.User.Password(); has { + ru.User = url.UserPassword(ru.User.Username(), "xxxxx") + } + return ru.String() +} diff --git a/vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go b/vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go index 8f3ee35842..8c407adb3b 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go +++ b/vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package retryablehttp import ( diff --git a/vendor/github.com/hashicorp/golang-lru/README.md b/vendor/github.com/hashicorp/golang-lru/README.md deleted file mode 100644 index 33e58cfaf9..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/README.md +++ /dev/null @@ -1,25 +0,0 @@ -golang-lru -========== - -This provides the `lru` package which implements a fixed-size -thread safe LRU cache. It is based on the cache in Groupcache. - -Documentation -============= - -Full docs are available on [Godoc](http://godoc.org/github.com/hashicorp/golang-lru) - -Example -======= - -Using the LRU is very simple: - -```go -l, _ := New(128) -for i := 0; i < 256; i++ { - l.Add(i, nil) -} -if l.Len() != 128 { - panic(fmt.Sprintf("bad len: %v", l.Len())) -} -``` diff --git a/vendor/github.com/hashicorp/golang-lru/arc.go b/vendor/github.com/hashicorp/golang-lru/arc.go deleted file mode 100644 index 555225a218..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/arc.go +++ /dev/null @@ -1,257 +0,0 @@ -package lru - -import ( - "sync" - - "github.com/hashicorp/golang-lru/simplelru" -) - -// ARCCache is a thread-safe fixed size Adaptive Replacement Cache (ARC). -// ARC is an enhancement over the standard LRU cache in that tracks both -// frequency and recency of use. This avoids a burst in access to new -// entries from evicting the frequently used older entries. It adds some -// additional tracking overhead to a standard LRU cache, computationally -// it is roughly 2x the cost, and the extra memory overhead is linear -// with the size of the cache. ARC has been patented by IBM, but is -// similar to the TwoQueueCache (2Q) which requires setting parameters. -type ARCCache struct { - size int // Size is the total capacity of the cache - p int // P is the dynamic preference towards T1 or T2 - - t1 simplelru.LRUCache // T1 is the LRU for recently accessed items - b1 simplelru.LRUCache // B1 is the LRU for evictions from t1 - - t2 simplelru.LRUCache // T2 is the LRU for frequently accessed items - b2 simplelru.LRUCache // B2 is the LRU for evictions from t2 - - lock sync.RWMutex -} - -// NewARC creates an ARC of the given size -func NewARC(size int) (*ARCCache, error) { - // Create the sub LRUs - b1, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - b2, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - t1, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - t2, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - - // Initialize the ARC - c := &ARCCache{ - size: size, - p: 0, - t1: t1, - b1: b1, - t2: t2, - b2: b2, - } - return c, nil -} - -// Get looks up a key's value from the cache. -func (c *ARCCache) Get(key interface{}) (value interface{}, ok bool) { - c.lock.Lock() - defer c.lock.Unlock() - - // If the value is contained in T1 (recent), then - // promote it to T2 (frequent) - if val, ok := c.t1.Peek(key); ok { - c.t1.Remove(key) - c.t2.Add(key, val) - return val, ok - } - - // Check if the value is contained in T2 (frequent) - if val, ok := c.t2.Get(key); ok { - return val, ok - } - - // No hit - return nil, false -} - -// Add adds a value to the cache. -func (c *ARCCache) Add(key, value interface{}) { - c.lock.Lock() - defer c.lock.Unlock() - - // Check if the value is contained in T1 (recent), and potentially - // promote it to frequent T2 - if c.t1.Contains(key) { - c.t1.Remove(key) - c.t2.Add(key, value) - return - } - - // Check if the value is already in T2 (frequent) and update it - if c.t2.Contains(key) { - c.t2.Add(key, value) - return - } - - // Check if this value was recently evicted as part of the - // recently used list - if c.b1.Contains(key) { - // T1 set is too small, increase P appropriately - delta := 1 - b1Len := c.b1.Len() - b2Len := c.b2.Len() - if b2Len > b1Len { - delta = b2Len / b1Len - } - if c.p+delta >= c.size { - c.p = c.size - } else { - c.p += delta - } - - // Potentially need to make room in the cache - if c.t1.Len()+c.t2.Len() >= c.size { - c.replace(false) - } - - // Remove from B1 - c.b1.Remove(key) - - // Add the key to the frequently used list - c.t2.Add(key, value) - return - } - - // Check if this value was recently evicted as part of the - // frequently used list - if c.b2.Contains(key) { - // T2 set is too small, decrease P appropriately - delta := 1 - b1Len := c.b1.Len() - b2Len := c.b2.Len() - if b1Len > b2Len { - delta = b1Len / b2Len - } - if delta >= c.p { - c.p = 0 - } else { - c.p -= delta - } - - // Potentially need to make room in the cache - if c.t1.Len()+c.t2.Len() >= c.size { - c.replace(true) - } - - // Remove from B2 - c.b2.Remove(key) - - // Add the key to the frequently used list - c.t2.Add(key, value) - return - } - - // Potentially need to make room in the cache - if c.t1.Len()+c.t2.Len() >= c.size { - c.replace(false) - } - - // Keep the size of the ghost buffers trim - if c.b1.Len() > c.size-c.p { - c.b1.RemoveOldest() - } - if c.b2.Len() > c.p { - c.b2.RemoveOldest() - } - - // Add to the recently seen list - c.t1.Add(key, value) - return -} - -// replace is used to adaptively evict from either T1 or T2 -// based on the current learned value of P -func (c *ARCCache) replace(b2ContainsKey bool) { - t1Len := c.t1.Len() - if t1Len > 0 && (t1Len > c.p || (t1Len == c.p && b2ContainsKey)) { - k, _, ok := c.t1.RemoveOldest() - if ok { - c.b1.Add(k, nil) - } - } else { - k, _, ok := c.t2.RemoveOldest() - if ok { - c.b2.Add(k, nil) - } - } -} - -// Len returns the number of cached entries -func (c *ARCCache) Len() int { - c.lock.RLock() - defer c.lock.RUnlock() - return c.t1.Len() + c.t2.Len() -} - -// Keys returns all the cached keys -func (c *ARCCache) Keys() []interface{} { - c.lock.RLock() - defer c.lock.RUnlock() - k1 := c.t1.Keys() - k2 := c.t2.Keys() - return append(k1, k2...) -} - -// Remove is used to purge a key from the cache -func (c *ARCCache) Remove(key interface{}) { - c.lock.Lock() - defer c.lock.Unlock() - if c.t1.Remove(key) { - return - } - if c.t2.Remove(key) { - return - } - if c.b1.Remove(key) { - return - } - if c.b2.Remove(key) { - return - } -} - -// Purge is used to clear the cache -func (c *ARCCache) Purge() { - c.lock.Lock() - defer c.lock.Unlock() - c.t1.Purge() - c.t2.Purge() - c.b1.Purge() - c.b2.Purge() -} - -// Contains is used to check if the cache contains a key -// without updating recency or frequency. -func (c *ARCCache) Contains(key interface{}) bool { - c.lock.RLock() - defer c.lock.RUnlock() - return c.t1.Contains(key) || c.t2.Contains(key) -} - -// Peek is used to inspect the cache value of a key -// without updating recency or frequency. -func (c *ARCCache) Peek(key interface{}) (value interface{}, ok bool) { - c.lock.RLock() - defer c.lock.RUnlock() - if val, ok := c.t1.Peek(key); ok { - return val, ok - } - return c.t2.Peek(key) -} diff --git a/vendor/github.com/hashicorp/golang-lru/doc.go b/vendor/github.com/hashicorp/golang-lru/doc.go deleted file mode 100644 index 2547df979d..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -// Package lru provides three different LRU caches of varying sophistication. -// -// Cache is a simple LRU cache. It is based on the -// LRU implementation in groupcache: -// https://github.com/golang/groupcache/tree/master/lru -// -// TwoQueueCache tracks frequently used and recently used entries separately. -// This avoids a burst of accesses from taking out frequently used entries, -// at the cost of about 2x computational overhead and some extra bookkeeping. -// -// ARCCache is an adaptive replacement cache. It tracks recent evictions as -// well as recent usage in both the frequent and recent caches. Its -// computational overhead is comparable to TwoQueueCache, but the memory -// overhead is linear with the size of the cache. -// -// ARC has been patented by IBM, so do not use it if that is problematic for -// your program. -// -// All caches in this package take locks while operating, and are therefore -// thread-safe for consumers. -package lru diff --git a/vendor/github.com/hashicorp/golang-lru/lru.go b/vendor/github.com/hashicorp/golang-lru/lru.go deleted file mode 100644 index 4e5e9d8fd0..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/lru.go +++ /dev/null @@ -1,150 +0,0 @@ -package lru - -import ( - "sync" - - "github.com/hashicorp/golang-lru/simplelru" -) - -// Cache is a thread-safe fixed size LRU cache. -type Cache struct { - lru simplelru.LRUCache - lock sync.RWMutex -} - -// New creates an LRU of the given size. -func New(size int) (*Cache, error) { - return NewWithEvict(size, nil) -} - -// NewWithEvict constructs a fixed size cache with the given eviction -// callback. -func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) { - lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted)) - if err != nil { - return nil, err - } - c := &Cache{ - lru: lru, - } - return c, nil -} - -// Purge is used to completely clear the cache. -func (c *Cache) Purge() { - c.lock.Lock() - c.lru.Purge() - c.lock.Unlock() -} - -// Add adds a value to the cache. Returns true if an eviction occurred. -func (c *Cache) Add(key, value interface{}) (evicted bool) { - c.lock.Lock() - evicted = c.lru.Add(key, value) - c.lock.Unlock() - return evicted -} - -// Get looks up a key's value from the cache. -func (c *Cache) Get(key interface{}) (value interface{}, ok bool) { - c.lock.Lock() - value, ok = c.lru.Get(key) - c.lock.Unlock() - return value, ok -} - -// Contains checks if a key is in the cache, without updating the -// recent-ness or deleting it for being stale. -func (c *Cache) Contains(key interface{}) bool { - c.lock.RLock() - containKey := c.lru.Contains(key) - c.lock.RUnlock() - return containKey -} - -// Peek returns the key value (or undefined if not found) without updating -// the "recently used"-ness of the key. -func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) { - c.lock.RLock() - value, ok = c.lru.Peek(key) - c.lock.RUnlock() - return value, ok -} - -// ContainsOrAdd checks if a key is in the cache without updating the -// recent-ness or deleting it for being stale, and if not, adds the value. -// Returns whether found and whether an eviction occurred. -func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) { - c.lock.Lock() - defer c.lock.Unlock() - - if c.lru.Contains(key) { - return true, false - } - evicted = c.lru.Add(key, value) - return false, evicted -} - -// PeekOrAdd checks if a key is in the cache without updating the -// recent-ness or deleting it for being stale, and if not, adds the value. -// Returns whether found and whether an eviction occurred. -func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) { - c.lock.Lock() - defer c.lock.Unlock() - - previous, ok = c.lru.Peek(key) - if ok { - return previous, true, false - } - - evicted = c.lru.Add(key, value) - return nil, false, evicted -} - -// Remove removes the provided key from the cache. -func (c *Cache) Remove(key interface{}) (present bool) { - c.lock.Lock() - present = c.lru.Remove(key) - c.lock.Unlock() - return -} - -// Resize changes the cache size. -func (c *Cache) Resize(size int) (evicted int) { - c.lock.Lock() - evicted = c.lru.Resize(size) - c.lock.Unlock() - return evicted -} - -// RemoveOldest removes the oldest item from the cache. -func (c *Cache) RemoveOldest() (key interface{}, value interface{}, ok bool) { - c.lock.Lock() - key, value, ok = c.lru.RemoveOldest() - c.lock.Unlock() - return -} - -// GetOldest returns the oldest entry -func (c *Cache) GetOldest() (key interface{}, value interface{}, ok bool) { - c.lock.Lock() - key, value, ok = c.lru.GetOldest() - c.lock.Unlock() - return -} - -// Keys returns a slice of the keys in the cache, from oldest to newest. -func (c *Cache) Keys() []interface{} { - c.lock.RLock() - keys := c.lru.Keys() - c.lock.RUnlock() - return keys -} - -// Len returns the number of items in the cache. -func (c *Cache) Len() int { - c.lock.RLock() - length := c.lru.Len() - c.lock.RUnlock() - return length -} diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go deleted file mode 100644 index a86c8539e0..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go +++ /dev/null @@ -1,177 +0,0 @@ -package simplelru - -import ( - "container/list" - "errors" -) - -// EvictCallback is used to get a callback when a cache entry is evicted -type EvictCallback func(key interface{}, value interface{}) - -// LRU implements a non-thread safe fixed size LRU cache -type LRU struct { - size int - evictList *list.List - items map[interface{}]*list.Element - onEvict EvictCallback -} - -// entry is used to hold a value in the evictList -type entry struct { - key interface{} - value interface{} -} - -// NewLRU constructs an LRU of the given size -func NewLRU(size int, onEvict EvictCallback) (*LRU, error) { - if size <= 0 { - return nil, errors.New("Must provide a positive size") - } - c := &LRU{ - size: size, - evictList: list.New(), - items: make(map[interface{}]*list.Element), - onEvict: onEvict, - } - return c, nil -} - -// Purge is used to completely clear the cache. -func (c *LRU) Purge() { - for k, v := range c.items { - if c.onEvict != nil { - c.onEvict(k, v.Value.(*entry).value) - } - delete(c.items, k) - } - c.evictList.Init() -} - -// Add adds a value to the cache. Returns true if an eviction occurred. -func (c *LRU) Add(key, value interface{}) (evicted bool) { - // Check for existing item - if ent, ok := c.items[key]; ok { - c.evictList.MoveToFront(ent) - ent.Value.(*entry).value = value - return false - } - - // Add new item - ent := &entry{key, value} - entry := c.evictList.PushFront(ent) - c.items[key] = entry - - evict := c.evictList.Len() > c.size - // Verify size not exceeded - if evict { - c.removeOldest() - } - return evict -} - -// Get looks up a key's value from the cache. -func (c *LRU) Get(key interface{}) (value interface{}, ok bool) { - if ent, ok := c.items[key]; ok { - c.evictList.MoveToFront(ent) - if ent.Value.(*entry) == nil { - return nil, false - } - return ent.Value.(*entry).value, true - } - return -} - -// Contains checks if a key is in the cache, without updating the recent-ness -// or deleting it for being stale. -func (c *LRU) Contains(key interface{}) (ok bool) { - _, ok = c.items[key] - return ok -} - -// Peek returns the key value (or undefined if not found) without updating -// the "recently used"-ness of the key. -func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) { - var ent *list.Element - if ent, ok = c.items[key]; ok { - return ent.Value.(*entry).value, true - } - return nil, ok -} - -// Remove removes the provided key from the cache, returning if the -// key was contained. -func (c *LRU) Remove(key interface{}) (present bool) { - if ent, ok := c.items[key]; ok { - c.removeElement(ent) - return true - } - return false -} - -// RemoveOldest removes the oldest item from the cache. -func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { - ent := c.evictList.Back() - if ent != nil { - c.removeElement(ent) - kv := ent.Value.(*entry) - return kv.key, kv.value, true - } - return nil, nil, false -} - -// GetOldest returns the oldest entry -func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) { - ent := c.evictList.Back() - if ent != nil { - kv := ent.Value.(*entry) - return kv.key, kv.value, true - } - return nil, nil, false -} - -// Keys returns a slice of the keys in the cache, from oldest to newest. -func (c *LRU) Keys() []interface{} { - keys := make([]interface{}, len(c.items)) - i := 0 - for ent := c.evictList.Back(); ent != nil; ent = ent.Prev() { - keys[i] = ent.Value.(*entry).key - i++ - } - return keys -} - -// Len returns the number of items in the cache. -func (c *LRU) Len() int { - return c.evictList.Len() -} - -// Resize changes the cache size. -func (c *LRU) Resize(size int) (evicted int) { - diff := c.Len() - size - if diff < 0 { - diff = 0 - } - for i := 0; i < diff; i++ { - c.removeOldest() - } - c.size = size - return diff -} - -// removeOldest removes the oldest item from the cache. -func (c *LRU) removeOldest() { - ent := c.evictList.Back() - if ent != nil { - c.removeElement(ent) - } -} - -// removeElement is used to remove a given list element from the cache -func (c *LRU) removeElement(e *list.Element) { - c.evictList.Remove(e) - kv := e.Value.(*entry) - delete(c.items, kv.key) - if c.onEvict != nil { - c.onEvict(kv.key, kv.value) - } -} diff --git a/vendor/github.com/hashicorp/golang-lru/.gitignore b/vendor/github.com/hashicorp/golang-lru/v2/.gitignore similarity index 100% rename from vendor/github.com/hashicorp/golang-lru/.gitignore rename to vendor/github.com/hashicorp/golang-lru/v2/.gitignore diff --git a/vendor/github.com/hashicorp/golang-lru/v2/.golangci.yml b/vendor/github.com/hashicorp/golang-lru/v2/.golangci.yml new file mode 100644 index 0000000000..7e7b8a9627 --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/v2/.golangci.yml @@ -0,0 +1,46 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +linters: + fast: false + disable-all: true + enable: + - revive + - megacheck + - govet + - unconvert + - gas + - gocyclo + - dupl + - misspell + - unparam + - unused + - typecheck + - ineffassign + # - stylecheck + - exportloopref + - gocritic + - nakedret + - gosimple + - prealloc + +# golangci-lint configuration file +linters-settings: + revive: + ignore-generated-header: true + severity: warning + rules: + - name: package-comments + severity: warning + disabled: true + - name: exported + severity: warning + disabled: false + arguments: ["checkPrivateReceivers", "disableStutteringCheck"] + +issues: + exclude-use-default: false + exclude-rules: + - path: _test\.go + linters: + - dupl diff --git a/vendor/github.com/hashicorp/golang-lru/2q.go b/vendor/github.com/hashicorp/golang-lru/v2/2q.go similarity index 64% rename from vendor/github.com/hashicorp/golang-lru/2q.go rename to vendor/github.com/hashicorp/golang-lru/v2/2q.go index e474cd0758..8c95252b6f 100644 --- a/vendor/github.com/hashicorp/golang-lru/2q.go +++ b/vendor/github.com/hashicorp/golang-lru/v2/2q.go @@ -1,10 +1,13 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package lru import ( - "fmt" + "errors" "sync" - "github.com/hashicorp/golang-lru/simplelru" + "github.com/hashicorp/golang-lru/v2/simplelru" ) const ( @@ -26,33 +29,35 @@ const ( // computationally about 2x the cost, and adds some metadata over // head. The ARCCache is similar, but does not require setting any // parameters. -type TwoQueueCache struct { - size int - recentSize int +type TwoQueueCache[K comparable, V any] struct { + size int + recentSize int + recentRatio float64 + ghostRatio float64 - recent simplelru.LRUCache - frequent simplelru.LRUCache - recentEvict simplelru.LRUCache + recent simplelru.LRUCache[K, V] + frequent simplelru.LRUCache[K, V] + recentEvict simplelru.LRUCache[K, struct{}] lock sync.RWMutex } // New2Q creates a new TwoQueueCache using the default // values for the parameters. -func New2Q(size int) (*TwoQueueCache, error) { - return New2QParams(size, Default2QRecentRatio, Default2QGhostEntries) +func New2Q[K comparable, V any](size int) (*TwoQueueCache[K, V], error) { + return New2QParams[K, V](size, Default2QRecentRatio, Default2QGhostEntries) } // New2QParams creates a new TwoQueueCache using the provided // parameter values. -func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCache, error) { +func New2QParams[K comparable, V any](size int, recentRatio, ghostRatio float64) (*TwoQueueCache[K, V], error) { if size <= 0 { - return nil, fmt.Errorf("invalid size") + return nil, errors.New("invalid size") } if recentRatio < 0.0 || recentRatio > 1.0 { - return nil, fmt.Errorf("invalid recent ratio") + return nil, errors.New("invalid recent ratio") } if ghostRatio < 0.0 || ghostRatio > 1.0 { - return nil, fmt.Errorf("invalid ghost ratio") + return nil, errors.New("invalid ghost ratio") } // Determine the sub-sizes @@ -60,23 +65,25 @@ func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCa evictSize := int(float64(size) * ghostRatio) // Allocate the LRUs - recent, err := simplelru.NewLRU(size, nil) + recent, err := simplelru.NewLRU[K, V](size, nil) if err != nil { return nil, err } - frequent, err := simplelru.NewLRU(size, nil) + frequent, err := simplelru.NewLRU[K, V](size, nil) if err != nil { return nil, err } - recentEvict, err := simplelru.NewLRU(evictSize, nil) + recentEvict, err := simplelru.NewLRU[K, struct{}](evictSize, nil) if err != nil { return nil, err } // Initialize the cache - c := &TwoQueueCache{ + c := &TwoQueueCache[K, V]{ size: size, recentSize: recentSize, + recentRatio: recentRatio, + ghostRatio: ghostRatio, recent: recent, frequent: frequent, recentEvict: recentEvict, @@ -85,7 +92,7 @@ func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCa } // Get looks up a key's value from the cache. -func (c *TwoQueueCache) Get(key interface{}) (value interface{}, ok bool) { +func (c *TwoQueueCache[K, V]) Get(key K) (value V, ok bool) { c.lock.Lock() defer c.lock.Unlock() @@ -103,11 +110,11 @@ func (c *TwoQueueCache) Get(key interface{}) (value interface{}, ok bool) { } // No hit - return nil, false + return } // Add adds a value to the cache. -func (c *TwoQueueCache) Add(key, value interface{}) { +func (c *TwoQueueCache[K, V]) Add(key K, value V) { c.lock.Lock() defer c.lock.Unlock() @@ -138,11 +145,10 @@ func (c *TwoQueueCache) Add(key, value interface{}) { // Add to the recently seen list c.ensureSpace(false) c.recent.Add(key, value) - return } // ensureSpace is used to ensure we have space in the cache -func (c *TwoQueueCache) ensureSpace(recentEvict bool) { +func (c *TwoQueueCache[K, V]) ensureSpace(recentEvict bool) { // If we have space, nothing to do recentLen := c.recent.Len() freqLen := c.frequent.Len() @@ -154,7 +160,7 @@ func (c *TwoQueueCache) ensureSpace(recentEvict bool) { // the target, evict from there if recentLen > 0 && (recentLen > c.recentSize || (recentLen == c.recentSize && !recentEvict)) { k, _, _ := c.recent.RemoveOldest() - c.recentEvict.Add(k, nil) + c.recentEvict.Add(k, struct{}{}) return } @@ -163,15 +169,43 @@ func (c *TwoQueueCache) ensureSpace(recentEvict bool) { } // Len returns the number of items in the cache. -func (c *TwoQueueCache) Len() int { +func (c *TwoQueueCache[K, V]) Len() int { c.lock.RLock() defer c.lock.RUnlock() return c.recent.Len() + c.frequent.Len() } +// Resize changes the cache size. +func (c *TwoQueueCache[K, V]) Resize(size int) (evicted int) { + c.lock.Lock() + defer c.lock.Unlock() + + // Recalculate the sub-sizes + recentSize := int(float64(size) * c.recentRatio) + evictSize := int(float64(size) * c.ghostRatio) + c.size = size + c.recentSize = recentSize + + // ensureSpace + diff := c.recent.Len() + c.frequent.Len() - size + if diff < 0 { + diff = 0 + } + for i := 0; i < diff; i++ { + c.ensureSpace(true) + } + + // Reallocate the LRUs + c.recent.Resize(size) + c.frequent.Resize(size) + c.recentEvict.Resize(evictSize) + + return diff +} + // Keys returns a slice of the keys in the cache. // The frequently used keys are first in the returned slice. -func (c *TwoQueueCache) Keys() []interface{} { +func (c *TwoQueueCache[K, V]) Keys() []K { c.lock.RLock() defer c.lock.RUnlock() k1 := c.frequent.Keys() @@ -179,8 +213,18 @@ func (c *TwoQueueCache) Keys() []interface{} { return append(k1, k2...) } +// Values returns a slice of the values in the cache. +// The frequently used values are first in the returned slice. +func (c *TwoQueueCache[K, V]) Values() []V { + c.lock.RLock() + defer c.lock.RUnlock() + v1 := c.frequent.Values() + v2 := c.recent.Values() + return append(v1, v2...) +} + // Remove removes the provided key from the cache. -func (c *TwoQueueCache) Remove(key interface{}) { +func (c *TwoQueueCache[K, V]) Remove(key K) { c.lock.Lock() defer c.lock.Unlock() if c.frequent.Remove(key) { @@ -195,7 +239,7 @@ func (c *TwoQueueCache) Remove(key interface{}) { } // Purge is used to completely clear the cache. -func (c *TwoQueueCache) Purge() { +func (c *TwoQueueCache[K, V]) Purge() { c.lock.Lock() defer c.lock.Unlock() c.recent.Purge() @@ -205,7 +249,7 @@ func (c *TwoQueueCache) Purge() { // Contains is used to check if the cache contains a key // without updating recency or frequency. -func (c *TwoQueueCache) Contains(key interface{}) bool { +func (c *TwoQueueCache[K, V]) Contains(key K) bool { c.lock.RLock() defer c.lock.RUnlock() return c.frequent.Contains(key) || c.recent.Contains(key) @@ -213,7 +257,7 @@ func (c *TwoQueueCache) Contains(key interface{}) bool { // Peek is used to inspect the cache value of a key // without updating recency or frequency. -func (c *TwoQueueCache) Peek(key interface{}) (value interface{}, ok bool) { +func (c *TwoQueueCache[K, V]) Peek(key K) (value V, ok bool) { c.lock.RLock() defer c.lock.RUnlock() if val, ok := c.frequent.Peek(key); ok { diff --git a/vendor/github.com/hashicorp/golang-lru/LICENSE b/vendor/github.com/hashicorp/golang-lru/v2/LICENSE similarity index 99% rename from vendor/github.com/hashicorp/golang-lru/LICENSE rename to vendor/github.com/hashicorp/golang-lru/v2/LICENSE index be2cc4dfb6..0e5d580e0e 100644 --- a/vendor/github.com/hashicorp/golang-lru/LICENSE +++ b/vendor/github.com/hashicorp/golang-lru/v2/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2014 HashiCorp, Inc. + Mozilla Public License, version 2.0 1. Definitions diff --git a/vendor/github.com/hashicorp/golang-lru/v2/README.md b/vendor/github.com/hashicorp/golang-lru/v2/README.md new file mode 100644 index 0000000000..a942eb5397 --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/v2/README.md @@ -0,0 +1,79 @@ +golang-lru +========== + +This provides the `lru` package which implements a fixed-size +thread safe LRU cache. It is based on the cache in Groupcache. + +Documentation +============= + +Full docs are available on [Go Packages](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2) + +LRU cache example +================= + +```go +package main + +import ( + "fmt" + "github.com/hashicorp/golang-lru/v2" +) + +func main() { + l, _ := lru.New[int, any](128) + for i := 0; i < 256; i++ { + l.Add(i, nil) + } + if l.Len() != 128 { + panic(fmt.Sprintf("bad len: %v", l.Len())) + } +} +``` + +Expirable LRU cache example +=========================== + +```go +package main + +import ( + "fmt" + "time" + + "github.com/hashicorp/golang-lru/v2/expirable" +) + +func main() { + // make cache with 10ms TTL and 5 max keys + cache := expirable.NewLRU[string, string](5, nil, time.Millisecond*10) + + + // set value under key1. + cache.Add("key1", "val1") + + // get value under key1 + r, ok := cache.Get("key1") + + // check for OK value + if ok { + fmt.Printf("value before expiration is found: %v, value: %q\n", ok, r) + } + + // wait for cache to expire + time.Sleep(time.Millisecond * 12) + + // get value under key1 after key expiration + r, ok = cache.Get("key1") + fmt.Printf("value after expiration is found: %v, value: %q\n", ok, r) + + // set value under key2, would evict old entry because it is already expired. + cache.Add("key2", "val2") + + fmt.Printf("Cache len: %d\n", cache.Len()) + // Output: + // value before expiration is found: true, value: "val1" + // value after expiration is found: false, value: "" + // Cache len: 1 +} +``` diff --git a/vendor/github.com/hashicorp/golang-lru/v2/doc.go b/vendor/github.com/hashicorp/golang-lru/v2/doc.go new file mode 100644 index 0000000000..24107ee0ed --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/v2/doc.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package lru provides three different LRU caches of varying sophistication. +// +// Cache is a simple LRU cache. It is based on the LRU implementation in +// groupcache: https://github.com/golang/groupcache/tree/master/lru +// +// TwoQueueCache tracks frequently used and recently used entries separately. +// This avoids a burst of accesses from taking out frequently used entries, at +// the cost of about 2x computational overhead and some extra bookkeeping. +// +// ARCCache is an adaptive replacement cache. It tracks recent evictions as well +// as recent usage in both the frequent and recent caches. Its computational +// overhead is comparable to TwoQueueCache, but the memory overhead is linear +// with the size of the cache. +// +// ARC has been patented by IBM, so do not use it if that is problematic for +// your program. For this reason, it is in a separate go module contained within +// this repository. +// +// All caches in this package take locks while operating, and are therefore +// thread-safe for consumers. +package lru diff --git a/vendor/github.com/hashicorp/golang-lru/v2/internal/list.go b/vendor/github.com/hashicorp/golang-lru/v2/internal/list.go new file mode 100644 index 0000000000..5cd74a0343 --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/v2/internal/list.go @@ -0,0 +1,142 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE_list file. + +package internal + +import "time" + +// Entry is an LRU Entry +type Entry[K comparable, V any] struct { + // Next and previous pointers in the doubly-linked list of elements. + // To simplify the implementation, internally a list l is implemented + // as a ring, such that &l.root is both the next element of the last + // list element (l.Back()) and the previous element of the first list + // element (l.Front()). + next, prev *Entry[K, V] + + // The list to which this element belongs. + list *LruList[K, V] + + // The LRU Key of this element. + Key K + + // The Value stored with this element. + Value V + + // The time this element would be cleaned up, optional + ExpiresAt time.Time + + // The expiry bucket item was put in, optional + ExpireBucket uint8 +} + +// PrevEntry returns the previous list element or nil. +func (e *Entry[K, V]) PrevEntry() *Entry[K, V] { + if p := e.prev; e.list != nil && p != &e.list.root { + return p + } + return nil +} + +// LruList represents a doubly linked list. +// The zero Value for LruList is an empty list ready to use. +type LruList[K comparable, V any] struct { + root Entry[K, V] // sentinel list element, only &root, root.prev, and root.next are used + len int // current list Length excluding (this) sentinel element +} + +// Init initializes or clears list l. +func (l *LruList[K, V]) Init() *LruList[K, V] { + l.root.next = &l.root + l.root.prev = &l.root + l.len = 0 + return l +} + +// NewList returns an initialized list. +func NewList[K comparable, V any]() *LruList[K, V] { return new(LruList[K, V]).Init() } + +// Length returns the number of elements of list l. +// The complexity is O(1). +func (l *LruList[K, V]) Length() int { return l.len } + +// Back returns the last element of list l or nil if the list is empty. +func (l *LruList[K, V]) Back() *Entry[K, V] { + if l.len == 0 { + return nil + } + return l.root.prev +} + +// lazyInit lazily initializes a zero List Value. +func (l *LruList[K, V]) lazyInit() { + if l.root.next == nil { + l.Init() + } +} + +// insert inserts e after at, increments l.len, and returns e. +func (l *LruList[K, V]) insert(e, at *Entry[K, V]) *Entry[K, V] { + e.prev = at + e.next = at.next + e.prev.next = e + e.next.prev = e + e.list = l + l.len++ + return e +} + +// insertValue is a convenience wrapper for insert(&Entry{Value: v, ExpiresAt: ExpiresAt}, at). +func (l *LruList[K, V]) insertValue(k K, v V, expiresAt time.Time, at *Entry[K, V]) *Entry[K, V] { + return l.insert(&Entry[K, V]{Value: v, Key: k, ExpiresAt: expiresAt}, at) +} + +// Remove removes e from its list, decrements l.len +func (l *LruList[K, V]) Remove(e *Entry[K, V]) V { + e.prev.next = e.next + e.next.prev = e.prev + e.next = nil // avoid memory leaks + e.prev = nil // avoid memory leaks + e.list = nil + l.len-- + + return e.Value +} + +// move moves e to next to at. +func (l *LruList[K, V]) move(e, at *Entry[K, V]) { + if e == at { + return + } + e.prev.next = e.next + e.next.prev = e.prev + + e.prev = at + e.next = at.next + e.prev.next = e + e.next.prev = e +} + +// PushFront inserts a new element e with value v at the front of list l and returns e. +func (l *LruList[K, V]) PushFront(k K, v V) *Entry[K, V] { + l.lazyInit() + return l.insertValue(k, v, time.Time{}, &l.root) +} + +// PushFrontExpirable inserts a new expirable element e with Value v at the front of list l and returns e. +func (l *LruList[K, V]) PushFrontExpirable(k K, v V, expiresAt time.Time) *Entry[K, V] { + l.lazyInit() + return l.insertValue(k, v, expiresAt, &l.root) +} + +// MoveToFront moves element e to the front of list l. +// If e is not an element of l, the list is not modified. +// The element must not be nil. +func (l *LruList[K, V]) MoveToFront(e *Entry[K, V]) { + if e.list != l || l.root.next == e { + return + } + // see comment in List.Remove about initialization of l + l.move(e, &l.root) +} diff --git a/vendor/github.com/hashicorp/golang-lru/v2/lru.go b/vendor/github.com/hashicorp/golang-lru/v2/lru.go new file mode 100644 index 0000000000..a2655f1f31 --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/v2/lru.go @@ -0,0 +1,250 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package lru + +import ( + "sync" + + "github.com/hashicorp/golang-lru/v2/simplelru" +) + +const ( + // DefaultEvictedBufferSize defines the default buffer size to store evicted key/val + DefaultEvictedBufferSize = 16 +) + +// Cache is a thread-safe fixed size LRU cache. +type Cache[K comparable, V any] struct { + lru *simplelru.LRU[K, V] + evictedKeys []K + evictedVals []V + onEvictedCB func(k K, v V) + lock sync.RWMutex +} + +// New creates an LRU of the given size. +func New[K comparable, V any](size int) (*Cache[K, V], error) { + return NewWithEvict[K, V](size, nil) +} + +// NewWithEvict constructs a fixed size cache with the given eviction +// callback. +func NewWithEvict[K comparable, V any](size int, onEvicted func(key K, value V)) (c *Cache[K, V], err error) { + // create a cache with default settings + c = &Cache[K, V]{ + onEvictedCB: onEvicted, + } + if onEvicted != nil { + c.initEvictBuffers() + onEvicted = c.onEvicted + } + c.lru, err = simplelru.NewLRU(size, onEvicted) + return +} + +func (c *Cache[K, V]) initEvictBuffers() { + c.evictedKeys = make([]K, 0, DefaultEvictedBufferSize) + c.evictedVals = make([]V, 0, DefaultEvictedBufferSize) +} + +// onEvicted save evicted key/val and sent in externally registered callback +// outside of critical section +func (c *Cache[K, V]) onEvicted(k K, v V) { + c.evictedKeys = append(c.evictedKeys, k) + c.evictedVals = append(c.evictedVals, v) +} + +// Purge is used to completely clear the cache. +func (c *Cache[K, V]) Purge() { + var ks []K + var vs []V + c.lock.Lock() + c.lru.Purge() + if c.onEvictedCB != nil && len(c.evictedKeys) > 0 { + ks, vs = c.evictedKeys, c.evictedVals + c.initEvictBuffers() + } + c.lock.Unlock() + // invoke callback outside of critical section + if c.onEvictedCB != nil { + for i := 0; i < len(ks); i++ { + c.onEvictedCB(ks[i], vs[i]) + } + } +} + +// Add adds a value to the cache. Returns true if an eviction occurred. +func (c *Cache[K, V]) Add(key K, value V) (evicted bool) { + var k K + var v V + c.lock.Lock() + evicted = c.lru.Add(key, value) + if c.onEvictedCB != nil && evicted { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } + c.lock.Unlock() + if c.onEvictedCB != nil && evicted { + c.onEvictedCB(k, v) + } + return +} + +// Get looks up a key's value from the cache. +func (c *Cache[K, V]) Get(key K) (value V, ok bool) { + c.lock.Lock() + value, ok = c.lru.Get(key) + c.lock.Unlock() + return value, ok +} + +// Contains checks if a key is in the cache, without updating the +// recent-ness or deleting it for being stale. +func (c *Cache[K, V]) Contains(key K) bool { + c.lock.RLock() + containKey := c.lru.Contains(key) + c.lock.RUnlock() + return containKey +} + +// Peek returns the key value (or undefined if not found) without updating +// the "recently used"-ness of the key. +func (c *Cache[K, V]) Peek(key K) (value V, ok bool) { + c.lock.RLock() + value, ok = c.lru.Peek(key) + c.lock.RUnlock() + return value, ok +} + +// ContainsOrAdd checks if a key is in the cache without updating the +// recent-ness or deleting it for being stale, and if not, adds the value. +// Returns whether found and whether an eviction occurred. +func (c *Cache[K, V]) ContainsOrAdd(key K, value V) (ok, evicted bool) { + var k K + var v V + c.lock.Lock() + if c.lru.Contains(key) { + c.lock.Unlock() + return true, false + } + evicted = c.lru.Add(key, value) + if c.onEvictedCB != nil && evicted { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } + c.lock.Unlock() + if c.onEvictedCB != nil && evicted { + c.onEvictedCB(k, v) + } + return false, evicted +} + +// PeekOrAdd checks if a key is in the cache without updating the +// recent-ness or deleting it for being stale, and if not, adds the value. +// Returns whether found and whether an eviction occurred. +func (c *Cache[K, V]) PeekOrAdd(key K, value V) (previous V, ok, evicted bool) { + var k K + var v V + c.lock.Lock() + previous, ok = c.lru.Peek(key) + if ok { + c.lock.Unlock() + return previous, true, false + } + evicted = c.lru.Add(key, value) + if c.onEvictedCB != nil && evicted { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } + c.lock.Unlock() + if c.onEvictedCB != nil && evicted { + c.onEvictedCB(k, v) + } + return +} + +// Remove removes the provided key from the cache. +func (c *Cache[K, V]) Remove(key K) (present bool) { + var k K + var v V + c.lock.Lock() + present = c.lru.Remove(key) + if c.onEvictedCB != nil && present { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } + c.lock.Unlock() + if c.onEvictedCB != nil && present { + c.onEvictedCB(k, v) + } + return +} + +// Resize changes the cache size. +func (c *Cache[K, V]) Resize(size int) (evicted int) { + var ks []K + var vs []V + c.lock.Lock() + evicted = c.lru.Resize(size) + if c.onEvictedCB != nil && evicted > 0 { + ks, vs = c.evictedKeys, c.evictedVals + c.initEvictBuffers() + } + c.lock.Unlock() + if c.onEvictedCB != nil && evicted > 0 { + for i := 0; i < len(ks); i++ { + c.onEvictedCB(ks[i], vs[i]) + } + } + return evicted +} + +// RemoveOldest removes the oldest item from the cache. +func (c *Cache[K, V]) RemoveOldest() (key K, value V, ok bool) { + var k K + var v V + c.lock.Lock() + key, value, ok = c.lru.RemoveOldest() + if c.onEvictedCB != nil && ok { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } + c.lock.Unlock() + if c.onEvictedCB != nil && ok { + c.onEvictedCB(k, v) + } + return +} + +// GetOldest returns the oldest entry +func (c *Cache[K, V]) GetOldest() (key K, value V, ok bool) { + c.lock.RLock() + key, value, ok = c.lru.GetOldest() + c.lock.RUnlock() + return +} + +// Keys returns a slice of the keys in the cache, from oldest to newest. +func (c *Cache[K, V]) Keys() []K { + c.lock.RLock() + keys := c.lru.Keys() + c.lock.RUnlock() + return keys +} + +// Values returns a slice of the values in the cache, from oldest to newest. +func (c *Cache[K, V]) Values() []V { + c.lock.RLock() + values := c.lru.Values() + c.lock.RUnlock() + return values +} + +// Len returns the number of items in the cache. +func (c *Cache[K, V]) Len() int { + c.lock.RLock() + length := c.lru.Len() + c.lock.RUnlock() + return length +} diff --git a/vendor/github.com/hashicorp/golang-lru/v2/simplelru/LICENSE_list b/vendor/github.com/hashicorp/golang-lru/v2/simplelru/LICENSE_list new file mode 100644 index 0000000000..c4764e6b2f --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/v2/simplelru/LICENSE_list @@ -0,0 +1,29 @@ +This license applies to simplelru/list.go + +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru.go new file mode 100644 index 0000000000..f69792388c --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru.go @@ -0,0 +1,177 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package simplelru + +import ( + "errors" + + "github.com/hashicorp/golang-lru/v2/internal" +) + +// EvictCallback is used to get a callback when a cache entry is evicted +type EvictCallback[K comparable, V any] func(key K, value V) + +// LRU implements a non-thread safe fixed size LRU cache +type LRU[K comparable, V any] struct { + size int + evictList *internal.LruList[K, V] + items map[K]*internal.Entry[K, V] + onEvict EvictCallback[K, V] +} + +// NewLRU constructs an LRU of the given size +func NewLRU[K comparable, V any](size int, onEvict EvictCallback[K, V]) (*LRU[K, V], error) { + if size <= 0 { + return nil, errors.New("must provide a positive size") + } + + c := &LRU[K, V]{ + size: size, + evictList: internal.NewList[K, V](), + items: make(map[K]*internal.Entry[K, V]), + onEvict: onEvict, + } + return c, nil +} + +// Purge is used to completely clear the cache. +func (c *LRU[K, V]) Purge() { + for k, v := range c.items { + if c.onEvict != nil { + c.onEvict(k, v.Value) + } + delete(c.items, k) + } + c.evictList.Init() +} + +// Add adds a value to the cache. Returns true if an eviction occurred. +func (c *LRU[K, V]) Add(key K, value V) (evicted bool) { + // Check for existing item + if ent, ok := c.items[key]; ok { + c.evictList.MoveToFront(ent) + ent.Value = value + return false + } + + // Add new item + ent := c.evictList.PushFront(key, value) + c.items[key] = ent + + evict := c.evictList.Length() > c.size + // Verify size not exceeded + if evict { + c.removeOldest() + } + return evict +} + +// Get looks up a key's value from the cache. +func (c *LRU[K, V]) Get(key K) (value V, ok bool) { + if ent, ok := c.items[key]; ok { + c.evictList.MoveToFront(ent) + return ent.Value, true + } + return +} + +// Contains checks if a key is in the cache, without updating the recent-ness +// or deleting it for being stale. +func (c *LRU[K, V]) Contains(key K) (ok bool) { + _, ok = c.items[key] + return ok +} + +// Peek returns the key value (or undefined if not found) without updating +// the "recently used"-ness of the key. +func (c *LRU[K, V]) Peek(key K) (value V, ok bool) { + var ent *internal.Entry[K, V] + if ent, ok = c.items[key]; ok { + return ent.Value, true + } + return +} + +// Remove removes the provided key from the cache, returning if the +// key was contained. +func (c *LRU[K, V]) Remove(key K) (present bool) { + if ent, ok := c.items[key]; ok { + c.removeElement(ent) + return true + } + return false +} + +// RemoveOldest removes the oldest item from the cache. +func (c *LRU[K, V]) RemoveOldest() (key K, value V, ok bool) { + if ent := c.evictList.Back(); ent != nil { + c.removeElement(ent) + return ent.Key, ent.Value, true + } + return +} + +// GetOldest returns the oldest entry +func (c *LRU[K, V]) GetOldest() (key K, value V, ok bool) { + if ent := c.evictList.Back(); ent != nil { + return ent.Key, ent.Value, true + } + return +} + +// Keys returns a slice of the keys in the cache, from oldest to newest. +func (c *LRU[K, V]) Keys() []K { + keys := make([]K, c.evictList.Length()) + i := 0 + for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() { + keys[i] = ent.Key + i++ + } + return keys +} + +// Values returns a slice of the values in the cache, from oldest to newest. +func (c *LRU[K, V]) Values() []V { + values := make([]V, len(c.items)) + i := 0 + for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() { + values[i] = ent.Value + i++ + } + return values +} + +// Len returns the number of items in the cache. +func (c *LRU[K, V]) Len() int { + return c.evictList.Length() +} + +// Resize changes the cache size. +func (c *LRU[K, V]) Resize(size int) (evicted int) { + diff := c.Len() - size + if diff < 0 { + diff = 0 + } + for i := 0; i < diff; i++ { + c.removeOldest() + } + c.size = size + return diff +} + +// removeOldest removes the oldest item from the cache. +func (c *LRU[K, V]) removeOldest() { + if ent := c.evictList.Back(); ent != nil { + c.removeElement(ent) + } +} + +// removeElement is used to remove a given list element from the cache +func (c *LRU[K, V]) removeElement(e *internal.Entry[K, V]) { + c.evictList.Remove(e) + delete(c.items, e.Key) + if c.onEvict != nil { + c.onEvict(e.Key, e.Value) + } +} diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru_interface.go similarity index 57% rename from vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go rename to vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru_interface.go index 92d70934d6..043b8bcc3f 100644 --- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go +++ b/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru_interface.go @@ -1,32 +1,39 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package simplelru provides simple LRU implementation based on build-in container/list. package simplelru // LRUCache is the interface for simple LRU cache. -type LRUCache interface { +type LRUCache[K comparable, V any] interface { // Adds a value to the cache, returns true if an eviction occurred and // updates the "recently used"-ness of the key. - Add(key, value interface{}) bool + Add(key K, value V) bool // Returns key's value from the cache and // updates the "recently used"-ness of the key. #value, isFound - Get(key interface{}) (value interface{}, ok bool) + Get(key K) (value V, ok bool) // Checks if a key exists in cache without updating the recent-ness. - Contains(key interface{}) (ok bool) + Contains(key K) (ok bool) // Returns key's value without updating the "recently used"-ness of the key. - Peek(key interface{}) (value interface{}, ok bool) + Peek(key K) (value V, ok bool) // Removes a key from the cache. - Remove(key interface{}) bool + Remove(key K) bool // Removes the oldest entry from cache. - RemoveOldest() (interface{}, interface{}, bool) + RemoveOldest() (K, V, bool) // Returns the oldest entry from the cache. #key, value, isFound - GetOldest() (interface{}, interface{}, bool) + GetOldest() (K, V, bool) // Returns a slice of the keys in the cache, from oldest to newest. - Keys() []interface{} + Keys() []K + + // Values returns a slice of the values in the cache, from oldest to newest. + Values() []V // Returns the number of items in the cache. Len() int @@ -34,6 +41,6 @@ type LRUCache interface { // Clears all cache entries. Purge() - // Resizes cache, returning number evicted - Resize(int) int + // Resizes cache, returning number evicted + Resize(int) int } diff --git a/vendor/github.com/imacks/bitflags-go/README.md b/vendor/github.com/imacks/bitflags-go/README.md deleted file mode 100644 index 2554cb09ad..0000000000 --- a/vendor/github.com/imacks/bitflags-go/README.md +++ /dev/null @@ -1,39 +0,0 @@ -bitflags-go -=========== -This package is a simple wrapper for working with [bit field](https://en.wikipedia.org/wiki/Bit_field) in Go. - -Go 1.18+ required, because generics. - -Example code: - -```go -package main - -import ( - "fmt" - "github.com/imacks/bitflags-go" -) - -// enum type has to be integer type, such as byte, int, etc. Can be unsigned. -type fruits int - -const ( - apple fruits = 1<= hoursPerYear { + duration.Years = math.Floor(d.Hours() / hoursPerYear) + d -= time.Duration(duration.Years) * nsPerYear + } + if d.Hours() >= hoursPerMonth { + duration.Months = math.Floor(d.Hours() / hoursPerMonth) + d -= time.Duration(duration.Months) * nsPerMonth + } + if d.Hours() >= hoursPerWeek { + duration.Weeks = math.Floor(d.Hours() / hoursPerWeek) + d -= time.Duration(duration.Weeks) * nsPerWeek + } + if d.Hours() >= hoursPerDay { + duration.Days = math.Floor(d.Hours() / hoursPerDay) + d -= time.Duration(duration.Days) * nsPerDay + } + if d.Hours() >= 1 { + duration.Hours = math.Floor(d.Hours()) + d -= time.Duration(duration.Hours) * nsPerHour + } + if d.Minutes() >= 1 { + duration.Minutes = math.Floor(d.Minutes()) + d -= time.Duration(duration.Minutes) * nsPerMinute + } + duration.Seconds = d.Seconds() + + return duration +} + +// Format formats the given time.Duration into an ISO 8601 duration string (e.g., P1DT6H5M), +// negative durations are prefixed with a minus sign, for a zero duration "PT0S" is returned. +// Note that for *Duration's with period values of a month or year that the duration becomes a bit fuzzy +// since obviously those things vary month to month and year to year. +func Format(d time.Duration) string { + return FromTimeDuration(d).String() +} + +// ToTimeDuration converts the *Duration to the standard library's time.Duration. +// Note that for *Duration's with period values of a month or year that the duration becomes a bit fuzzy +// since obviously those things vary month to month and year to year. +func (duration *Duration) ToTimeDuration() time.Duration { + var timeDuration time.Duration + + // zero checks are here to avoid unnecessary math operations, on a duration such as `PT5M` + if duration.Years != 0 { + timeDuration += time.Duration(math.Round(duration.Years * nsPerYear)) + } + if duration.Months != 0 { + timeDuration += time.Duration(math.Round(duration.Months * nsPerMonth)) + } + if duration.Weeks != 0 { + timeDuration += time.Duration(math.Round(duration.Weeks * nsPerWeek)) + } + if duration.Days != 0 { + timeDuration += time.Duration(math.Round(duration.Days * nsPerDay)) + } + if duration.Hours != 0 { + timeDuration += time.Duration(math.Round(duration.Hours * nsPerHour)) + } + if duration.Minutes != 0 { + timeDuration += time.Duration(math.Round(duration.Minutes * nsPerMinute)) + } + if duration.Seconds != 0 { + timeDuration += time.Duration(math.Round(duration.Seconds * nsPerSecond)) + } + if duration.Negative { + timeDuration = -timeDuration + } + + return timeDuration +} + +// String returns the ISO8601 duration string for the *Duration +func (duration *Duration) String() string { + d := "P" + hasTime := false + + appendD := func(designator string, value float64, isTime bool) { + if !hasTime && isTime { + d += "T" + hasTime = true + } + + d += strconv.FormatFloat(value, 'f', -1, 64) + designator + } + + if duration.Years != 0 { + appendD("Y", duration.Years, false) + } + + if duration.Months != 0 { + appendD("M", duration.Months, false) + } + + if duration.Weeks != 0 { + appendD("W", duration.Weeks, false) + } + + if duration.Days != 0 { + appendD("D", duration.Days, false) + } + + if duration.Hours != 0 { + appendD("H", duration.Hours, true) + } + + if duration.Minutes != 0 { + appendD("M", duration.Minutes, true) + } + + if duration.Seconds != 0 { + appendD("S", duration.Seconds, true) + } + + // if the duration is zero, return "PT0S" + if d == "P" { + d += "T0S" + } + + if duration.Negative { + return "-" + d + } + + return d +} + +// MarshalJSON satisfies the Marshaler interface by return a valid JSON string representation of the duration +func (duration Duration) MarshalJSON() ([]byte, error) { + return json.Marshal(duration.String()) +} + +// UnmarshalJSON satisfies the Unmarshaler interface by return a valid JSON string representation of the duration +func (duration *Duration) UnmarshalJSON(source []byte) error { + durationString := "" + err := json.Unmarshal(source, &durationString) + if err != nil { + return err + } + + parsed, err := Parse(durationString) + if err != nil { + return fmt.Errorf("failed to parse duration: %w", err) + } + + *duration = *parsed + return nil +} diff --git a/vendor/github.com/sosodev/duration/readme.md b/vendor/github.com/sosodev/duration/readme.md new file mode 100644 index 0000000000..a1d9f37d10 --- /dev/null +++ b/vendor/github.com/sosodev/duration/readme.md @@ -0,0 +1,54 @@ +# duration + +[![Go Reference](https://pkg.go.dev/badge/github.com/sosodev/duration.svg)](https://pkg.go.dev/github.com/sosodev/duration) + +It's a Go module for parsing [ISO 8601 durations](https://en.wikipedia.org/wiki/ISO_8601#Durations) and converting them to the often much more useful `time.Duration`. + +## why? + +ISO 8601 is a pretty common standard and sometimes these durations show up in the wild. + +## installation + +`go get github.com/sosodev/duration` + +## [usage](https://go.dev/play/p/Nz5akjy1c6W) + +```go +package main + +import ( + "fmt" + "time" + "github.com/sosodev/duration" +) + +func main() { + d, err := duration.Parse("P3Y6M4DT12H30M5.5S") + if err != nil { + panic(err) + } + + fmt.Println(d.Years) // 3 + fmt.Println(d.Months) // 6 + fmt.Println(d.Days) // 4 + fmt.Println(d.Hours) // 12 + fmt.Println(d.Minutes) // 30 + fmt.Println(d.Seconds) // 5.5 + + d, err = duration.Parse("PT33.3S") + if err != nil { + panic(err) + } + + fmt.Println(d.ToTimeDuration() == time.Second*33+time.Millisecond*300) // true +} +``` + +## correctness + +This module aims to implement the ISO 8601 duration specification correctly. It properly supports fractional units and has unit tests +that assert the correctness of it's parsing and conversion to a `time.Duration`. + +With that said durations with months or years specified will be converted to `time.Duration` with a little fuzziness. Since I +couldn't find a standard value, and they obviously vary, for those I used `2.628e+15` nanoseconds for a month and `3.154e+16` nanoseconds for a year. diff --git a/vendor/github.com/vektah/gqlparser/v2/.go-version b/vendor/github.com/vektah/gqlparser/v2/.go-version new file mode 100644 index 0000000000..66e2ae6c25 --- /dev/null +++ b/vendor/github.com/vektah/gqlparser/v2/.go-version @@ -0,0 +1 @@ +1.19.1 diff --git a/vendor/github.com/vektah/gqlparser/v2/.golangci.yaml b/vendor/github.com/vektah/gqlparser/v2/.golangci.yaml new file mode 100644 index 0000000000..97a514b970 --- /dev/null +++ b/vendor/github.com/vektah/gqlparser/v2/.golangci.yaml @@ -0,0 +1,54 @@ +run: + tests: true + +linters-settings: + errcheck: + exclude-functions: + - (io.Writer).Write + - io.Copy + - io.WriteString + revive: + enable-all-rules: false + rules: + - name: empty-lines + testifylint: + disable-all: true + enable: + - bool-compare + - compares + - error-is-as + - error-nil + - expected-actual + - nil-compare + +linters: + disable-all: true + enable: + - bodyclose + - dupl + - errcheck + - gocritic + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - prealloc + - revive + - staticcheck + - testifylint + - typecheck + - unconvert + - unused + +issues: + exclude-dirs: + - bin + exclude-rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - dupl + - errcheck diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/comment.go b/vendor/github.com/vektah/gqlparser/v2/ast/comment.go new file mode 100644 index 0000000000..8fcfda5813 --- /dev/null +++ b/vendor/github.com/vektah/gqlparser/v2/ast/comment.go @@ -0,0 +1,31 @@ +package ast + +import ( + "strconv" + "strings" +) + +type Comment struct { + Value string + Position *Position +} + +func (c *Comment) Text() string { + return strings.TrimPrefix(c.Value, "#") +} + +type CommentGroup struct { + List []*Comment +} + +func (c *CommentGroup) Dump() string { + if len(c.List) == 0 { + return "" + } + var builder strings.Builder + for _, comment := range c.List { + builder.WriteString(comment.Value) + builder.WriteString("\n") + } + return strconv.Quote(builder.String()) +} diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/decode.go b/vendor/github.com/vektah/gqlparser/v2/ast/decode.go index d00920554c..c9966b2440 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/decode.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/decode.go @@ -11,7 +11,7 @@ func UnmarshalSelectionSet(b []byte) (SelectionSet, error) { return nil, err } - var result = make([]Selection, 0) + result := make([]Selection, 0) for _, item := range tmp { var field Field if err := json.Unmarshal(item, &field); err == nil { diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/definition.go b/vendor/github.com/vektah/gqlparser/v2/ast/definition.go index d203908168..3f0aa53d14 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/definition.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/definition.go @@ -31,6 +31,10 @@ type Definition struct { Position *Position `dump:"-"` BuiltIn bool `dump:"-"` + + BeforeDescriptionComment *CommentGroup + AfterDescriptionComment *CommentGroup + EndOfDefinitionComment *CommentGroup } func (d *Definition) IsLeafType() bool { @@ -66,6 +70,9 @@ type FieldDefinition struct { Type *Type Directives DirectiveList Position *Position `dump:"-"` + + BeforeDescriptionComment *CommentGroup + AfterDescriptionComment *CommentGroup } type ArgumentDefinition struct { @@ -75,6 +82,9 @@ type ArgumentDefinition struct { Type *Type Directives DirectiveList Position *Position `dump:"-"` + + BeforeDescriptionComment *CommentGroup + AfterDescriptionComment *CommentGroup } type EnumValueDefinition struct { @@ -82,6 +92,9 @@ type EnumValueDefinition struct { Name string Directives DirectiveList Position *Position `dump:"-"` + + BeforeDescriptionComment *CommentGroup + AfterDescriptionComment *CommentGroup } type DirectiveDefinition struct { @@ -91,4 +104,7 @@ type DirectiveDefinition struct { Locations []DirectiveLocation IsRepeatable bool Position *Position `dump:"-"` + + BeforeDescriptionComment *CommentGroup + AfterDescriptionComment *CommentGroup } diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/document.go b/vendor/github.com/vektah/gqlparser/v2/ast/document.go index 43bfb54ff5..a3a9e98dc2 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/document.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/document.go @@ -4,6 +4,7 @@ type QueryDocument struct { Operations OperationList Fragments FragmentDefinitionList Position *Position `dump:"-"` + Comment *CommentGroup } type SchemaDocument struct { @@ -13,6 +14,7 @@ type SchemaDocument struct { Definitions DefinitionList Extensions DefinitionList Position *Position `dump:"-"` + Comment *CommentGroup } func (d *SchemaDocument) Merge(other *SchemaDocument) { @@ -35,6 +37,8 @@ type Schema struct { Implements map[string][]*Definition Description string + + Comment *CommentGroup } // AddTypes is the helper to add types definition to the schema @@ -70,10 +74,15 @@ type SchemaDefinition struct { Directives DirectiveList OperationTypes OperationTypeDefinitionList Position *Position `dump:"-"` + + BeforeDescriptionComment *CommentGroup + AfterDescriptionComment *CommentGroup + EndOfDefinitionComment *CommentGroup } type OperationTypeDefinition struct { Operation Operation Type string Position *Position `dump:"-"` + Comment *CommentGroup } diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/fragment.go b/vendor/github.com/vektah/gqlparser/v2/ast/fragment.go index 57ab56c7c6..7bd7dbce7f 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/fragment.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/fragment.go @@ -9,6 +9,7 @@ type FragmentSpread struct { Definition *FragmentDefinition Position *Position `dump:"-"` + Comment *CommentGroup } type InlineFragment struct { @@ -20,6 +21,7 @@ type InlineFragment struct { ObjectDefinition *Definition Position *Position `dump:"-"` + Comment *CommentGroup } type FragmentDefinition struct { @@ -35,4 +37,5 @@ type FragmentDefinition struct { Definition *Definition Position *Position `dump:"-"` + Comment *CommentGroup } diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/operation.go b/vendor/github.com/vektah/gqlparser/v2/ast/operation.go index 3b37f81bf3..16ee064db9 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/operation.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/operation.go @@ -15,6 +15,7 @@ type OperationDefinition struct { Directives DirectiveList SelectionSet SelectionSet Position *Position `dump:"-"` + Comment *CommentGroup } type VariableDefinition struct { @@ -23,6 +24,7 @@ type VariableDefinition struct { DefaultValue *Value Directives DirectiveList Position *Position `dump:"-"` + Comment *CommentGroup // Requires validation Definition *Definition diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/path.go b/vendor/github.com/vektah/gqlparser/v2/ast/path.go index 9af1684388..f40aa953dd 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/path.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/path.go @@ -14,10 +14,15 @@ type PathElement interface { isPathElement() } -var _ PathElement = PathIndex(0) -var _ PathElement = PathName("") +var ( + _ PathElement = PathIndex(0) + _ PathElement = PathName("") +) func (path Path) String() string { + if path == nil { + return "" + } var str bytes.Buffer for i, v := range path { switch v := v.(type) { @@ -60,8 +65,8 @@ func (path *Path) UnmarshalJSON(b []byte) error { type PathIndex int -func (_ PathIndex) isPathElement() {} +func (PathIndex) isPathElement() {} type PathName string -func (_ PathName) isPathElement() {} +func (PathName) isPathElement() {} diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/selection.go b/vendor/github.com/vektah/gqlparser/v2/ast/selection.go index 159db84471..c927a4d33a 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/selection.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/selection.go @@ -11,9 +11,9 @@ func (*Field) isSelection() {} func (*FragmentSpread) isSelection() {} func (*InlineFragment) isSelection() {} -func (s *Field) GetPosition() *Position { return s.Position } +func (f *Field) GetPosition() *Position { return f.Position } func (s *FragmentSpread) GetPosition() *Position { return s.Position } -func (s *InlineFragment) GetPosition() *Position { return s.Position } +func (f *InlineFragment) GetPosition() *Position { return f.Position } type Field struct { Alias string @@ -22,6 +22,7 @@ type Field struct { Directives DirectiveList SelectionSet SelectionSet Position *Position `dump:"-"` + Comment *CommentGroup // Require validation Definition *FieldDefinition @@ -32,6 +33,7 @@ type Argument struct { Name string Value *Value Position *Position `dump:"-"` + Comment *CommentGroup } func (f *Field) ArgumentMap(vars map[string]interface{}) map[string]interface{} { diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/type.go b/vendor/github.com/vektah/gqlparser/v2/ast/type.go index 9577fdb48c..5f77bc7ce4 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/type.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/type.go @@ -63,6 +63,6 @@ func (t *Type) IsCompatible(other *Type) bool { return true } -func (v *Type) Dump() string { - return v.String() +func (t *Type) Dump() string { + return t.String() } diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/value.go b/vendor/github.com/vektah/gqlparser/v2/ast/value.go index c25ef15059..10f7b1ccc6 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/value.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/value.go @@ -26,6 +26,7 @@ type Value struct { Children ChildValueList Kind ValueKind Position *Position `dump:"-"` + Comment *CommentGroup // Require validation Definition *Definition @@ -37,6 +38,7 @@ type ChildValue struct { Name string Value *Value Position *Position `dump:"-"` + Comment *CommentGroup } func (v *Value) Value(vars map[string]interface{}) (interface{}, error) { diff --git a/vendor/github.com/vektah/gqlparser/v2/gqlerror/error.go b/vendor/github.com/vektah/gqlparser/v2/gqlerror/error.go index 8145061a22..483a086d6d 100644 --- a/vendor/github.com/vektah/gqlparser/v2/gqlerror/error.go +++ b/vendor/github.com/vektah/gqlparser/v2/gqlerror/error.go @@ -9,9 +9,9 @@ import ( "github.com/vektah/gqlparser/v2/ast" ) -// Error is the standard graphql error type described in https://facebook.github.io/graphql/draft/#sec-Errors +// Error is the standard graphql error type described in https://spec.graphql.org/draft/#sec-Errors type Error struct { - err error `json:"-"` + Err error `json:"-"` Message string `json:"message"` Path ast.Path `json:"path,omitempty"` Locations []Location `json:"locations,omitempty"` @@ -64,12 +64,19 @@ func (err *Error) Error() string { return res.String() } -func (err Error) pathString() string { +func (err *Error) pathString() string { return err.Path.String() } -func (err Error) Unwrap() error { - return err.err +func (err *Error) Unwrap() error { + return err.Err +} + +func (err *Error) AsError() error { + if err == nil { + return nil + } + return err } func (errs List) Error() string { @@ -99,14 +106,48 @@ func (errs List) As(target interface{}) bool { return false } +func (errs List) Unwrap() []error { + l := make([]error, len(errs)) + for i, err := range errs { + l[i] = err + } + return l +} + func WrapPath(path ast.Path, err error) *Error { + if err == nil { + return nil + } return &Error{ - err: err, + Err: err, Message: err.Error(), Path: path, } } +func Wrap(err error) *Error { + if err == nil { + return nil + } + return &Error{ + Err: err, + Message: err.Error(), + } +} + +func WrapIfUnwrapped(err error) *Error { + if err == nil { + return nil + } + if gqlErr, ok := err.(*Error); ok { + return gqlErr + } + return &Error{ + Err: err, + Message: err.Error(), + } +} + func Errorf(message string, args ...interface{}) *Error { return &Error{ Message: fmt.Sprintf(message, args...), diff --git a/vendor/github.com/vektah/gqlparser/v2/gqlparser.go b/vendor/github.com/vektah/gqlparser/v2/gqlparser.go index e242a896b4..d404fd0b53 100644 --- a/vendor/github.com/vektah/gqlparser/v2/gqlparser.go +++ b/vendor/github.com/vektah/gqlparser/v2/gqlparser.go @@ -5,11 +5,21 @@ import ( "github.com/vektah/gqlparser/v2/gqlerror" "github.com/vektah/gqlparser/v2/parser" "github.com/vektah/gqlparser/v2/validator" + + // Blank import is used to load up the validator rules. _ "github.com/vektah/gqlparser/v2/validator/rules" ) func LoadSchema(str ...*ast.Source) (*ast.Schema, error) { - return validator.LoadSchema(append([]*ast.Source{validator.Prelude}, str...)...) + schema, err := validator.LoadSchema(append([]*ast.Source{validator.Prelude}, str...)...) + gqlErr, ok := err.(*gqlerror.Error) + if ok { + return schema, gqlErr + } + if err != nil { + return schema, gqlerror.Wrap(err) + } + return schema, nil } func MustLoadSchema(str ...*ast.Source) *ast.Schema { @@ -23,11 +33,14 @@ func MustLoadSchema(str ...*ast.Source) *ast.Schema { func LoadQuery(schema *ast.Schema, str string) (*ast.QueryDocument, gqlerror.List) { query, err := parser.ParseQuery(&ast.Source{Input: str}) if err != nil { - gqlErr := err.(*gqlerror.Error) - return nil, gqlerror.List{gqlErr} + gqlErr, ok := err.(*gqlerror.Error) + if ok { + return nil, gqlerror.List{gqlErr} + } + return nil, gqlerror.List{gqlerror.Wrap(err)} } errs := validator.Validate(schema, query) - if errs != nil { + if len(errs) > 0 { return nil, errs } diff --git a/vendor/github.com/vektah/gqlparser/v2/lexer/lexer.go b/vendor/github.com/vektah/gqlparser/v2/lexer/lexer.go index 25dcdcb9c4..21dd3cf4b2 100644 --- a/vendor/github.com/vektah/gqlparser/v2/lexer/lexer.go +++ b/vendor/github.com/vektah/gqlparser/v2/lexer/lexer.go @@ -55,7 +55,7 @@ func (s *Lexer) makeValueToken(kind Type, value string) (Token, error) { }, nil } -func (s *Lexer) makeError(format string, args ...interface{}) (Token, error) { +func (s *Lexer) makeError(format string, args ...interface{}) (Token, *gqlerror.Error) { column := s.endRunes - s.lineStartRunes + 1 return Token{ Kind: Invalid, @@ -74,8 +74,7 @@ func (s *Lexer) makeError(format string, args ...interface{}) (Token, error) { // This skips over whitespace and comments until it finds the next lexable // token, then lexes punctuators immediately or calls the appropriate helper // function for more complicated tokens. -func (s *Lexer) ReadToken() (token Token, err error) { - +func (s *Lexer) ReadToken() (Token, error) { s.ws() s.start = s.end s.startRunes = s.endRunes @@ -121,8 +120,7 @@ func (s *Lexer) ReadToken() (token Token, err error) { case '|': return s.makeValueToken(Pipe, "") case '#': - s.readComment() - return s.ReadToken() + return s.readComment() case '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z': return s.readName() @@ -254,9 +252,8 @@ func (s *Lexer) readNumber() (Token, error) { if float { return s.makeToken(Float) - } else { - return s.makeToken(Int) } + return s.makeToken(Int) } // acceptByte if it matches any of given bytes, returning true if it found anything @@ -319,8 +316,8 @@ func (s *Lexer) readString() (Token, error) { } switch r { default: - var char = rune(r) - var w = 1 + char := rune(r) + w := 1 // skip unicode overhead if we are in the ascii range if r >= 127 { @@ -393,8 +390,8 @@ func (s *Lexer) readString() (Token, error) { case 't': buf.WriteByte('\t') default: - s.end += 1 - s.endRunes += 1 + s.end++ + s.endRunes++ return s.makeError("Invalid character escape sequence: \\%s.", string(escape)) } s.end += 2 @@ -442,11 +439,12 @@ func (s *Lexer) readBlockString() (Token, error) { return s.makeError(`Invalid character within String: "\u%04d".`, r) } - if r == '\\' && s.end+4 <= inputLen && s.Input[s.end:s.end+4] == `\"""` { + switch { + case r == '\\' && s.end+4 <= inputLen && s.Input[s.end:s.end+4] == `\"""`: buf.WriteString(`"""`) s.end += 4 s.endRunes += 4 - } else if r == '\r' { + case r == '\r': if s.end+1 < inputLen && s.Input[s.end+1] == '\n' { s.end++ s.endRunes++ @@ -457,9 +455,9 @@ func (s *Lexer) readBlockString() (Token, error) { s.endRunes++ s.line++ s.lineStartRunes = s.endRunes - } else { - var char = rune(r) - var w = 1 + default: + char := rune(r) + w := 1 // skip unicode overhead if we are in the ascii range if r >= 127 { diff --git a/vendor/github.com/vektah/gqlparser/v2/lexer/lexer_test.yml b/vendor/github.com/vektah/gqlparser/v2/lexer/lexer_test.yml index 5c4d5f0ff5..0899f4ca9b 100644 --- a/vendor/github.com/vektah/gqlparser/v2/lexer/lexer_test.yml +++ b/vendor/github.com/vektah/gqlparser/v2/lexer/lexer_test.yml @@ -26,22 +26,38 @@ simple tokens: column: 3 value: 'foo' - - name: skips whitespace - input: "\n\n foo\n\n\n" + - name: records line and column with comments + input: "\n\n\n#foo\n #bar\n foo\n" tokens: + - + kind: COMMENT + start: 3 + end: 7 + line: 4 + column: 0 + value: '#foo' + - + kind: COMMENT + start: 10 + end: 14 + line: 5 + column: 3 + value: '#bar' - kind: NAME - start: 6 - end: 9 + start: 17 + end: 20 + line: 6 + column: 3 value: 'foo' - - name: skips comments - input: "\n #comment\n foo#comment\n" + - name: skips whitespace + input: "\n\n foo\n\n\n" tokens: - kind: NAME - start: 18 - end: 21 + start: 6 + end: 9 value: 'foo' - name: skips commas @@ -78,6 +94,57 @@ simple tokens: end: 1 value: a +lexes comments: + - name: basic + input: '#simple' + tokens: + - + kind: COMMENT + start: 0 + end: 7 + value: '#simple' + + - name: two lines + input: "#first\n#second" + tokens: + - + kind: COMMENT + start: 0 + end: 6 + value: "#first" + - + kind: COMMENT + start: 7 + end: 14 + value: "#second" + + - name: whitespace + input: '# white space ' + tokens: + - + kind: COMMENT + start: 0 + end: 14 + value: '# white space ' + + - name: not escaped + input: '#not escaped \n\r\b\t\f' + tokens: + - + kind: COMMENT + start: 0 + end: 23 + value: '#not escaped \n\r\b\t\f' + + - name: slashes + input: '#slashes \\ \/' + tokens: + - + kind: COMMENT + start: 0 + end: 14 + value: '#slashes \\ \/' + lexes strings: - name: basic input: '"simple"' @@ -674,7 +741,6 @@ lex reports useful unknown character error: - name: question mark input: "?" error: - message: 'Cannot parse the unexpected character "?".' message: 'Cannot parse the unexpected character "?".' locations: [{ line: 1, column: 1 }] diff --git a/vendor/github.com/vektah/gqlparser/v2/parser/parser.go b/vendor/github.com/vektah/gqlparser/v2/parser/parser.go index 68eb51edc6..bfcf7ea498 100644 --- a/vendor/github.com/vektah/gqlparser/v2/parser/parser.go +++ b/vendor/github.com/vektah/gqlparser/v2/parser/parser.go @@ -1,6 +1,7 @@ package parser import ( + "fmt" "strconv" "github.com/vektah/gqlparser/v2/ast" @@ -17,6 +18,53 @@ type parser struct { peekError error prev lexer.Token + + comment *ast.CommentGroup + commentConsuming bool + + tokenCount int + maxTokenLimit int +} + +func (p *parser) SetMaxTokenLimit(maxToken int) { + p.maxTokenLimit = maxToken +} + +func (p *parser) consumeComment() (*ast.Comment, bool) { + if p.err != nil { + return nil, false + } + tok := p.peek() + if tok.Kind != lexer.Comment { + return nil, false + } + p.next() + return &ast.Comment{ + Value: tok.Value, + Position: &tok.Pos, + }, true +} + +func (p *parser) consumeCommentGroup() { + if p.err != nil { + return + } + if p.commentConsuming { + return + } + p.commentConsuming = true + + var comments []*ast.Comment + for { + comment, ok := p.consumeComment() + if !ok { + break + } + comments = append(comments, comment) + } + + p.comment = &ast.CommentGroup{List: comments} + p.commentConsuming = false } func (p *parser) peekPos() *ast.Position { @@ -36,6 +84,9 @@ func (p *parser) peek() lexer.Token { if !p.peeked { p.peekToken, p.peekError = p.lexer.ReadToken() p.peeked = true + if p.peekToken.Kind == lexer.Comment { + p.consumeCommentGroup() + } } return p.peekToken @@ -52,33 +103,45 @@ func (p *parser) next() lexer.Token { if p.err != nil { return p.prev } + // Increment the token count before reading the next token + p.tokenCount++ + if p.maxTokenLimit != 0 && p.tokenCount > p.maxTokenLimit { + p.err = fmt.Errorf("exceeded token limit of %d", p.maxTokenLimit) + return p.prev + } if p.peeked { p.peeked = false + p.comment = nil p.prev, p.err = p.peekToken, p.peekError } else { p.prev, p.err = p.lexer.ReadToken() + if p.prev.Kind == lexer.Comment { + p.consumeCommentGroup() + } } return p.prev } -func (p *parser) expectKeyword(value string) lexer.Token { +func (p *parser) expectKeyword(value string) (lexer.Token, *ast.CommentGroup) { tok := p.peek() + comment := p.comment if tok.Kind == lexer.Name && tok.Value == value { - return p.next() + return p.next(), comment } p.error(tok, "Expected %s, found %s", strconv.Quote(value), tok.String()) - return tok + return tok, comment } -func (p *parser) expect(kind lexer.Type) lexer.Token { +func (p *parser) expect(kind lexer.Type) (lexer.Token, *ast.CommentGroup) { tok := p.peek() + comment := p.comment if tok.Kind == kind { - return p.next() + return p.next(), comment } p.error(tok, "Expected %s, found %s", kind, tok.Kind.String()) - return tok + return tok, comment } func (p *parser) skip(kind lexer.Type) bool { @@ -115,10 +178,10 @@ func (p *parser) many(start lexer.Type, end lexer.Type, cb func()) { p.next() } -func (p *parser) some(start lexer.Type, end lexer.Type, cb func()) { +func (p *parser) some(start lexer.Type, end lexer.Type, cb func()) *ast.CommentGroup { hasDef := p.skip(start) if !hasDef { - return + return nil } called := false @@ -129,8 +192,10 @@ func (p *parser) some(start lexer.Type, end lexer.Type, cb func()) { if !called { p.error(p.peek(), "expected at least one definition, found %s", p.peek().Kind.String()) - return + return nil } + comment := p.comment p.next() + return comment } diff --git a/vendor/github.com/vektah/gqlparser/v2/parser/query.go b/vendor/github.com/vektah/gqlparser/v2/parser/query.go index a38d982acb..f653bed5f9 100644 --- a/vendor/github.com/vektah/gqlparser/v2/parser/query.go +++ b/vendor/github.com/vektah/gqlparser/v2/parser/query.go @@ -2,13 +2,22 @@ package parser import ( "github.com/vektah/gqlparser/v2/lexer" - + //nolint:revive . "github.com/vektah/gqlparser/v2/ast" ) func ParseQuery(source *Source) (*QueryDocument, error) { p := parser{ - lexer: lexer.New(source), + lexer: lexer.New(source), + maxTokenLimit: 0, // 0 means unlimited + } + return p.parseQueryDocument(), p.err +} + +func ParseQueryWithTokenLimit(source *Source, maxTokenLimit int) (*QueryDocument, error) { + p := parser{ + lexer: lexer.New(source), + maxTokenLimit: maxTokenLimit, } return p.parseQueryDocument(), p.err } @@ -44,6 +53,7 @@ func (p *parser) parseOperationDefinition() *OperationDefinition { if p.peek().Kind == lexer.BraceL { return &OperationDefinition{ Position: p.peekPos(), + Comment: p.comment, Operation: Query, SelectionSet: p.parseRequiredSelectionSet(), } @@ -51,6 +61,7 @@ func (p *parser) parseOperationDefinition() *OperationDefinition { var od OperationDefinition od.Position = p.peekPos() + od.Comment = p.comment od.Operation = p.parseOperationType() if p.peek().Kind == lexer.Name { @@ -80,7 +91,7 @@ func (p *parser) parseOperationType() Operation { func (p *parser) parseVariableDefinitions() VariableDefinitionList { var defs []*VariableDefinition - p.many(lexer.ParenL, lexer.ParenR, func() { + p.some(lexer.ParenL, lexer.ParenR, func() { defs = append(defs, p.parseVariableDefinition()) }) @@ -90,6 +101,7 @@ func (p *parser) parseVariableDefinitions() VariableDefinitionList { func (p *parser) parseVariableDefinition() *VariableDefinition { var def VariableDefinition def.Position = p.peekPos() + def.Comment = p.comment def.Variable = p.parseVariable() p.expect(lexer.Colon) @@ -116,7 +128,7 @@ func (p *parser) parseOptionalSelectionSet() SelectionSet { selections = append(selections, p.parseSelection()) }) - return SelectionSet(selections) + return selections } func (p *parser) parseRequiredSelectionSet() SelectionSet { @@ -130,7 +142,7 @@ func (p *parser) parseRequiredSelectionSet() SelectionSet { selections = append(selections, p.parseSelection()) }) - return SelectionSet(selections) + return selections } func (p *parser) parseSelection() Selection { @@ -143,6 +155,7 @@ func (p *parser) parseSelection() Selection { func (p *parser) parseField() *Field { var field Field field.Position = p.peekPos() + field.Comment = p.comment field.Alias = p.parseName() if p.skip(lexer.Colon) { @@ -162,7 +175,7 @@ func (p *parser) parseField() *Field { func (p *parser) parseArguments(isConst bool) ArgumentList { var arguments ArgumentList - p.many(lexer.ParenL, lexer.ParenR, func() { + p.some(lexer.ParenL, lexer.ParenR, func() { arguments = append(arguments, p.parseArgument(isConst)) }) @@ -172,6 +185,7 @@ func (p *parser) parseArguments(isConst bool) ArgumentList { func (p *parser) parseArgument(isConst bool) *Argument { arg := Argument{} arg.Position = p.peekPos() + arg.Comment = p.comment arg.Name = p.parseName() p.expect(lexer.Colon) @@ -180,11 +194,12 @@ func (p *parser) parseArgument(isConst bool) *Argument { } func (p *parser) parseFragment() Selection { - p.expect(lexer.Spread) + _, comment := p.expect(lexer.Spread) if peek := p.peek(); peek.Kind == lexer.Name && peek.Value != "on" { return &FragmentSpread{ Position: p.peekPos(), + Comment: comment, Name: p.parseFragmentName(), Directives: p.parseDirectives(false), } @@ -192,6 +207,7 @@ func (p *parser) parseFragment() Selection { var def InlineFragment def.Position = p.peekPos() + def.Comment = comment if p.peek().Value == "on" { p.next() // "on" @@ -206,6 +222,7 @@ func (p *parser) parseFragment() Selection { func (p *parser) parseFragmentDefinition() *FragmentDefinition { var def FragmentDefinition def.Position = p.peekPos() + def.Comment = p.comment p.expectKeyword("fragment") def.Name = p.parseFragmentName() @@ -242,7 +259,7 @@ func (p *parser) parseValueLiteral(isConst bool) *Value { p.unexpectedError() return nil } - return &Value{Position: &token.Pos, Raw: p.parseVariable(), Kind: Variable} + return &Value{Position: &token.Pos, Comment: p.comment, Raw: p.parseVariable(), Kind: Variable} case lexer.Int: kind = IntValue case lexer.Float: @@ -267,32 +284,35 @@ func (p *parser) parseValueLiteral(isConst bool) *Value { p.next() - return &Value{Position: &token.Pos, Raw: token.Value, Kind: kind} + return &Value{Position: &token.Pos, Comment: p.comment, Raw: token.Value, Kind: kind} } func (p *parser) parseList(isConst bool) *Value { var values ChildValueList pos := p.peekPos() + comment := p.comment p.many(lexer.BracketL, lexer.BracketR, func() { values = append(values, &ChildValue{Value: p.parseValueLiteral(isConst)}) }) - return &Value{Children: values, Kind: ListValue, Position: pos} + return &Value{Children: values, Kind: ListValue, Position: pos, Comment: comment} } func (p *parser) parseObject(isConst bool) *Value { var fields ChildValueList pos := p.peekPos() + comment := p.comment p.many(lexer.BraceL, lexer.BraceR, func() { fields = append(fields, p.parseObjectField(isConst)) }) - return &Value{Children: fields, Kind: ObjectValue, Position: pos} + return &Value{Children: fields, Kind: ObjectValue, Position: pos, Comment: comment} } func (p *parser) parseObjectField(isConst bool) *ChildValue { field := ChildValue{} field.Position = p.peekPos() + field.Comment = p.comment field.Name = p.parseName() p.expect(lexer.Colon) @@ -342,7 +362,7 @@ func (p *parser) parseTypeReference() *Type { } func (p *parser) parseName() string { - token := p.expect(lexer.Name) + token, _ := p.expect(lexer.Name) return token.Value } diff --git a/vendor/github.com/vektah/gqlparser/v2/parser/query_test.yml b/vendor/github.com/vektah/gqlparser/v2/parser/query_test.yml index a46a01e718..ec0580f5fa 100644 --- a/vendor/github.com/vektah/gqlparser/v2/parser/query_test.yml +++ b/vendor/github.com/vektah/gqlparser/v2/parser/query_test.yml @@ -436,6 +436,7 @@ large queries: - Alias: "id" Name: "id" + Comment: "# Copyright (c) 2015-present, Facebook, Inc.\n#\n# This source code is licensed under the MIT license found in the\n# LICENSE file in the root directory of this source tree.\n" - Operation: Operation("mutation") Name: "likeStory" diff --git a/vendor/github.com/vektah/gqlparser/v2/parser/schema.go b/vendor/github.com/vektah/gqlparser/v2/parser/schema.go index aec08a9700..44c693754f 100644 --- a/vendor/github.com/vektah/gqlparser/v2/parser/schema.go +++ b/vendor/github.com/vektah/gqlparser/v2/parser/schema.go @@ -1,39 +1,73 @@ package parser import ( + //nolint:revive . "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/lexer" ) +func ParseSchemas(inputs ...*Source) (*SchemaDocument, error) { + sd := &SchemaDocument{} + for _, input := range inputs { + inputAst, err := ParseSchema(input) + if err != nil { + return nil, err + } + sd.Merge(inputAst) + } + return sd, nil +} + func ParseSchema(source *Source) (*SchemaDocument, error) { p := parser{ - lexer: lexer.New(source), + lexer: lexer.New(source), + maxTokenLimit: 0, // default value is unlimited } - ast, err := p.parseSchemaDocument(), p.err + sd, err := p.parseSchemaDocument(), p.err if err != nil { return nil, err } - for _, def := range ast.Definitions { + for _, def := range sd.Definitions { def.BuiltIn = source.BuiltIn } - for _, def := range ast.Extensions { + for _, def := range sd.Extensions { def.BuiltIn = source.BuiltIn } - return ast, nil + return sd, nil } -func ParseSchemas(inputs ...*Source) (*SchemaDocument, error) { - ast := &SchemaDocument{} +func ParseSchemasWithLimit(maxTokenLimit int, inputs ...*Source) (*SchemaDocument, error) { + sd := &SchemaDocument{} for _, input := range inputs { - inputAst, err := ParseSchema(input) + inputAst, err := ParseSchemaWithLimit(input, maxTokenLimit) if err != nil { return nil, err } - ast.Merge(inputAst) + sd.Merge(inputAst) } - return ast, nil + return sd, nil +} + +func ParseSchemaWithLimit(source *Source, maxTokenLimit int) (*SchemaDocument, error) { + p := parser{ + lexer: lexer.New(source), + maxTokenLimit: maxTokenLimit, // 0 is unlimited + } + sd, err := p.parseSchemaDocument(), p.err + if err != nil { + return nil, err + } + + for _, def := range sd.Definitions { + def.BuiltIn = source.BuiltIn + } + for _, def := range sd.Extensions { + def.BuiltIn = source.BuiltIn + } + + return sd, nil } func (p *parser) parseSchemaDocument() *SchemaDocument { @@ -44,7 +78,7 @@ func (p *parser) parseSchemaDocument() *SchemaDocument { return nil } - var description string + var description descriptionWithComment if p.peek().Kind == lexer.BlockString || p.peek().Kind == lexer.String { description = p.parseDescription() } @@ -62,7 +96,7 @@ func (p *parser) parseSchemaDocument() *SchemaDocument { case "directive": doc.Directives = append(doc.Directives, p.parseDirectiveDefinition(description)) case "extend": - if description != "" { + if description.text != "" { p.unexpectedToken(p.prev) } p.parseTypeSystemExtension(&doc) @@ -72,20 +106,26 @@ func (p *parser) parseSchemaDocument() *SchemaDocument { } } + // treat end of file comments + doc.Comment = p.comment + return &doc } -func (p *parser) parseDescription() string { +func (p *parser) parseDescription() descriptionWithComment { token := p.peek() + var desc descriptionWithComment if token.Kind != lexer.BlockString && token.Kind != lexer.String { - return "" + return desc } - return p.next().Value + desc.comment = p.comment + desc.text = p.next().Value + return desc } -func (p *parser) parseTypeSystemDefinition(description string) *Definition { +func (p *parser) parseTypeSystemDefinition(description descriptionWithComment) *Definition { tok := p.peek() if tok.Kind != lexer.Name { p.unexpectedError() @@ -111,15 +151,17 @@ func (p *parser) parseTypeSystemDefinition(description string) *Definition { } } -func (p *parser) parseSchemaDefinition(description string) *SchemaDefinition { - p.expectKeyword("schema") +func (p *parser) parseSchemaDefinition(description descriptionWithComment) *SchemaDefinition { + _, comment := p.expectKeyword("schema") - def := SchemaDefinition{Description: description} + def := SchemaDefinition{} def.Position = p.peekPos() - def.Description = description + def.BeforeDescriptionComment = description.comment + def.Description = description.text + def.AfterDescriptionComment = comment def.Directives = p.parseDirectives(true) - p.some(lexer.BraceL, lexer.BraceR, func() { + def.EndOfDefinitionComment = p.some(lexer.BraceL, lexer.BraceR, func() { def.OperationTypes = append(def.OperationTypes, p.parseOperationTypeDefinition()) }) return &def @@ -128,35 +170,40 @@ func (p *parser) parseSchemaDefinition(description string) *SchemaDefinition { func (p *parser) parseOperationTypeDefinition() *OperationTypeDefinition { var op OperationTypeDefinition op.Position = p.peekPos() + op.Comment = p.comment op.Operation = p.parseOperationType() p.expect(lexer.Colon) op.Type = p.parseName() return &op } -func (p *parser) parseScalarTypeDefinition(description string) *Definition { - p.expectKeyword("scalar") +func (p *parser) parseScalarTypeDefinition(description descriptionWithComment) *Definition { + _, comment := p.expectKeyword("scalar") var def Definition def.Position = p.peekPos() + def.BeforeDescriptionComment = description.comment + def.Description = description.text + def.AfterDescriptionComment = comment def.Kind = Scalar - def.Description = description def.Name = p.parseName() def.Directives = p.parseDirectives(true) return &def } -func (p *parser) parseObjectTypeDefinition(description string) *Definition { - p.expectKeyword("type") +func (p *parser) parseObjectTypeDefinition(description descriptionWithComment) *Definition { + _, comment := p.expectKeyword("type") var def Definition def.Position = p.peekPos() def.Kind = Object - def.Description = description + def.BeforeDescriptionComment = description.comment + def.Description = description.text + def.AfterDescriptionComment = comment def.Name = p.parseName() def.Interfaces = p.parseImplementsInterfaces() def.Directives = p.parseDirectives(true) - def.Fields = p.parseFieldsDefinition() + def.Fields, def.EndOfDefinitionComment = p.parseFieldsDefinition() return &def } @@ -175,18 +222,26 @@ func (p *parser) parseImplementsInterfaces() []string { return types } -func (p *parser) parseFieldsDefinition() FieldList { +func (p *parser) parseFieldsDefinition() (FieldList, *CommentGroup) { var defs FieldList - p.some(lexer.BraceL, lexer.BraceR, func() { + comment := p.some(lexer.BraceL, lexer.BraceR, func() { defs = append(defs, p.parseFieldDefinition()) }) - return defs + return defs, comment } func (p *parser) parseFieldDefinition() *FieldDefinition { var def FieldDefinition def.Position = p.peekPos() - def.Description = p.parseDescription() + + desc := p.parseDescription() + if desc.text != "" { + def.BeforeDescriptionComment = desc.comment + def.Description = desc.text + } + + p.peek() // peek to set p.comment + def.AfterDescriptionComment = p.comment def.Name = p.parseName() def.Arguments = p.parseArgumentDefs() p.expect(lexer.Colon) @@ -207,7 +262,15 @@ func (p *parser) parseArgumentDefs() ArgumentDefinitionList { func (p *parser) parseArgumentDef() *ArgumentDefinition { var def ArgumentDefinition def.Position = p.peekPos() - def.Description = p.parseDescription() + + desc := p.parseDescription() + if desc.text != "" { + def.BeforeDescriptionComment = desc.comment + def.Description = desc.text + } + + p.peek() // peek to set p.comment + def.AfterDescriptionComment = p.comment def.Name = p.parseName() p.expect(lexer.Colon) def.Type = p.parseTypeReference() @@ -221,7 +284,15 @@ func (p *parser) parseArgumentDef() *ArgumentDefinition { func (p *parser) parseInputValueDef() *FieldDefinition { var def FieldDefinition def.Position = p.peekPos() - def.Description = p.parseDescription() + + desc := p.parseDescription() + if desc.text != "" { + def.BeforeDescriptionComment = desc.comment + def.Description = desc.text + } + + p.peek() // peek to set p.comment + def.AfterDescriptionComment = p.comment def.Name = p.parseName() p.expect(lexer.Colon) def.Type = p.parseTypeReference() @@ -232,27 +303,31 @@ func (p *parser) parseInputValueDef() *FieldDefinition { return &def } -func (p *parser) parseInterfaceTypeDefinition(description string) *Definition { - p.expectKeyword("interface") +func (p *parser) parseInterfaceTypeDefinition(description descriptionWithComment) *Definition { + _, comment := p.expectKeyword("interface") var def Definition def.Position = p.peekPos() def.Kind = Interface - def.Description = description + def.BeforeDescriptionComment = description.comment + def.Description = description.text + def.AfterDescriptionComment = comment def.Name = p.parseName() def.Interfaces = p.parseImplementsInterfaces() def.Directives = p.parseDirectives(true) - def.Fields = p.parseFieldsDefinition() + def.Fields, def.EndOfDefinitionComment = p.parseFieldsDefinition() return &def } -func (p *parser) parseUnionTypeDefinition(description string) *Definition { - p.expectKeyword("union") +func (p *parser) parseUnionTypeDefinition(description descriptionWithComment) *Definition { + _, comment := p.expectKeyword("union") var def Definition def.Position = p.peekPos() def.Kind = Union - def.Description = description + def.BeforeDescriptionComment = description.comment + def.Description = description.text + def.AfterDescriptionComment = comment def.Name = p.parseName() def.Directives = p.parseDirectives(true) def.Types = p.parseUnionMemberTypes() @@ -273,87 +348,101 @@ func (p *parser) parseUnionMemberTypes() []string { return types } -func (p *parser) parseEnumTypeDefinition(description string) *Definition { - p.expectKeyword("enum") +func (p *parser) parseEnumTypeDefinition(description descriptionWithComment) *Definition { + _, comment := p.expectKeyword("enum") var def Definition def.Position = p.peekPos() def.Kind = Enum - def.Description = description + def.BeforeDescriptionComment = description.comment + def.Description = description.text + def.AfterDescriptionComment = comment def.Name = p.parseName() def.Directives = p.parseDirectives(true) - def.EnumValues = p.parseEnumValuesDefinition() + def.EnumValues, def.EndOfDefinitionComment = p.parseEnumValuesDefinition() return &def } -func (p *parser) parseEnumValuesDefinition() EnumValueList { +func (p *parser) parseEnumValuesDefinition() (EnumValueList, *CommentGroup) { var values EnumValueList - p.some(lexer.BraceL, lexer.BraceR, func() { + comment := p.some(lexer.BraceL, lexer.BraceR, func() { values = append(values, p.parseEnumValueDefinition()) }) - return values + return values, comment } func (p *parser) parseEnumValueDefinition() *EnumValueDefinition { - return &EnumValueDefinition{ - Position: p.peekPos(), - Description: p.parseDescription(), - Name: p.parseName(), - Directives: p.parseDirectives(true), + var def EnumValueDefinition + def.Position = p.peekPos() + desc := p.parseDescription() + if desc.text != "" { + def.BeforeDescriptionComment = desc.comment + def.Description = desc.text } + + p.peek() // peek to set p.comment + def.AfterDescriptionComment = p.comment + + def.Name = p.parseName() + def.Directives = p.parseDirectives(true) + + return &def } -func (p *parser) parseInputObjectTypeDefinition(description string) *Definition { - p.expectKeyword("input") +func (p *parser) parseInputObjectTypeDefinition(description descriptionWithComment) *Definition { + _, comment := p.expectKeyword("input") var def Definition def.Position = p.peekPos() def.Kind = InputObject - def.Description = description + def.BeforeDescriptionComment = description.comment + def.Description = description.text + def.AfterDescriptionComment = comment def.Name = p.parseName() def.Directives = p.parseDirectives(true) - def.Fields = p.parseInputFieldsDefinition() + def.Fields, def.EndOfDefinitionComment = p.parseInputFieldsDefinition() return &def } -func (p *parser) parseInputFieldsDefinition() FieldList { +func (p *parser) parseInputFieldsDefinition() (FieldList, *CommentGroup) { var values FieldList - p.some(lexer.BraceL, lexer.BraceR, func() { + comment := p.some(lexer.BraceL, lexer.BraceR, func() { values = append(values, p.parseInputValueDef()) }) - return values + return values, comment } func (p *parser) parseTypeSystemExtension(doc *SchemaDocument) { - p.expectKeyword("extend") + _, comment := p.expectKeyword("extend") switch p.peek().Value { case "schema": - doc.SchemaExtension = append(doc.SchemaExtension, p.parseSchemaExtension()) + doc.SchemaExtension = append(doc.SchemaExtension, p.parseSchemaExtension(comment)) case "scalar": - doc.Extensions = append(doc.Extensions, p.parseScalarTypeExtension()) + doc.Extensions = append(doc.Extensions, p.parseScalarTypeExtension(comment)) case "type": - doc.Extensions = append(doc.Extensions, p.parseObjectTypeExtension()) + doc.Extensions = append(doc.Extensions, p.parseObjectTypeExtension(comment)) case "interface": - doc.Extensions = append(doc.Extensions, p.parseInterfaceTypeExtension()) + doc.Extensions = append(doc.Extensions, p.parseInterfaceTypeExtension(comment)) case "union": - doc.Extensions = append(doc.Extensions, p.parseUnionTypeExtension()) + doc.Extensions = append(doc.Extensions, p.parseUnionTypeExtension(comment)) case "enum": - doc.Extensions = append(doc.Extensions, p.parseEnumTypeExtension()) + doc.Extensions = append(doc.Extensions, p.parseEnumTypeExtension(comment)) case "input": - doc.Extensions = append(doc.Extensions, p.parseInputObjectTypeExtension()) + doc.Extensions = append(doc.Extensions, p.parseInputObjectTypeExtension(comment)) default: p.unexpectedError() } } -func (p *parser) parseSchemaExtension() *SchemaDefinition { +func (p *parser) parseSchemaExtension(comment *CommentGroup) *SchemaDefinition { p.expectKeyword("schema") var def SchemaDefinition def.Position = p.peekPos() + def.AfterDescriptionComment = comment def.Directives = p.parseDirectives(true) - p.some(lexer.BraceL, lexer.BraceR, func() { + def.EndOfDefinitionComment = p.some(lexer.BraceL, lexer.BraceR, func() { def.OperationTypes = append(def.OperationTypes, p.parseOperationTypeDefinition()) }) if len(def.Directives) == 0 && len(def.OperationTypes) == 0 { @@ -362,11 +451,12 @@ func (p *parser) parseSchemaExtension() *SchemaDefinition { return &def } -func (p *parser) parseScalarTypeExtension() *Definition { +func (p *parser) parseScalarTypeExtension(comment *CommentGroup) *Definition { p.expectKeyword("scalar") var def Definition def.Position = p.peekPos() + def.AfterDescriptionComment = comment def.Kind = Scalar def.Name = p.parseName() def.Directives = p.parseDirectives(true) @@ -376,42 +466,45 @@ func (p *parser) parseScalarTypeExtension() *Definition { return &def } -func (p *parser) parseObjectTypeExtension() *Definition { +func (p *parser) parseObjectTypeExtension(comment *CommentGroup) *Definition { p.expectKeyword("type") var def Definition def.Position = p.peekPos() + def.AfterDescriptionComment = comment def.Kind = Object def.Name = p.parseName() def.Interfaces = p.parseImplementsInterfaces() def.Directives = p.parseDirectives(true) - def.Fields = p.parseFieldsDefinition() + def.Fields, def.EndOfDefinitionComment = p.parseFieldsDefinition() if len(def.Interfaces) == 0 && len(def.Directives) == 0 && len(def.Fields) == 0 { p.unexpectedError() } return &def } -func (p *parser) parseInterfaceTypeExtension() *Definition { +func (p *parser) parseInterfaceTypeExtension(comment *CommentGroup) *Definition { p.expectKeyword("interface") var def Definition def.Position = p.peekPos() + def.AfterDescriptionComment = comment def.Kind = Interface def.Name = p.parseName() def.Directives = p.parseDirectives(true) - def.Fields = p.parseFieldsDefinition() + def.Fields, def.EndOfDefinitionComment = p.parseFieldsDefinition() if len(def.Directives) == 0 && len(def.Fields) == 0 { p.unexpectedError() } return &def } -func (p *parser) parseUnionTypeExtension() *Definition { +func (p *parser) parseUnionTypeExtension(comment *CommentGroup) *Definition { p.expectKeyword("union") var def Definition def.Position = p.peekPos() + def.AfterDescriptionComment = comment def.Kind = Union def.Name = p.parseName() def.Directives = p.parseDirectives(true) @@ -423,43 +516,47 @@ func (p *parser) parseUnionTypeExtension() *Definition { return &def } -func (p *parser) parseEnumTypeExtension() *Definition { +func (p *parser) parseEnumTypeExtension(comment *CommentGroup) *Definition { p.expectKeyword("enum") var def Definition def.Position = p.peekPos() + def.AfterDescriptionComment = comment def.Kind = Enum def.Name = p.parseName() def.Directives = p.parseDirectives(true) - def.EnumValues = p.parseEnumValuesDefinition() + def.EnumValues, def.EndOfDefinitionComment = p.parseEnumValuesDefinition() if len(def.Directives) == 0 && len(def.EnumValues) == 0 { p.unexpectedError() } return &def } -func (p *parser) parseInputObjectTypeExtension() *Definition { +func (p *parser) parseInputObjectTypeExtension(comment *CommentGroup) *Definition { p.expectKeyword("input") var def Definition def.Position = p.peekPos() + def.AfterDescriptionComment = comment def.Kind = InputObject def.Name = p.parseName() def.Directives = p.parseDirectives(false) - def.Fields = p.parseInputFieldsDefinition() + def.Fields, def.EndOfDefinitionComment = p.parseInputFieldsDefinition() if len(def.Directives) == 0 && len(def.Fields) == 0 { p.unexpectedError() } return &def } -func (p *parser) parseDirectiveDefinition(description string) *DirectiveDefinition { - p.expectKeyword("directive") +func (p *parser) parseDirectiveDefinition(description descriptionWithComment) *DirectiveDefinition { + _, comment := p.expectKeyword("directive") p.expect(lexer.At) var def DirectiveDefinition def.Position = p.peekPos() - def.Description = description + def.BeforeDescriptionComment = description.comment + def.Description = description.text + def.AfterDescriptionComment = comment def.Name = p.parseName() def.Arguments = p.parseArgumentDefs() @@ -486,7 +583,7 @@ func (p *parser) parseDirectiveLocations() []DirectiveLocation { } func (p *parser) parseDirectiveLocation() DirectiveLocation { - name := p.expect(lexer.Name) + name, _ := p.expect(lexer.Name) switch name.Value { case `QUERY`: @@ -532,3 +629,8 @@ func (p *parser) parseDirectiveLocation() DirectiveLocation { p.unexpectedToken(name) return "" } + +type descriptionWithComment struct { + text string + comment *CommentGroup +} diff --git a/vendor/github.com/vektah/gqlparser/v2/parser/schema_test.yml b/vendor/github.com/vektah/gqlparser/v2/parser/schema_test.yml index 8b6a5d0ca3..705514a995 100644 --- a/vendor/github.com/vektah/gqlparser/v2/parser/schema_test.yml +++ b/vendor/github.com/vektah/gqlparser/v2/parser/schema_test.yml @@ -15,6 +15,67 @@ object types: Name: "world" Type: String + - name: with comments + input: | + # Hello + # Hello another + type Hello { + # World + # World another + world: String + # end of type comments + } + # end of file comments + ast: | + + Definitions: [Definition] + - + Kind: DefinitionKind("OBJECT") + Name: "Hello" + Fields: [FieldDefinition] + - + Name: "world" + Type: String + AfterDescriptionComment: "# World\n# World another\n" + AfterDescriptionComment: "# Hello\n# Hello another\n" + EndOfDefinitionComment: "# end of type comments\n" + Comment: "# end of file comments\n" + + - name: with comments and description + input: | + # Hello + # Hello another + "type description" + # Hello after description + # Hello after description another + type Hello { + # World + # World another + "field description" + # World after description + # World after description another + world: String + # end of definition coments + # end of definition comments another + } + ast: | + + Definitions: [Definition] + - + Kind: DefinitionKind("OBJECT") + Description: "type description" + Name: "Hello" + Fields: [FieldDefinition] + - + Description: "field description" + Name: "world" + Type: String + BeforeDescriptionComment: "# World\n# World another\n" + AfterDescriptionComment: "# World after description\n# World after description another\n" + BeforeDescriptionComment: "# Hello\n# Hello another\n" + AfterDescriptionComment: "# Hello after description\n# Hello after description another\n" + EndOfDefinitionComment: "# end of definition coments\n# end of definition comments another\n" + - name: with description input: | "Description" @@ -35,6 +96,7 @@ object types: - name: with block description input: | + # Before description comment """ Description """ @@ -53,6 +115,8 @@ object types: - Name: "world" Type: String + BeforeDescriptionComment: "# Before description comment\n" + AfterDescriptionComment: "# Even with comments between them\n" - name: with field arg input: | type Hello { @@ -146,8 +210,11 @@ object types: type extensions: - name: Object extension input: | + # comment extend type Hello { + # comment world world: String + # end of definition comment } ast: | @@ -159,6 +226,9 @@ type extensions: - Name: "world" Type: String + AfterDescriptionComment: "# comment world\n" + AfterDescriptionComment: "# comment\n" + EndOfDefinitionComment: "# end of definition comment\n" - name: without any fields input: "extend type Hello implements Greeting" @@ -277,6 +347,30 @@ schema definition: Operation: Operation("query") Type: "Query" + - name: with comments and description + input: | + # before description comment + "description" + # after description comment + schema { + # before field comment + query: Query + # after field comment + } + ast: | + + Schema: [SchemaDefinition] + - + Description: "description" + OperationTypes: [OperationTypeDefinition] + - + Operation: Operation("query") + Type: "Query" + Comment: "# before field comment\n" + BeforeDescriptionComment: "# before description comment\n" + AfterDescriptionComment: "# after description comment\n" + EndOfDefinitionComment: "# after field comment\n" + schema extensions: - name: simple input: | @@ -292,6 +386,26 @@ schema extensions: Operation: Operation("mutation") Type: "Mutation" + - name: with comment and description + input: | + # before extend comment + extend schema { + # before field comment + mutation: Mutation + # after field comment + } + ast: | + + SchemaExtension: [SchemaDefinition] + - + OperationTypes: [OperationTypeDefinition] + - + Operation: Operation("mutation") + Type: "Mutation" + Comment: "# before field comment\n" + AfterDescriptionComment: "# before extend comment\n" + EndOfDefinitionComment: "# after field comment\n" + - name: directive only input: "extend schema @directive" ast: | diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/prelude.go b/vendor/github.com/vektah/gqlparser/v2/validator/prelude.go index c354ec0dfa..43766f2215 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/prelude.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/prelude.go @@ -2,6 +2,7 @@ package validator import ( _ "embed" + "github.com/vektah/gqlparser/v2/ast" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/prelude.graphql b/vendor/github.com/vektah/gqlparser/v2/validator/prelude.graphql index bdca0096a5..e199da5d9f 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/prelude.graphql +++ b/vendor/github.com/vektah/gqlparser/v2/validator/prelude.graphql @@ -27,6 +27,9 @@ directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITIO "The @specifiedBy built-in directive is used within the type system definition language to provide a scalar specification URL for specifying the behavior of custom scalar types." directive @specifiedBy(url: String!) on SCALAR +"The @defer directive may be specified on a fragment spread to imply de-prioritization, that causes the fragment to be omitted in the initial response, and delivered as a subsequent response afterward. A query with @defer directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred delivered in a subsequent response. @include and @skip take precedence over @defer." +directive @defer(if: Boolean = true, label: String) on FRAGMENT_SPREAD | INLINE_FRAGMENT + type __Schema { description: String types: [__Type!]! diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/fields_on_correct_type.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/fields_on_correct_type.go index aa83c6967e..24d4f3db05 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/fields_on_correct_type.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/fields_on_correct_type.go @@ -6,6 +6,8 @@ import ( "strings" "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) @@ -41,11 +43,12 @@ func getSuggestedTypeNames(walker *Walker, parent *ast.Definition, name string) return nil } - var suggestedObjectTypes []string + possibleTypes := walker.Schema.GetPossibleTypes(parent) + suggestedObjectTypes := make([]string, 0, len(possibleTypes)) var suggestedInterfaceTypes []string interfaceUsageCount := map[string]int{} - for _, possibleType := range walker.Schema.GetPossibleTypes(parent) { + for _, possibleType := range possibleTypes { field := possibleType.Fields.ForName(name) if field == nil { continue @@ -64,7 +67,7 @@ func getSuggestedTypeNames(walker *Walker, parent *ast.Definition, name string) } } - suggestedTypes := append(suggestedInterfaceTypes, suggestedObjectTypes...) + suggestedTypes := concatSlice(suggestedInterfaceTypes, suggestedObjectTypes) sort.SliceStable(suggestedTypes, func(i, j int) bool { typeA, typeB := suggestedTypes[i], suggestedTypes[j] @@ -78,6 +81,16 @@ func getSuggestedTypeNames(walker *Walker, parent *ast.Definition, name string) return suggestedTypes } +// By employing a full slice expression (slice[low:high:max]), +// where max is set to the slice’s length, +// we ensure that appending elements results +// in a slice backed by a distinct array. +// This method prevents the shared array issue +func concatSlice(first []string, second []string) []string { + n := len(first) + return append(first[:n:n], second...) +} + // For the field name provided, determine if there are any similar field names // that may be the result of a typo. func getSuggestedFieldNames(parent *ast.Definition, name string) []string { @@ -85,7 +98,7 @@ func getSuggestedFieldNames(parent *ast.Definition, name string) []string { return nil } - var possibleFieldNames []string + possibleFieldNames := make([]string, 0, len(parent.Fields)) for _, field := range parent.Fields { possibleFieldNames = append(possibleFieldNames, field.Name) } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/fragments_on_composite_types.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/fragments_on_composite_types.go index 5215f697e7..81ef861ba5 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/fragments_on_composite_types.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/fragments_on_composite_types.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_argument_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_argument_names.go index da5a796218..c187dabf30 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_argument_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_argument_names.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_directives.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_directives.go index 18fe41fd78..f7bae811c9 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_directives.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_directives.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) @@ -12,7 +14,7 @@ func init() { Line int Column int } - var seen map[mayNotBeUsedDirective]bool = map[mayNotBeUsedDirective]bool{} + seen := map[mayNotBeUsedDirective]bool{} observers.OnDirective(func(walker *Walker, directive *ast.Directive) { if directive.Definition == nil { addError( diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_fragment_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_fragment_names.go index b7427d0d0d..3afd9c1c16 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_fragment_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_fragment_names.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_root_type.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_root_type.go index 4c60c8d8c2..60bc0d5242 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_root_type.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_root_type.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_type_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_type_names.go index 7abfbf62f1..902939d354 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_type_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_type_names.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/lone_anonymous_operation.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/lone_anonymous_operation.go index d275285425..fe8bb2039a 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/lone_anonymous_operation.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/lone_anonymous_operation.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_fragment_cycles.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_fragment_cycles.go index da73f3499f..a953174f72 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_fragment_cycles.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_fragment_cycles.go @@ -5,6 +5,8 @@ import ( "strings" "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_undefined_variables.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_undefined_variables.go index 91df727a25..46c18d120a 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_undefined_variables.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_undefined_variables.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_fragments.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_fragments.go index dfc896725a..59d9c15c49 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_fragments.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_fragments.go @@ -2,12 +2,13 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) func init() { AddRule("NoUnusedFragments", func(observers *Events, addError AddErrFunc) { - inFragmentDefinition := false fragmentNameUsed := make(map[string]bool) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_variables.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_variables.go index df2e5f4b7f..d308810943 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_variables.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_variables.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/overlapping_fields_can_be_merged.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/overlapping_fields_can_be_merged.go index 38e1efa11b..eaa2035ea5 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/overlapping_fields_can_be_merged.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/overlapping_fields_can_be_merged.go @@ -6,11 +6,12 @@ import ( "reflect" "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) func init() { - AddRule("OverlappingFieldsCanBeMerged", func(observers *Events, addError AddErrFunc) { /** * Algorithm: @@ -302,10 +303,8 @@ func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetweenFieldsAndFr } func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetweenFragments(conflicts *conflictMessageContainer, areMutuallyExclusive bool, fragmentSpreadA *ast.FragmentSpread, fragmentSpreadB *ast.FragmentSpread) { - var check func(fragmentSpreadA *ast.FragmentSpread, fragmentSpreadB *ast.FragmentSpread) check = func(fragmentSpreadA *ast.FragmentSpread, fragmentSpreadB *ast.FragmentSpread) { - if fragmentSpreadA.Name == fragmentSpreadB.Name { return } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go index a3f795c97b..244e5f20cb 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go @@ -2,12 +2,13 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) func init() { AddRule("PossibleFragmentSpreads", func(observers *Events, addError AddErrFunc) { - validate := func(walker *Walker, parentDef *ast.Definition, fragmentName string, emitError func()) { if parentDef == nil { return diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/provided_required_arguments.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/provided_required_arguments.go index d8ed652092..ab79163b16 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/provided_required_arguments.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/provided_required_arguments.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/scalar_leafs.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/scalar_leafs.go index 718bc6834a..605ab9e8e2 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/scalar_leafs.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/scalar_leafs.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/single_field_subscriptions.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/single_field_subscriptions.go index a9e5bf6335..7d4c684318 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/single_field_subscriptions.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/single_field_subscriptions.go @@ -5,6 +5,8 @@ import ( "strings" "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_argument_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_argument_names.go index 1d9a50ab22..e977d63876 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_argument_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_argument_names.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_directives_per_location.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_directives_per_location.go index 52dfb21eb3..47971ee1a1 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_directives_per_location.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_directives_per_location.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_fragment_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_fragment_names.go index 8c348aea06..2c44a4372d 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_fragment_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_fragment_names.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_input_field_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_input_field_names.go index 092be671c0..c5fce8ff53 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_input_field_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_input_field_names.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_operation_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_operation_names.go index 4d41b60ae3..49ffbe47f4 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_operation_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_operation_names.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_variable_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_variable_names.go index 6481ef4cd2..c93948c177 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_variable_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_variable_names.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/values_of_correct_type.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/values_of_correct_type.go index 22bea77117..914e428ea0 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/values_of_correct_type.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/values_of_correct_type.go @@ -6,6 +6,8 @@ import ( "strconv" "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) @@ -157,7 +159,7 @@ func unexpectedTypeMessageOnly(v *ast.Value) ErrorOption { return Message(`Float cannot represent non numeric value: %s`, v.String()) case "ID", "ID!": return Message(`ID cannot represent a non-string and non-integer value: %s`, v.String()) - //case "Enum": + // case "Enum": // return Message(`Enum "%s" cannot represent non-enum value: %s`, v.ExpectedType.String(), v.String()) default: if v.Definition.Kind == ast.Enum { diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_are_input_types.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_are_input_types.go index 4ea94e5a82..d16ee02156 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_are_input_types.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_are_input_types.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_in_allowed_position.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_in_allowed_position.go index eef7435400..e3fd6fbbd6 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_in_allowed_position.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_in_allowed_position.go @@ -2,6 +2,8 @@ package validator import ( "github.com/vektah/gqlparser/v2/ast" + + //nolint:revive // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/schema.go b/vendor/github.com/vektah/gqlparser/v2/validator/schema.go index 976ed8304e..d859028444 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/schema.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/schema.go @@ -5,20 +5,21 @@ import ( "strconv" "strings" + //nolint:revive . "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/gqlerror" "github.com/vektah/gqlparser/v2/parser" ) func LoadSchema(inputs ...*Source) (*Schema, error) { - ast, err := parser.ParseSchemas(inputs...) + sd, err := parser.ParseSchemas(inputs...) if err != nil { - return nil, err + return nil, gqlerror.WrapIfUnwrapped(err) } - return ValidateSchemaDocument(ast) + return ValidateSchemaDocument(sd) } -func ValidateSchemaDocument(ast *SchemaDocument) (*Schema, error) { +func ValidateSchemaDocument(sd *SchemaDocument) (*Schema, error) { schema := Schema{ Types: map[string]*Definition{}, Directives: map[string]*DirectiveDefinition{}, @@ -26,16 +27,16 @@ func ValidateSchemaDocument(ast *SchemaDocument) (*Schema, error) { Implements: map[string][]*Definition{}, } - for i, def := range ast.Definitions { + for i, def := range sd.Definitions { if schema.Types[def.Name] != nil { return nil, gqlerror.ErrorPosf(def.Position, "Cannot redeclare type %s.", def.Name) } - schema.Types[def.Name] = ast.Definitions[i] + schema.Types[def.Name] = sd.Definitions[i] } - defs := append(DefinitionList{}, ast.Definitions...) + defs := append(DefinitionList{}, sd.Definitions...) - for _, ext := range ast.Extensions { + for _, ext := range sd.Extensions { def := schema.Types[ext.Name] if def == nil { schema.Types[ext.Name] = &Definition{ @@ -79,13 +80,13 @@ func ValidateSchemaDocument(ast *SchemaDocument) (*Schema, error) { } } - for i, dir := range ast.Directives { + for i, dir := range sd.Directives { if schema.Directives[dir.Name] != nil { // While the spec says SDL must not (§3.5) explicitly define builtin // scalars, it may (§3.13) define builtin directives. Here we check for // that, and reject doubly-defined directives otherwise. switch dir.Name { - case "include", "skip", "deprecated", "specifiedBy": // the builtins + case "include", "skip", "deprecated", "specifiedBy", "defer": // the builtins // In principle here we might want to validate that the // directives are the same. But they might not be, if the // server has an older spec than we do. (Plus, validating this @@ -98,16 +99,16 @@ func ValidateSchemaDocument(ast *SchemaDocument) (*Schema, error) { return nil, gqlerror.ErrorPosf(dir.Position, "Cannot redeclare directive %s.", dir.Name) } } - schema.Directives[dir.Name] = ast.Directives[i] + schema.Directives[dir.Name] = sd.Directives[i] } - if len(ast.Schema) > 1 { - return nil, gqlerror.ErrorPosf(ast.Schema[1].Position, "Cannot have multiple schema entry points, consider schema extensions instead.") + if len(sd.Schema) > 1 { + return nil, gqlerror.ErrorPosf(sd.Schema[1].Position, "Cannot have multiple schema entry points, consider schema extensions instead.") } - if len(ast.Schema) == 1 { - schema.Description = ast.Schema[0].Description - for _, entrypoint := range ast.Schema[0].OperationTypes { + if len(sd.Schema) == 1 { + schema.Description = sd.Schema[0].Description + for _, entrypoint := range sd.Schema[0].OperationTypes { def := schema.Types[entrypoint.Type] if def == nil { return nil, gqlerror.ErrorPosf(entrypoint.Position, "Schema root %s refers to a type %s that does not exist.", entrypoint.Operation, entrypoint.Type) @@ -123,7 +124,7 @@ func ValidateSchemaDocument(ast *SchemaDocument) (*Schema, error) { } } - for _, ext := range ast.SchemaExtension { + for _, ext := range sd.SchemaExtension { for _, entrypoint := range ext.OperationTypes { def := schema.Types[entrypoint.Type] if def == nil { @@ -151,7 +152,7 @@ func ValidateSchemaDocument(ast *SchemaDocument) (*Schema, error) { // Inferred root operation type names should be performed only when a `schema` directive is // **not** provided, when it is, `Mutation` and `Subscription` becomes valid types and are not // assigned as a root operation on the schema. - if len(ast.Schema) == 0 { + if len(sd.Schema) == 0 { if schema.Query == nil && schema.Types["Query"] != nil { schema.Query = schema.Types["Query"] } @@ -283,6 +284,9 @@ func validateDefinition(schema *Schema, def *Definition) *gqlerror.Error { return gqlerror.ErrorPosf(def.Position, "%s %s: non-enum value %s.", def.Kind, def.Name, value.Name) } } + if err := validateDirectives(schema, value.Directives, LocationEnumValue, nil); err != nil { + return err + } } case InputObject: if len(def.Fields) == 0 { @@ -358,11 +362,12 @@ func validateDirectives(schema *Schema, dirs DirectiveList, location DirectiveLo if currentDirective != nil && dir.Name == currentDirective.Name { return gqlerror.ErrorPosf(dir.Position, "Directive %s cannot refer to itself.", currentDirective.Name) } - if schema.Directives[dir.Name] == nil { + dirDefinition := schema.Directives[dir.Name] + if dirDefinition == nil { return gqlerror.ErrorPosf(dir.Position, "Undefined directive %s.", dir.Name) } validKind := false - for _, dirLocation := range schema.Directives[dir.Name].Locations { + for _, dirLocation := range dirDefinition.Locations { if dirLocation == location { validKind = true break @@ -371,6 +376,18 @@ func validateDirectives(schema *Schema, dirs DirectiveList, location DirectiveLo if !validKind { return gqlerror.ErrorPosf(dir.Position, "Directive %s is not applicable on %s.", dir.Name, location) } + for _, arg := range dir.Arguments { + if dirDefinition.Arguments.ForName(arg.Name) == nil { + return gqlerror.ErrorPosf(arg.Position, "Undefined argument %s for directive %s.", arg.Name, dir.Name) + } + } + for _, schemaArg := range dirDefinition.Arguments { + if schemaArg.Type.NonNull && schemaArg.DefaultValue == nil { + if arg := dir.Arguments.ForName(schemaArg.Name); arg == nil || arg.Value.Kind == NullValue { + return gqlerror.ErrorPosf(dir.Position, "Argument %s for directive %s cannot be null.", schemaArg.Name, dir.Name) + } + } + } dir.Definition = schema.Directives[dir.Name] } return nil @@ -378,7 +395,7 @@ func validateDirectives(schema *Schema, dirs DirectiveList, location DirectiveLo func validateImplements(schema *Schema, def *Definition, intfName string) *gqlerror.Error { // see validation rules at the bottom of - // https://facebook.github.io/graphql/October2021/#sec-Objects + // https://spec.graphql.org/October2021/#sec-Objects intf := schema.Types[intfName] if intf == nil { return gqlerror.ErrorPosf(def.Position, "Undefined type %s.", strconv.Quote(intfName)) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/schema_test.yml b/vendor/github.com/vektah/gqlparser/v2/validator/schema_test.yml index 7034a4697c..22f125bec4 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/schema_test.yml +++ b/vendor/github.com/vektah/gqlparser/v2/validator/schema_test.yml @@ -80,6 +80,15 @@ object types: message: 'Name "__id" must not begin with "__", which is reserved by GraphQL introspection.' locations: [{line: 2, column: 3}] + - name: field argument list must not be empty + input: | + type FooBar { + foo(): ID + } + error: + message: 'expected at least one definition, found )' + locations: [{line: 2, column: 7}] + - name: check reserved names on type field argument input: | type FooBar { @@ -528,7 +537,16 @@ directives: directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT - - name: must be declared + - name: must be declared (type) + input: | + type User @foo { + name: String + } + error: + message: "Undefined directive foo." + locations: [{line: 1, column: 12}] + + - name: must be declared (field) input: | type User { name: String @foo @@ -537,6 +555,15 @@ directives: message: "Undefined directive foo." locations: [{line: 2, column: 17}] + - name: must be declared (enum) + input: | + enum Unit { + METER @foo + } + error: + message: "Undefined directive foo." + locations: [{line: 2, column: 10}] + - name: cannot be self-referential input: | directive @A(foo: Int! @A) on FIELD_DEFINITION @@ -604,6 +631,32 @@ directives: type P { name: String @testField } interface I { id: ID @testField } + - name: Invalid directive argument not allowed + input: | + directive @foo(bla: Int!) on FIELD_DEFINITION + type P {f: Int @foo(foobla: 11)} + + error: + message: 'Undefined argument foobla for directive foo.' + locations: [{line: 2, column: 21}] + + - name: non-null argument must be provided + input: | + directive @foo(bla: Int!) on FIELD_DEFINITION + type P {f: Int @foo } + + error: + message: 'Argument bla for directive foo cannot be null.' + locations: [{line: 2, column: 17}] + + - name: non-null argument must not be null + input: | + directive @foo(bla: Int!) on FIELD_DEFINITION + type P {f: Int @foo(bla: null) } + + error: + message: 'Argument bla for directive foo cannot be null.' + locations: [{line: 2, column: 17}] entry points: - name: multiple schema entry points diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/validator.go b/vendor/github.com/vektah/gqlparser/v2/validator/validator.go index 34bf93db3d..b4f37ce276 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/validator.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/validator.go @@ -1,6 +1,7 @@ package validator import ( + //nolint:revive . "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/gqlerror" ) @@ -24,7 +25,15 @@ func AddRule(name string, f ruleFunc) { func Validate(schema *Schema, doc *QueryDocument) gqlerror.List { var errs gqlerror.List - + if schema == nil { + errs = append(errs, gqlerror.Errorf("cannot validate as Schema is nil")) + } + if doc == nil { + errs = append(errs, gqlerror.Errorf("cannot validate as QueryDocument is nil")) + } + if len(errs) > 0 { + return errs + } observers := &Events{} for i := range rules { rule := rules[i] diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/vars.go b/vendor/github.com/vektah/gqlparser/v2/validator/vars.go index 8dbb05bc15..c386b6b946 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/vars.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/vars.go @@ -11,7 +11,7 @@ import ( "github.com/vektah/gqlparser/v2/gqlerror" ) -var UnexpectedType = fmt.Errorf("Unexpected Type") +var ErrUnexpectedType = fmt.Errorf("Unexpected Type") // VariableValues coerces and validates variable values func VariableValues(schema *ast.Schema, op *ast.OperationDefinition, variables map[string]interface{}) (map[string]interface{}, error) { @@ -53,8 +53,8 @@ func VariableValues(schema *ast.Schema, op *ast.OperationDefinition, variables m } else { rv := reflect.ValueOf(val) - jsonNumber, isJsonNumber := val.(json.Number) - if isJsonNumber { + jsonNumber, isJSONNumber := val.(json.Number) + if isJSONNumber { if v.Type.NamedType == "Int" { n, err := jsonNumber.Int64() if err != nil { @@ -67,7 +67,6 @@ func VariableValues(schema *ast.Schema, op *ast.OperationDefinition, variables m return nil, gqlerror.ErrorPathf(validator.path, "cannot use value %f as %s", f, v.Type.NamedType) } rv = reflect.ValueOf(f) - } } if rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface { @@ -222,7 +221,7 @@ func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) (reflec if fieldDef.Type.NonNull && field.IsNil() { return val, gqlerror.ErrorPathf(v.path, "cannot be null") } - //allow null object field and skip it + // allow null object field and skip it if !fieldDef.Type.NonNull && field.IsNil() { continue } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/walk.go b/vendor/github.com/vektah/gqlparser/v2/validator/walk.go index 6ee69e4c2e..d3140746fb 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/walk.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/walk.go @@ -22,27 +22,35 @@ type Events struct { func (o *Events) OnOperation(f func(walker *Walker, operation *ast.OperationDefinition)) { o.operationVisitor = append(o.operationVisitor, f) } + func (o *Events) OnField(f func(walker *Walker, field *ast.Field)) { o.field = append(o.field, f) } + func (o *Events) OnFragment(f func(walker *Walker, fragment *ast.FragmentDefinition)) { o.fragment = append(o.fragment, f) } + func (o *Events) OnInlineFragment(f func(walker *Walker, inlineFragment *ast.InlineFragment)) { o.inlineFragment = append(o.inlineFragment, f) } + func (o *Events) OnFragmentSpread(f func(walker *Walker, fragmentSpread *ast.FragmentSpread)) { o.fragmentSpread = append(o.fragmentSpread, f) } + func (o *Events) OnDirective(f func(walker *Walker, directive *ast.Directive)) { o.directive = append(o.directive, f) } + func (o *Events) OnDirectiveList(f func(walker *Walker, directives []*ast.Directive)) { o.directiveList = append(o.directiveList, f) } + func (o *Events) OnValue(f func(walker *Walker, value *ast.Value)) { o.value = append(o.value, f) } + func (o *Events) OnVariable(f func(walker *Walker, variable *ast.VariableDefinition)) { o.variable = append(o.variable, f) } @@ -277,7 +285,7 @@ func (w *Walker) walkSelection(parentDef *ast.Definition, it ast.Selection) { w.walkDirectives(nextParentDef, it.Directives, ast.LocationFragmentSpread) if def != nil && !w.validatedFragmentSpreads[def.Name] { - // prevent inifinite recursion + // prevent infinite recursion w.validatedFragmentSpreads[def.Name] = true w.walkSelectionSet(nextParentDef, def.SelectionSet) } diff --git a/vendor/go.mozilla.org/pkcs7/Makefile b/vendor/go.mozilla.org/pkcs7/Makefile deleted file mode 100644 index 47c73b8684..0000000000 --- a/vendor/go.mozilla.org/pkcs7/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -all: vet staticcheck test - -test: - go test -covermode=count -coverprofile=coverage.out . - -showcoverage: test - go tool cover -html=coverage.out - -vet: - go vet . - -lint: - golint . - -staticcheck: - staticcheck . - -gettools: - go get -u honnef.co/go/tools/... - go get -u golang.org/x/lint/golint diff --git a/vendor/go.mozilla.org/pkcs7/README.md b/vendor/go.mozilla.org/pkcs7/README.md deleted file mode 100644 index a55d117c68..0000000000 --- a/vendor/go.mozilla.org/pkcs7/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# pkcs7 - -[![GoDoc](https://godoc.org/go.mozilla.org/pkcs7?status.svg)](https://godoc.org/go.mozilla.org/pkcs7) -[![Build Status](https://github.com/mozilla-services/pkcs7/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/mozilla-services/pkcs7/actions/workflows/ci.yml?query=branch%3Amaster+event%3Apush) - -pkcs7 implements parsing and creating signed and enveloped messages. - -```go -package main - -import ( - "bytes" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "fmt" - "os" - - "go.mozilla.org/pkcs7" -) - -func SignAndDetach(content []byte, cert *x509.Certificate, privkey *rsa.PrivateKey) (signed []byte, err error) { - toBeSigned, err := NewSignedData(content) - if err != nil { - err = fmt.Errorf("Cannot initialize signed data: %s", err) - return - } - if err = toBeSigned.AddSigner(cert, privkey, SignerInfoConfig{}); err != nil { - err = fmt.Errorf("Cannot add signer: %s", err) - return - } - - // Detach signature, omit if you want an embedded signature - toBeSigned.Detach() - - signed, err = toBeSigned.Finish() - if err != nil { - err = fmt.Errorf("Cannot finish signing data: %s", err) - return - } - - // Verify the signature - pem.Encode(os.Stdout, &pem.Block{Type: "PKCS7", Bytes: signed}) - p7, err := pkcs7.Parse(signed) - if err != nil { - err = fmt.Errorf("Cannot parse our signed data: %s", err) - return - } - - // since the signature was detached, reattach the content here - p7.Content = content - - if bytes.Compare(content, p7.Content) != 0 { - err = fmt.Errorf("Our content was not in the parsed data:\n\tExpected: %s\n\tActual: %s", content, p7.Content) - return - } - if err = p7.Verify(); err != nil { - err = fmt.Errorf("Cannot verify our signed data: %s", err) - return - } - - return signed, nil -} -``` - - - -## Credits -This is a fork of [fullsailor/pkcs7](https://github.com/fullsailor/pkcs7) diff --git a/vendor/go.mozilla.org/pkcs7/ber.go b/vendor/go.mozilla.org/pkcs7/ber.go deleted file mode 100644 index 73da024a0d..0000000000 --- a/vendor/go.mozilla.org/pkcs7/ber.go +++ /dev/null @@ -1,271 +0,0 @@ -package pkcs7 - -import ( - "bytes" - "errors" -) - -var encodeIndent = 0 - -type asn1Object interface { - EncodeTo(writer *bytes.Buffer) error -} - -type asn1Structured struct { - tagBytes []byte - content []asn1Object -} - -func (s asn1Structured) EncodeTo(out *bytes.Buffer) error { - //fmt.Printf("%s--> tag: % X\n", strings.Repeat("| ", encodeIndent), s.tagBytes) - encodeIndent++ - inner := new(bytes.Buffer) - for _, obj := range s.content { - err := obj.EncodeTo(inner) - if err != nil { - return err - } - } - encodeIndent-- - out.Write(s.tagBytes) - encodeLength(out, inner.Len()) - out.Write(inner.Bytes()) - return nil -} - -type asn1Primitive struct { - tagBytes []byte - length int - content []byte -} - -func (p asn1Primitive) EncodeTo(out *bytes.Buffer) error { - _, err := out.Write(p.tagBytes) - if err != nil { - return err - } - if err = encodeLength(out, p.length); err != nil { - return err - } - //fmt.Printf("%s--> tag: % X length: %d\n", strings.Repeat("| ", encodeIndent), p.tagBytes, p.length) - //fmt.Printf("%s--> content length: %d\n", strings.Repeat("| ", encodeIndent), len(p.content)) - out.Write(p.content) - - return nil -} - -func ber2der(ber []byte) ([]byte, error) { - if len(ber) == 0 { - return nil, errors.New("ber2der: input ber is empty") - } - //fmt.Printf("--> ber2der: Transcoding %d bytes\n", len(ber)) - out := new(bytes.Buffer) - - obj, _, err := readObject(ber, 0) - if err != nil { - return nil, err - } - obj.EncodeTo(out) - - // if offset < len(ber) { - // return nil, fmt.Errorf("ber2der: Content longer than expected. Got %d, expected %d", offset, len(ber)) - //} - - return out.Bytes(), nil -} - -// encodes lengths that are longer than 127 into string of bytes -func marshalLongLength(out *bytes.Buffer, i int) (err error) { - n := lengthLength(i) - - for ; n > 0; n-- { - err = out.WriteByte(byte(i >> uint((n-1)*8))) - if err != nil { - return - } - } - - return nil -} - -// computes the byte length of an encoded length value -func lengthLength(i int) (numBytes int) { - numBytes = 1 - for i > 255 { - numBytes++ - i >>= 8 - } - return -} - -// encodes the length in DER format -// If the length fits in 7 bits, the value is encoded directly. -// -// Otherwise, the number of bytes to encode the length is first determined. -// This number is likely to be 4 or less for a 32bit length. This number is -// added to 0x80. The length is encoded in big endian encoding follow after -// -// Examples: -// length | byte 1 | bytes n -// 0 | 0x00 | - -// 120 | 0x78 | - -// 200 | 0x81 | 0xC8 -// 500 | 0x82 | 0x01 0xF4 -// -func encodeLength(out *bytes.Buffer, length int) (err error) { - if length >= 128 { - l := lengthLength(length) - err = out.WriteByte(0x80 | byte(l)) - if err != nil { - return - } - err = marshalLongLength(out, length) - if err != nil { - return - } - } else { - err = out.WriteByte(byte(length)) - if err != nil { - return - } - } - return -} - -func readObject(ber []byte, offset int) (asn1Object, int, error) { - berLen := len(ber) - if offset >= berLen { - return nil, 0, errors.New("ber2der: offset is after end of ber data") - } - tagStart := offset - b := ber[offset] - offset++ - if offset >= berLen { - return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") - } - tag := b & 0x1F // last 5 bits - if tag == 0x1F { - tag = 0 - for ber[offset] >= 0x80 { - tag = tag*128 + ber[offset] - 0x80 - offset++ - if offset > berLen { - return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") - } - } - // jvehent 20170227: this doesn't appear to be used anywhere... - //tag = tag*128 + ber[offset] - 0x80 - offset++ - if offset > berLen { - return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") - } - } - tagEnd := offset - - kind := b & 0x20 - if kind == 0 { - debugprint("--> Primitive\n") - } else { - debugprint("--> Constructed\n") - } - // read length - var length int - l := ber[offset] - offset++ - if offset > berLen { - return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") - } - indefinite := false - if l > 0x80 { - numberOfBytes := (int)(l & 0x7F) - if numberOfBytes > 4 { // int is only guaranteed to be 32bit - return nil, 0, errors.New("ber2der: BER tag length too long") - } - if numberOfBytes == 4 && (int)(ber[offset]) > 0x7F { - return nil, 0, errors.New("ber2der: BER tag length is negative") - } - if (int)(ber[offset]) == 0x0 { - return nil, 0, errors.New("ber2der: BER tag length has leading zero") - } - debugprint("--> (compute length) indicator byte: %x\n", l) - debugprint("--> (compute length) length bytes: % X\n", ber[offset:offset+numberOfBytes]) - for i := 0; i < numberOfBytes; i++ { - length = length*256 + (int)(ber[offset]) - offset++ - if offset > berLen { - return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") - } - } - } else if l == 0x80 { - indefinite = true - } else { - length = (int)(l) - } - if length < 0 { - return nil, 0, errors.New("ber2der: invalid negative value found in BER tag length") - } - //fmt.Printf("--> length : %d\n", length) - contentEnd := offset + length - if contentEnd > len(ber) { - return nil, 0, errors.New("ber2der: BER tag length is more than available data") - } - debugprint("--> content start : %d\n", offset) - debugprint("--> content end : %d\n", contentEnd) - debugprint("--> content : % X\n", ber[offset:contentEnd]) - var obj asn1Object - if indefinite && kind == 0 { - return nil, 0, errors.New("ber2der: Indefinite form tag must have constructed encoding") - } - if kind == 0 { - obj = asn1Primitive{ - tagBytes: ber[tagStart:tagEnd], - length: length, - content: ber[offset:contentEnd], - } - } else { - var subObjects []asn1Object - for (offset < contentEnd) || indefinite { - var subObj asn1Object - var err error - subObj, offset, err = readObject(ber, offset) - if err != nil { - return nil, 0, err - } - subObjects = append(subObjects, subObj) - - if indefinite { - terminated, err := isIndefiniteTermination(ber, offset) - if err != nil { - return nil, 0, err - } - - if terminated { - break - } - } - } - obj = asn1Structured{ - tagBytes: ber[tagStart:tagEnd], - content: subObjects, - } - } - - // Apply indefinite form length with 0x0000 terminator. - if indefinite { - contentEnd = offset + 2 - } - - return obj, contentEnd, nil -} - -func isIndefiniteTermination(ber []byte, offset int) (bool, error) { - if len(ber) - offset < 2 { - return false, errors.New("ber2der: Invalid BER format") - } - - return bytes.Index(ber[offset:], []byte{0x0, 0x0}) == 0, nil -} - -func debugprint(format string, a ...interface{}) { - //fmt.Printf(format, a) -} diff --git a/vendor/go.mozilla.org/pkcs7/decrypt.go b/vendor/go.mozilla.org/pkcs7/decrypt.go deleted file mode 100644 index 0d088d6287..0000000000 --- a/vendor/go.mozilla.org/pkcs7/decrypt.go +++ /dev/null @@ -1,177 +0,0 @@ -package pkcs7 - -import ( - "bytes" - "crypto" - "crypto/aes" - "crypto/cipher" - "crypto/des" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/asn1" - "errors" - "fmt" -) - -// ErrUnsupportedAlgorithm tells you when our quick dev assumptions have failed -var ErrUnsupportedAlgorithm = errors.New("pkcs7: cannot decrypt data: only RSA, DES, DES-EDE3, AES-256-CBC and AES-128-GCM supported") - -// ErrNotEncryptedContent is returned when attempting to Decrypt data that is not encrypted data -var ErrNotEncryptedContent = errors.New("pkcs7: content data is a decryptable data type") - -// Decrypt decrypts encrypted content info for recipient cert and private key -func (p7 *PKCS7) Decrypt(cert *x509.Certificate, pkey crypto.PrivateKey) ([]byte, error) { - data, ok := p7.raw.(envelopedData) - if !ok { - return nil, ErrNotEncryptedContent - } - recipient := selectRecipientForCertificate(data.RecipientInfos, cert) - if recipient.EncryptedKey == nil { - return nil, errors.New("pkcs7: no enveloped recipient for provided certificate") - } - switch pkey := pkey.(type) { - case *rsa.PrivateKey: - var contentKey []byte - contentKey, err := rsa.DecryptPKCS1v15(rand.Reader, pkey, recipient.EncryptedKey) - if err != nil { - return nil, err - } - return data.EncryptedContentInfo.decrypt(contentKey) - } - return nil, ErrUnsupportedAlgorithm -} - -// DecryptUsingPSK decrypts encrypted data using caller provided -// pre-shared secret -func (p7 *PKCS7) DecryptUsingPSK(key []byte) ([]byte, error) { - data, ok := p7.raw.(encryptedData) - if !ok { - return nil, ErrNotEncryptedContent - } - return data.EncryptedContentInfo.decrypt(key) -} - -func (eci encryptedContentInfo) decrypt(key []byte) ([]byte, error) { - alg := eci.ContentEncryptionAlgorithm.Algorithm - if !alg.Equal(OIDEncryptionAlgorithmDESCBC) && - !alg.Equal(OIDEncryptionAlgorithmDESEDE3CBC) && - !alg.Equal(OIDEncryptionAlgorithmAES256CBC) && - !alg.Equal(OIDEncryptionAlgorithmAES128CBC) && - !alg.Equal(OIDEncryptionAlgorithmAES128GCM) && - !alg.Equal(OIDEncryptionAlgorithmAES256GCM) { - fmt.Printf("Unsupported Content Encryption Algorithm: %s\n", alg) - return nil, ErrUnsupportedAlgorithm - } - - // EncryptedContent can either be constructed of multple OCTET STRINGs - // or _be_ a tagged OCTET STRING - var cyphertext []byte - if eci.EncryptedContent.IsCompound { - // Complex case to concat all of the children OCTET STRINGs - var buf bytes.Buffer - cypherbytes := eci.EncryptedContent.Bytes - for { - var part []byte - cypherbytes, _ = asn1.Unmarshal(cypherbytes, &part) - buf.Write(part) - if cypherbytes == nil { - break - } - } - cyphertext = buf.Bytes() - } else { - // Simple case, the bytes _are_ the cyphertext - cyphertext = eci.EncryptedContent.Bytes - } - - var block cipher.Block - var err error - - switch { - case alg.Equal(OIDEncryptionAlgorithmDESCBC): - block, err = des.NewCipher(key) - case alg.Equal(OIDEncryptionAlgorithmDESEDE3CBC): - block, err = des.NewTripleDESCipher(key) - case alg.Equal(OIDEncryptionAlgorithmAES256CBC), alg.Equal(OIDEncryptionAlgorithmAES256GCM): - fallthrough - case alg.Equal(OIDEncryptionAlgorithmAES128GCM), alg.Equal(OIDEncryptionAlgorithmAES128CBC): - block, err = aes.NewCipher(key) - } - - if err != nil { - return nil, err - } - - if alg.Equal(OIDEncryptionAlgorithmAES128GCM) || alg.Equal(OIDEncryptionAlgorithmAES256GCM) { - params := aesGCMParameters{} - paramBytes := eci.ContentEncryptionAlgorithm.Parameters.Bytes - - _, err := asn1.Unmarshal(paramBytes, ¶ms) - if err != nil { - return nil, err - } - - gcm, err := cipher.NewGCM(block) - if err != nil { - return nil, err - } - - if len(params.Nonce) != gcm.NonceSize() { - return nil, errors.New("pkcs7: encryption algorithm parameters are incorrect") - } - if params.ICVLen != gcm.Overhead() { - return nil, errors.New("pkcs7: encryption algorithm parameters are incorrect") - } - - plaintext, err := gcm.Open(nil, params.Nonce, cyphertext, nil) - if err != nil { - return nil, err - } - - return plaintext, nil - } - - iv := eci.ContentEncryptionAlgorithm.Parameters.Bytes - if len(iv) != block.BlockSize() { - return nil, errors.New("pkcs7: encryption algorithm parameters are malformed") - } - mode := cipher.NewCBCDecrypter(block, iv) - plaintext := make([]byte, len(cyphertext)) - mode.CryptBlocks(plaintext, cyphertext) - if plaintext, err = unpad(plaintext, mode.BlockSize()); err != nil { - return nil, err - } - return plaintext, nil -} - -func unpad(data []byte, blocklen int) ([]byte, error) { - if blocklen < 1 { - return nil, fmt.Errorf("invalid blocklen %d", blocklen) - } - if len(data)%blocklen != 0 || len(data) == 0 { - return nil, fmt.Errorf("invalid data len %d", len(data)) - } - - // the last byte is the length of padding - padlen := int(data[len(data)-1]) - - // check padding integrity, all bytes should be the same - pad := data[len(data)-padlen:] - for _, padbyte := range pad { - if padbyte != byte(padlen) { - return nil, errors.New("invalid padding") - } - } - - return data[:len(data)-padlen], nil -} - -func selectRecipientForCertificate(recipients []recipientInfo, cert *x509.Certificate) recipientInfo { - for _, recp := range recipients { - if isCertMatchForIssuerAndSerial(cert, recp.IssuerAndSerialNumber) { - return recp - } - } - return recipientInfo{} -} diff --git a/vendor/go.mozilla.org/pkcs7/encrypt.go b/vendor/go.mozilla.org/pkcs7/encrypt.go deleted file mode 100644 index 6b2655708c..0000000000 --- a/vendor/go.mozilla.org/pkcs7/encrypt.go +++ /dev/null @@ -1,399 +0,0 @@ -package pkcs7 - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/des" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "errors" - "fmt" -) - -type envelopedData struct { - Version int - RecipientInfos []recipientInfo `asn1:"set"` - EncryptedContentInfo encryptedContentInfo -} - -type encryptedData struct { - Version int - EncryptedContentInfo encryptedContentInfo -} - -type recipientInfo struct { - Version int - IssuerAndSerialNumber issuerAndSerial - KeyEncryptionAlgorithm pkix.AlgorithmIdentifier - EncryptedKey []byte -} - -type encryptedContentInfo struct { - ContentType asn1.ObjectIdentifier - ContentEncryptionAlgorithm pkix.AlgorithmIdentifier - EncryptedContent asn1.RawValue `asn1:"tag:0,optional"` -} - -const ( - // EncryptionAlgorithmDESCBC is the DES CBC encryption algorithm - EncryptionAlgorithmDESCBC = iota - - // EncryptionAlgorithmAES128CBC is the AES 128 bits with CBC encryption algorithm - // Avoid this algorithm unless required for interoperability; use AES GCM instead. - EncryptionAlgorithmAES128CBC - - // EncryptionAlgorithmAES256CBC is the AES 256 bits with CBC encryption algorithm - // Avoid this algorithm unless required for interoperability; use AES GCM instead. - EncryptionAlgorithmAES256CBC - - // EncryptionAlgorithmAES128GCM is the AES 128 bits with GCM encryption algorithm - EncryptionAlgorithmAES128GCM - - // EncryptionAlgorithmAES256GCM is the AES 256 bits with GCM encryption algorithm - EncryptionAlgorithmAES256GCM -) - -// ContentEncryptionAlgorithm determines the algorithm used to encrypt the -// plaintext message. Change the value of this variable to change which -// algorithm is used in the Encrypt() function. -var ContentEncryptionAlgorithm = EncryptionAlgorithmDESCBC - -// ErrUnsupportedEncryptionAlgorithm is returned when attempting to encrypt -// content with an unsupported algorithm. -var ErrUnsupportedEncryptionAlgorithm = errors.New("pkcs7: cannot encrypt content: only DES-CBC, AES-CBC, and AES-GCM supported") - -// ErrPSKNotProvided is returned when attempting to encrypt -// using a PSK without actually providing the PSK. -var ErrPSKNotProvided = errors.New("pkcs7: cannot encrypt content: PSK not provided") - -const nonceSize = 12 - -type aesGCMParameters struct { - Nonce []byte `asn1:"tag:4"` - ICVLen int -} - -func encryptAESGCM(content []byte, key []byte) ([]byte, *encryptedContentInfo, error) { - var keyLen int - var algID asn1.ObjectIdentifier - switch ContentEncryptionAlgorithm { - case EncryptionAlgorithmAES128GCM: - keyLen = 16 - algID = OIDEncryptionAlgorithmAES128GCM - case EncryptionAlgorithmAES256GCM: - keyLen = 32 - algID = OIDEncryptionAlgorithmAES256GCM - default: - return nil, nil, fmt.Errorf("invalid ContentEncryptionAlgorithm in encryptAESGCM: %d", ContentEncryptionAlgorithm) - } - if key == nil { - // Create AES key - key = make([]byte, keyLen) - - _, err := rand.Read(key) - if err != nil { - return nil, nil, err - } - } - - // Create nonce - nonce := make([]byte, nonceSize) - - _, err := rand.Read(nonce) - if err != nil { - return nil, nil, err - } - - // Encrypt content - block, err := aes.NewCipher(key) - if err != nil { - return nil, nil, err - } - - gcm, err := cipher.NewGCM(block) - if err != nil { - return nil, nil, err - } - - ciphertext := gcm.Seal(nil, nonce, content, nil) - - // Prepare ASN.1 Encrypted Content Info - paramSeq := aesGCMParameters{ - Nonce: nonce, - ICVLen: gcm.Overhead(), - } - - paramBytes, err := asn1.Marshal(paramSeq) - if err != nil { - return nil, nil, err - } - - eci := encryptedContentInfo{ - ContentType: OIDData, - ContentEncryptionAlgorithm: pkix.AlgorithmIdentifier{ - Algorithm: algID, - Parameters: asn1.RawValue{ - Tag: asn1.TagSequence, - Bytes: paramBytes, - }, - }, - EncryptedContent: marshalEncryptedContent(ciphertext), - } - - return key, &eci, nil -} - -func encryptDESCBC(content []byte, key []byte) ([]byte, *encryptedContentInfo, error) { - if key == nil { - // Create DES key - key = make([]byte, 8) - - _, err := rand.Read(key) - if err != nil { - return nil, nil, err - } - } - - // Create CBC IV - iv := make([]byte, des.BlockSize) - _, err := rand.Read(iv) - if err != nil { - return nil, nil, err - } - - // Encrypt padded content - block, err := des.NewCipher(key) - if err != nil { - return nil, nil, err - } - mode := cipher.NewCBCEncrypter(block, iv) - plaintext, err := pad(content, mode.BlockSize()) - if err != nil { - return nil, nil, err - } - cyphertext := make([]byte, len(plaintext)) - mode.CryptBlocks(cyphertext, plaintext) - - // Prepare ASN.1 Encrypted Content Info - eci := encryptedContentInfo{ - ContentType: OIDData, - ContentEncryptionAlgorithm: pkix.AlgorithmIdentifier{ - Algorithm: OIDEncryptionAlgorithmDESCBC, - Parameters: asn1.RawValue{Tag: 4, Bytes: iv}, - }, - EncryptedContent: marshalEncryptedContent(cyphertext), - } - - return key, &eci, nil -} - -func encryptAESCBC(content []byte, key []byte) ([]byte, *encryptedContentInfo, error) { - var keyLen int - var algID asn1.ObjectIdentifier - switch ContentEncryptionAlgorithm { - case EncryptionAlgorithmAES128CBC: - keyLen = 16 - algID = OIDEncryptionAlgorithmAES128CBC - case EncryptionAlgorithmAES256CBC: - keyLen = 32 - algID = OIDEncryptionAlgorithmAES256CBC - default: - return nil, nil, fmt.Errorf("invalid ContentEncryptionAlgorithm in encryptAESCBC: %d", ContentEncryptionAlgorithm) - } - - if key == nil { - // Create AES key - key = make([]byte, keyLen) - - _, err := rand.Read(key) - if err != nil { - return nil, nil, err - } - } - - // Create CBC IV - iv := make([]byte, aes.BlockSize) - _, err := rand.Read(iv) - if err != nil { - return nil, nil, err - } - - // Encrypt padded content - block, err := aes.NewCipher(key) - if err != nil { - return nil, nil, err - } - mode := cipher.NewCBCEncrypter(block, iv) - plaintext, err := pad(content, mode.BlockSize()) - if err != nil { - return nil, nil, err - } - cyphertext := make([]byte, len(plaintext)) - mode.CryptBlocks(cyphertext, plaintext) - - // Prepare ASN.1 Encrypted Content Info - eci := encryptedContentInfo{ - ContentType: OIDData, - ContentEncryptionAlgorithm: pkix.AlgorithmIdentifier{ - Algorithm: algID, - Parameters: asn1.RawValue{Tag: 4, Bytes: iv}, - }, - EncryptedContent: marshalEncryptedContent(cyphertext), - } - - return key, &eci, nil -} - -// Encrypt creates and returns an envelope data PKCS7 structure with encrypted -// recipient keys for each recipient public key. -// -// The algorithm used to perform encryption is determined by the current value -// of the global ContentEncryptionAlgorithm package variable. By default, the -// value is EncryptionAlgorithmDESCBC. To use a different algorithm, change the -// value before calling Encrypt(). For example: -// -// ContentEncryptionAlgorithm = EncryptionAlgorithmAES128GCM -// -// TODO(fullsailor): Add support for encrypting content with other algorithms -func Encrypt(content []byte, recipients []*x509.Certificate) ([]byte, error) { - var eci *encryptedContentInfo - var key []byte - var err error - - // Apply chosen symmetric encryption method - switch ContentEncryptionAlgorithm { - case EncryptionAlgorithmDESCBC: - key, eci, err = encryptDESCBC(content, nil) - case EncryptionAlgorithmAES128CBC: - fallthrough - case EncryptionAlgorithmAES256CBC: - key, eci, err = encryptAESCBC(content, nil) - case EncryptionAlgorithmAES128GCM: - fallthrough - case EncryptionAlgorithmAES256GCM: - key, eci, err = encryptAESGCM(content, nil) - - default: - return nil, ErrUnsupportedEncryptionAlgorithm - } - - if err != nil { - return nil, err - } - - // Prepare each recipient's encrypted cipher key - recipientInfos := make([]recipientInfo, len(recipients)) - for i, recipient := range recipients { - encrypted, err := encryptKey(key, recipient) - if err != nil { - return nil, err - } - ias, err := cert2issuerAndSerial(recipient) - if err != nil { - return nil, err - } - info := recipientInfo{ - Version: 0, - IssuerAndSerialNumber: ias, - KeyEncryptionAlgorithm: pkix.AlgorithmIdentifier{ - Algorithm: OIDEncryptionAlgorithmRSA, - }, - EncryptedKey: encrypted, - } - recipientInfos[i] = info - } - - // Prepare envelope content - envelope := envelopedData{ - EncryptedContentInfo: *eci, - Version: 0, - RecipientInfos: recipientInfos, - } - innerContent, err := asn1.Marshal(envelope) - if err != nil { - return nil, err - } - - // Prepare outer payload structure - wrapper := contentInfo{ - ContentType: OIDEnvelopedData, - Content: asn1.RawValue{Class: 2, Tag: 0, IsCompound: true, Bytes: innerContent}, - } - - return asn1.Marshal(wrapper) -} - -// EncryptUsingPSK creates and returns an encrypted data PKCS7 structure, -// encrypted using caller provided pre-shared secret. -func EncryptUsingPSK(content []byte, key []byte) ([]byte, error) { - var eci *encryptedContentInfo - var err error - - if key == nil { - return nil, ErrPSKNotProvided - } - - // Apply chosen symmetric encryption method - switch ContentEncryptionAlgorithm { - case EncryptionAlgorithmDESCBC: - _, eci, err = encryptDESCBC(content, key) - - case EncryptionAlgorithmAES128GCM: - fallthrough - case EncryptionAlgorithmAES256GCM: - _, eci, err = encryptAESGCM(content, key) - - default: - return nil, ErrUnsupportedEncryptionAlgorithm - } - - if err != nil { - return nil, err - } - - // Prepare encrypted-data content - ed := encryptedData{ - Version: 0, - EncryptedContentInfo: *eci, - } - innerContent, err := asn1.Marshal(ed) - if err != nil { - return nil, err - } - - // Prepare outer payload structure - wrapper := contentInfo{ - ContentType: OIDEncryptedData, - Content: asn1.RawValue{Class: 2, Tag: 0, IsCompound: true, Bytes: innerContent}, - } - - return asn1.Marshal(wrapper) -} - -func marshalEncryptedContent(content []byte) asn1.RawValue { - asn1Content, _ := asn1.Marshal(content) - return asn1.RawValue{Tag: 0, Class: 2, Bytes: asn1Content, IsCompound: true} -} - -func encryptKey(key []byte, recipient *x509.Certificate) ([]byte, error) { - if pub := recipient.PublicKey.(*rsa.PublicKey); pub != nil { - return rsa.EncryptPKCS1v15(rand.Reader, pub, key) - } - return nil, ErrUnsupportedAlgorithm -} - -func pad(data []byte, blocklen int) ([]byte, error) { - if blocklen < 1 { - return nil, fmt.Errorf("invalid blocklen %d", blocklen) - } - padlen := blocklen - (len(data) % blocklen) - if padlen == 0 { - padlen = blocklen - } - pad := bytes.Repeat([]byte{byte(padlen)}, padlen) - return append(data, pad...), nil -} diff --git a/vendor/go.mozilla.org/pkcs7/pkcs7.go b/vendor/go.mozilla.org/pkcs7/pkcs7.go deleted file mode 100644 index ccc6cc6dfe..0000000000 --- a/vendor/go.mozilla.org/pkcs7/pkcs7.go +++ /dev/null @@ -1,291 +0,0 @@ -// Package pkcs7 implements parsing and generation of some PKCS#7 structures. -package pkcs7 - -import ( - "bytes" - "crypto" - "crypto/dsa" - "crypto/ecdsa" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "errors" - "fmt" - "sort" - - _ "crypto/sha1" // for crypto.SHA1 -) - -// PKCS7 Represents a PKCS7 structure -type PKCS7 struct { - Content []byte - Certificates []*x509.Certificate - CRLs []pkix.CertificateList - Signers []signerInfo - raw interface{} -} - -type contentInfo struct { - ContentType asn1.ObjectIdentifier - Content asn1.RawValue `asn1:"explicit,optional,tag:0"` -} - -// ErrUnsupportedContentType is returned when a PKCS7 content is not supported. -// Currently only Data (1.2.840.113549.1.7.1), Signed Data (1.2.840.113549.1.7.2), -// and Enveloped Data are supported (1.2.840.113549.1.7.3) -var ErrUnsupportedContentType = errors.New("pkcs7: cannot parse data: unimplemented content type") - -type unsignedData []byte - -var ( - // Signed Data OIDs - OIDData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1} - OIDSignedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2} - OIDEnvelopedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 3} - OIDEncryptedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 6} - OIDAttributeContentType = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 3} - OIDAttributeMessageDigest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 4} - OIDAttributeSigningTime = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 5} - - // Digest Algorithms - OIDDigestAlgorithmSHA1 = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26} - OIDDigestAlgorithmSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} - OIDDigestAlgorithmSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} - OIDDigestAlgorithmSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3} - - OIDDigestAlgorithmDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1} - OIDDigestAlgorithmDSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3} - - OIDDigestAlgorithmECDSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} - OIDDigestAlgorithmECDSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} - OIDDigestAlgorithmECDSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} - OIDDigestAlgorithmECDSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} - - // Signature Algorithms - OIDEncryptionAlgorithmRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} - OIDEncryptionAlgorithmRSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} - OIDEncryptionAlgorithmRSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} - OIDEncryptionAlgorithmRSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} - OIDEncryptionAlgorithmRSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} - - OIDEncryptionAlgorithmECDSAP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} - OIDEncryptionAlgorithmECDSAP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} - OIDEncryptionAlgorithmECDSAP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} - - // Encryption Algorithms - OIDEncryptionAlgorithmDESCBC = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 7} - OIDEncryptionAlgorithmDESEDE3CBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 3, 7} - OIDEncryptionAlgorithmAES256CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42} - OIDEncryptionAlgorithmAES128GCM = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 6} - OIDEncryptionAlgorithmAES128CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2} - OIDEncryptionAlgorithmAES256GCM = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 46} -) - -func getHashForOID(oid asn1.ObjectIdentifier) (crypto.Hash, error) { - switch { - case oid.Equal(OIDDigestAlgorithmSHA1), oid.Equal(OIDDigestAlgorithmECDSASHA1), - oid.Equal(OIDDigestAlgorithmDSA), oid.Equal(OIDDigestAlgorithmDSASHA1), - oid.Equal(OIDEncryptionAlgorithmRSA): - return crypto.SHA1, nil - case oid.Equal(OIDDigestAlgorithmSHA256), oid.Equal(OIDDigestAlgorithmECDSASHA256): - return crypto.SHA256, nil - case oid.Equal(OIDDigestAlgorithmSHA384), oid.Equal(OIDDigestAlgorithmECDSASHA384): - return crypto.SHA384, nil - case oid.Equal(OIDDigestAlgorithmSHA512), oid.Equal(OIDDigestAlgorithmECDSASHA512): - return crypto.SHA512, nil - } - return crypto.Hash(0), ErrUnsupportedAlgorithm -} - -// getDigestOIDForSignatureAlgorithm takes an x509.SignatureAlgorithm -// and returns the corresponding OID digest algorithm -func getDigestOIDForSignatureAlgorithm(digestAlg x509.SignatureAlgorithm) (asn1.ObjectIdentifier, error) { - switch digestAlg { - case x509.SHA1WithRSA, x509.ECDSAWithSHA1: - return OIDDigestAlgorithmSHA1, nil - case x509.SHA256WithRSA, x509.ECDSAWithSHA256: - return OIDDigestAlgorithmSHA256, nil - case x509.SHA384WithRSA, x509.ECDSAWithSHA384: - return OIDDigestAlgorithmSHA384, nil - case x509.SHA512WithRSA, x509.ECDSAWithSHA512: - return OIDDigestAlgorithmSHA512, nil - } - return nil, fmt.Errorf("pkcs7: cannot convert hash to oid, unknown hash algorithm") -} - -// getOIDForEncryptionAlgorithm takes the private key type of the signer and -// the OID of a digest algorithm to return the appropriate signerInfo.DigestEncryptionAlgorithm -func getOIDForEncryptionAlgorithm(pkey crypto.PrivateKey, OIDDigestAlg asn1.ObjectIdentifier) (asn1.ObjectIdentifier, error) { - switch pkey.(type) { - case *rsa.PrivateKey: - switch { - default: - return OIDEncryptionAlgorithmRSA, nil - case OIDDigestAlg.Equal(OIDEncryptionAlgorithmRSA): - return OIDEncryptionAlgorithmRSA, nil - case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA1): - return OIDEncryptionAlgorithmRSASHA1, nil - case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA256): - return OIDEncryptionAlgorithmRSASHA256, nil - case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA384): - return OIDEncryptionAlgorithmRSASHA384, nil - case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA512): - return OIDEncryptionAlgorithmRSASHA512, nil - } - case *ecdsa.PrivateKey: - switch { - case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA1): - return OIDDigestAlgorithmECDSASHA1, nil - case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA256): - return OIDDigestAlgorithmECDSASHA256, nil - case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA384): - return OIDDigestAlgorithmECDSASHA384, nil - case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA512): - return OIDDigestAlgorithmECDSASHA512, nil - } - case *dsa.PrivateKey: - return OIDDigestAlgorithmDSA, nil - } - return nil, fmt.Errorf("pkcs7: cannot convert encryption algorithm to oid, unknown private key type %T", pkey) - -} - -// Parse decodes a DER encoded PKCS7 package -func Parse(data []byte) (p7 *PKCS7, err error) { - if len(data) == 0 { - return nil, errors.New("pkcs7: input data is empty") - } - var info contentInfo - der, err := ber2der(data) - if err != nil { - return nil, err - } - rest, err := asn1.Unmarshal(der, &info) - if len(rest) > 0 { - err = asn1.SyntaxError{Msg: "trailing data"} - return - } - if err != nil { - return - } - - // fmt.Printf("--> Content Type: %s", info.ContentType) - switch { - case info.ContentType.Equal(OIDSignedData): - return parseSignedData(info.Content.Bytes) - case info.ContentType.Equal(OIDEnvelopedData): - return parseEnvelopedData(info.Content.Bytes) - case info.ContentType.Equal(OIDEncryptedData): - return parseEncryptedData(info.Content.Bytes) - } - return nil, ErrUnsupportedContentType -} - -func parseEnvelopedData(data []byte) (*PKCS7, error) { - var ed envelopedData - if _, err := asn1.Unmarshal(data, &ed); err != nil { - return nil, err - } - return &PKCS7{ - raw: ed, - }, nil -} - -func parseEncryptedData(data []byte) (*PKCS7, error) { - var ed encryptedData - if _, err := asn1.Unmarshal(data, &ed); err != nil { - return nil, err - } - return &PKCS7{ - raw: ed, - }, nil -} - -func (raw rawCertificates) Parse() ([]*x509.Certificate, error) { - if len(raw.Raw) == 0 { - return nil, nil - } - - var val asn1.RawValue - if _, err := asn1.Unmarshal(raw.Raw, &val); err != nil { - return nil, err - } - - return x509.ParseCertificates(val.Bytes) -} - -func isCertMatchForIssuerAndSerial(cert *x509.Certificate, ias issuerAndSerial) bool { - return cert.SerialNumber.Cmp(ias.SerialNumber) == 0 && bytes.Equal(cert.RawIssuer, ias.IssuerName.FullBytes) -} - -// Attribute represents a key value pair attribute. Value must be marshalable byte -// `encoding/asn1` -type Attribute struct { - Type asn1.ObjectIdentifier - Value interface{} -} - -type attributes struct { - types []asn1.ObjectIdentifier - values []interface{} -} - -// Add adds the attribute, maintaining insertion order -func (attrs *attributes) Add(attrType asn1.ObjectIdentifier, value interface{}) { - attrs.types = append(attrs.types, attrType) - attrs.values = append(attrs.values, value) -} - -type sortableAttribute struct { - SortKey []byte - Attribute attribute -} - -type attributeSet []sortableAttribute - -func (sa attributeSet) Len() int { - return len(sa) -} - -func (sa attributeSet) Less(i, j int) bool { - return bytes.Compare(sa[i].SortKey, sa[j].SortKey) < 0 -} - -func (sa attributeSet) Swap(i, j int) { - sa[i], sa[j] = sa[j], sa[i] -} - -func (sa attributeSet) Attributes() []attribute { - attrs := make([]attribute, len(sa)) - for i, attr := range sa { - attrs[i] = attr.Attribute - } - return attrs -} - -func (attrs *attributes) ForMarshalling() ([]attribute, error) { - sortables := make(attributeSet, len(attrs.types)) - for i := range sortables { - attrType := attrs.types[i] - attrValue := attrs.values[i] - asn1Value, err := asn1.Marshal(attrValue) - if err != nil { - return nil, err - } - attr := attribute{ - Type: attrType, - Value: asn1.RawValue{Tag: 17, IsCompound: true, Bytes: asn1Value}, // 17 == SET tag - } - encoded, err := asn1.Marshal(attr) - if err != nil { - return nil, err - } - sortables[i] = sortableAttribute{ - SortKey: encoded, - Attribute: attr, - } - } - sort.Sort(sortables) - return sortables.Attributes(), nil -} diff --git a/vendor/go.mozilla.org/pkcs7/sign.go b/vendor/go.mozilla.org/pkcs7/sign.go deleted file mode 100644 index 31c3654c51..0000000000 --- a/vendor/go.mozilla.org/pkcs7/sign.go +++ /dev/null @@ -1,429 +0,0 @@ -package pkcs7 - -import ( - "bytes" - "crypto" - "crypto/dsa" - "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "errors" - "fmt" - "math/big" - "time" -) - -// SignedData is an opaque data structure for creating signed data payloads -type SignedData struct { - sd signedData - certs []*x509.Certificate - data, messageDigest []byte - digestOid asn1.ObjectIdentifier - encryptionOid asn1.ObjectIdentifier -} - -// NewSignedData takes data and initializes a PKCS7 SignedData struct that is -// ready to be signed via AddSigner. The digest algorithm is set to SHA1 by default -// and can be changed by calling SetDigestAlgorithm. -func NewSignedData(data []byte) (*SignedData, error) { - content, err := asn1.Marshal(data) - if err != nil { - return nil, err - } - ci := contentInfo{ - ContentType: OIDData, - Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: content, IsCompound: true}, - } - sd := signedData{ - ContentInfo: ci, - Version: 1, - } - return &SignedData{sd: sd, data: data, digestOid: OIDDigestAlgorithmSHA1}, nil -} - -// SignerInfoConfig are optional values to include when adding a signer -type SignerInfoConfig struct { - ExtraSignedAttributes []Attribute - ExtraUnsignedAttributes []Attribute -} - -type signedData struct { - Version int `asn1:"default:1"` - DigestAlgorithmIdentifiers []pkix.AlgorithmIdentifier `asn1:"set"` - ContentInfo contentInfo - Certificates rawCertificates `asn1:"optional,tag:0"` - CRLs []pkix.CertificateList `asn1:"optional,tag:1"` - SignerInfos []signerInfo `asn1:"set"` -} - -type signerInfo struct { - Version int `asn1:"default:1"` - IssuerAndSerialNumber issuerAndSerial - DigestAlgorithm pkix.AlgorithmIdentifier - AuthenticatedAttributes []attribute `asn1:"optional,omitempty,tag:0"` - DigestEncryptionAlgorithm pkix.AlgorithmIdentifier - EncryptedDigest []byte - UnauthenticatedAttributes []attribute `asn1:"optional,omitempty,tag:1"` -} - -type attribute struct { - Type asn1.ObjectIdentifier - Value asn1.RawValue `asn1:"set"` -} - -func marshalAttributes(attrs []attribute) ([]byte, error) { - encodedAttributes, err := asn1.Marshal(struct { - A []attribute `asn1:"set"` - }{A: attrs}) - if err != nil { - return nil, err - } - - // Remove the leading sequence octets - var raw asn1.RawValue - asn1.Unmarshal(encodedAttributes, &raw) - return raw.Bytes, nil -} - -type rawCertificates struct { - Raw asn1.RawContent -} - -type issuerAndSerial struct { - IssuerName asn1.RawValue - SerialNumber *big.Int -} - -// SetDigestAlgorithm sets the digest algorithm to be used in the signing process. -// -// This should be called before adding signers -func (sd *SignedData) SetDigestAlgorithm(d asn1.ObjectIdentifier) { - sd.digestOid = d -} - -// SetEncryptionAlgorithm sets the encryption algorithm to be used in the signing process. -// -// This should be called before adding signers -func (sd *SignedData) SetEncryptionAlgorithm(d asn1.ObjectIdentifier) { - sd.encryptionOid = d -} - -// AddSigner is a wrapper around AddSignerChain() that adds a signer without any parent. -func (sd *SignedData) AddSigner(ee *x509.Certificate, pkey crypto.PrivateKey, config SignerInfoConfig) error { - var parents []*x509.Certificate - return sd.AddSignerChain(ee, pkey, parents, config) -} - -// AddSignerChain signs attributes about the content and adds certificates -// and signers infos to the Signed Data. The certificate and private key -// of the end-entity signer are used to issue the signature, and any -// parent of that end-entity that need to be added to the list of -// certifications can be specified in the parents slice. -// -// The signature algorithm used to hash the data is the one of the end-entity -// certificate. -func (sd *SignedData) AddSignerChain(ee *x509.Certificate, pkey crypto.PrivateKey, parents []*x509.Certificate, config SignerInfoConfig) error { - // Following RFC 2315, 9.2 SignerInfo type, the distinguished name of - // the issuer of the end-entity signer is stored in the issuerAndSerialNumber - // section of the SignedData.SignerInfo, alongside the serial number of - // the end-entity. - var ias issuerAndSerial - ias.SerialNumber = ee.SerialNumber - if len(parents) == 0 { - // no parent, the issuer is the end-entity cert itself - ias.IssuerName = asn1.RawValue{FullBytes: ee.RawIssuer} - } else { - err := verifyPartialChain(ee, parents) - if err != nil { - return err - } - // the first parent is the issuer - ias.IssuerName = asn1.RawValue{FullBytes: parents[0].RawSubject} - } - sd.sd.DigestAlgorithmIdentifiers = append(sd.sd.DigestAlgorithmIdentifiers, - pkix.AlgorithmIdentifier{Algorithm: sd.digestOid}, - ) - hash, err := getHashForOID(sd.digestOid) - if err != nil { - return err - } - h := hash.New() - h.Write(sd.data) - sd.messageDigest = h.Sum(nil) - encryptionOid, err := getOIDForEncryptionAlgorithm(pkey, sd.digestOid) - if err != nil { - return err - } - attrs := &attributes{} - attrs.Add(OIDAttributeContentType, sd.sd.ContentInfo.ContentType) - attrs.Add(OIDAttributeMessageDigest, sd.messageDigest) - attrs.Add(OIDAttributeSigningTime, time.Now().UTC()) - for _, attr := range config.ExtraSignedAttributes { - attrs.Add(attr.Type, attr.Value) - } - finalAttrs, err := attrs.ForMarshalling() - if err != nil { - return err - } - unsignedAttrs := &attributes{} - for _, attr := range config.ExtraUnsignedAttributes { - unsignedAttrs.Add(attr.Type, attr.Value) - } - finalUnsignedAttrs, err := unsignedAttrs.ForMarshalling() - if err != nil { - return err - } - // create signature of signed attributes - signature, err := signAttributes(finalAttrs, pkey, hash) - if err != nil { - return err - } - signer := signerInfo{ - AuthenticatedAttributes: finalAttrs, - UnauthenticatedAttributes: finalUnsignedAttrs, - DigestAlgorithm: pkix.AlgorithmIdentifier{Algorithm: sd.digestOid}, - DigestEncryptionAlgorithm: pkix.AlgorithmIdentifier{Algorithm: encryptionOid}, - IssuerAndSerialNumber: ias, - EncryptedDigest: signature, - Version: 1, - } - sd.certs = append(sd.certs, ee) - if len(parents) > 0 { - sd.certs = append(sd.certs, parents...) - } - sd.sd.SignerInfos = append(sd.sd.SignerInfos, signer) - return nil -} - -// SignWithoutAttr issues a signature on the content of the pkcs7 SignedData. -// Unlike AddSigner/AddSignerChain, it calculates the digest on the data alone -// and does not include any signed attributes like timestamp and so on. -// -// This function is needed to sign old Android APKs, something you probably -// shouldn't do unless you're maintaining backward compatibility for old -// applications. -func (sd *SignedData) SignWithoutAttr(ee *x509.Certificate, pkey crypto.PrivateKey, config SignerInfoConfig) error { - var signature []byte - sd.sd.DigestAlgorithmIdentifiers = append(sd.sd.DigestAlgorithmIdentifiers, pkix.AlgorithmIdentifier{Algorithm: sd.digestOid}) - hash, err := getHashForOID(sd.digestOid) - if err != nil { - return err - } - h := hash.New() - h.Write(sd.data) - sd.messageDigest = h.Sum(nil) - switch pkey := pkey.(type) { - case *dsa.PrivateKey: - // dsa doesn't implement crypto.Signer so we make a special case - // https://github.com/golang/go/issues/27889 - r, s, err := dsa.Sign(rand.Reader, pkey, sd.messageDigest) - if err != nil { - return err - } - signature, err = asn1.Marshal(dsaSignature{r, s}) - if err != nil { - return err - } - default: - key, ok := pkey.(crypto.Signer) - if !ok { - return errors.New("pkcs7: private key does not implement crypto.Signer") - } - signature, err = key.Sign(rand.Reader, sd.messageDigest, hash) - if err != nil { - return err - } - } - var ias issuerAndSerial - ias.SerialNumber = ee.SerialNumber - // no parent, the issue is the end-entity cert itself - ias.IssuerName = asn1.RawValue{FullBytes: ee.RawIssuer} - if sd.encryptionOid == nil { - // if the encryption algorithm wasn't set by SetEncryptionAlgorithm, - // infer it from the digest algorithm - sd.encryptionOid, err = getOIDForEncryptionAlgorithm(pkey, sd.digestOid) - } - if err != nil { - return err - } - signer := signerInfo{ - DigestAlgorithm: pkix.AlgorithmIdentifier{Algorithm: sd.digestOid}, - DigestEncryptionAlgorithm: pkix.AlgorithmIdentifier{Algorithm: sd.encryptionOid}, - IssuerAndSerialNumber: ias, - EncryptedDigest: signature, - Version: 1, - } - // create signature of signed attributes - sd.certs = append(sd.certs, ee) - sd.sd.SignerInfos = append(sd.sd.SignerInfos, signer) - return nil -} - -func (si *signerInfo) SetUnauthenticatedAttributes(extraUnsignedAttrs []Attribute) error { - unsignedAttrs := &attributes{} - for _, attr := range extraUnsignedAttrs { - unsignedAttrs.Add(attr.Type, attr.Value) - } - finalUnsignedAttrs, err := unsignedAttrs.ForMarshalling() - if err != nil { - return err - } - - si.UnauthenticatedAttributes = finalUnsignedAttrs - - return nil -} - -// AddCertificate adds the certificate to the payload. Useful for parent certificates -func (sd *SignedData) AddCertificate(cert *x509.Certificate) { - sd.certs = append(sd.certs, cert) -} - -// Detach removes content from the signed data struct to make it a detached signature. -// This must be called right before Finish() -func (sd *SignedData) Detach() { - sd.sd.ContentInfo = contentInfo{ContentType: OIDData} -} - -// GetSignedData returns the private Signed Data -func (sd *SignedData) GetSignedData() *signedData { - return &sd.sd -} - -// Finish marshals the content and its signers -func (sd *SignedData) Finish() ([]byte, error) { - sd.sd.Certificates = marshalCertificates(sd.certs) - inner, err := asn1.Marshal(sd.sd) - if err != nil { - return nil, err - } - outer := contentInfo{ - ContentType: OIDSignedData, - Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: inner, IsCompound: true}, - } - return asn1.Marshal(outer) -} - -// RemoveAuthenticatedAttributes removes authenticated attributes from signedData -// similar to OpenSSL's PKCS7_NOATTR or -noattr flags -func (sd *SignedData) RemoveAuthenticatedAttributes() { - for i := range sd.sd.SignerInfos { - sd.sd.SignerInfos[i].AuthenticatedAttributes = nil - } -} - -// RemoveUnauthenticatedAttributes removes unauthenticated attributes from signedData -func (sd *SignedData) RemoveUnauthenticatedAttributes() { - for i := range sd.sd.SignerInfos { - sd.sd.SignerInfos[i].UnauthenticatedAttributes = nil - } -} - -// verifyPartialChain checks that a given cert is issued by the first parent in the list, -// then continue down the path. It doesn't require the last parent to be a root CA, -// or to be trusted in any truststore. It simply verifies that the chain provided, albeit -// partial, makes sense. -func verifyPartialChain(cert *x509.Certificate, parents []*x509.Certificate) error { - if len(parents) == 0 { - return fmt.Errorf("pkcs7: zero parents provided to verify the signature of certificate %q", cert.Subject.CommonName) - } - err := cert.CheckSignatureFrom(parents[0]) - if err != nil { - return fmt.Errorf("pkcs7: certificate signature from parent is invalid: %v", err) - } - if len(parents) == 1 { - // there is no more parent to check, return - return nil - } - return verifyPartialChain(parents[0], parents[1:]) -} - -func cert2issuerAndSerial(cert *x509.Certificate) (issuerAndSerial, error) { - var ias issuerAndSerial - // The issuer RDNSequence has to match exactly the sequence in the certificate - // We cannot use cert.Issuer.ToRDNSequence() here since it mangles the sequence - ias.IssuerName = asn1.RawValue{FullBytes: cert.RawIssuer} - ias.SerialNumber = cert.SerialNumber - - return ias, nil -} - -// signs the DER encoded form of the attributes with the private key -func signAttributes(attrs []attribute, pkey crypto.PrivateKey, digestAlg crypto.Hash) ([]byte, error) { - attrBytes, err := marshalAttributes(attrs) - if err != nil { - return nil, err - } - h := digestAlg.New() - h.Write(attrBytes) - hash := h.Sum(nil) - - // dsa doesn't implement crypto.Signer so we make a special case - // https://github.com/golang/go/issues/27889 - switch pkey := pkey.(type) { - case *dsa.PrivateKey: - r, s, err := dsa.Sign(rand.Reader, pkey, hash) - if err != nil { - return nil, err - } - return asn1.Marshal(dsaSignature{r, s}) - } - - key, ok := pkey.(crypto.Signer) - if !ok { - return nil, errors.New("pkcs7: private key does not implement crypto.Signer") - } - return key.Sign(rand.Reader, hash, digestAlg) -} - -type dsaSignature struct { - R, S *big.Int -} - -// concats and wraps the certificates in the RawValue structure -func marshalCertificates(certs []*x509.Certificate) rawCertificates { - var buf bytes.Buffer - for _, cert := range certs { - buf.Write(cert.Raw) - } - rawCerts, _ := marshalCertificateBytes(buf.Bytes()) - return rawCerts -} - -// Even though, the tag & length are stripped out during marshalling the -// RawContent, we have to encode it into the RawContent. If its missing, -// then `asn1.Marshal()` will strip out the certificate wrapper instead. -func marshalCertificateBytes(certs []byte) (rawCertificates, error) { - var val = asn1.RawValue{Bytes: certs, Class: 2, Tag: 0, IsCompound: true} - b, err := asn1.Marshal(val) - if err != nil { - return rawCertificates{}, err - } - return rawCertificates{Raw: b}, nil -} - -// DegenerateCertificate creates a signed data structure containing only the -// provided certificate or certificate chain. -func DegenerateCertificate(cert []byte) ([]byte, error) { - rawCert, err := marshalCertificateBytes(cert) - if err != nil { - return nil, err - } - emptyContent := contentInfo{ContentType: OIDData} - sd := signedData{ - Version: 1, - ContentInfo: emptyContent, - Certificates: rawCert, - CRLs: []pkix.CertificateList{}, - } - content, err := asn1.Marshal(sd) - if err != nil { - return nil, err - } - signedContent := contentInfo{ - ContentType: OIDSignedData, - Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: content, IsCompound: true}, - } - return asn1.Marshal(signedContent) -} diff --git a/vendor/go.mozilla.org/pkcs7/verify.go b/vendor/go.mozilla.org/pkcs7/verify.go deleted file mode 100644 index f09e27245c..0000000000 --- a/vendor/go.mozilla.org/pkcs7/verify.go +++ /dev/null @@ -1,343 +0,0 @@ -package pkcs7 - -import ( - "crypto/subtle" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "errors" - "fmt" - "time" -) - -// Verify is a wrapper around VerifyWithChain() that initializes an empty -// trust store, effectively disabling certificate verification when validating -// a signature. -func (p7 *PKCS7) Verify() (err error) { - return p7.VerifyWithChain(nil) -} - -// VerifyWithChain checks the signatures of a PKCS7 object. -// -// If truststore is not nil, it also verifies the chain of trust of -// the end-entity signer cert to one of the roots in the -// truststore. When the PKCS7 object includes the signing time -// authenticated attr verifies the chain at that time and UTC now -// otherwise. -func (p7 *PKCS7) VerifyWithChain(truststore *x509.CertPool) (err error) { - if len(p7.Signers) == 0 { - return errors.New("pkcs7: Message has no signers") - } - for _, signer := range p7.Signers { - if err := verifySignature(p7, signer, truststore); err != nil { - return err - } - } - return nil -} - -// VerifyWithChainAtTime checks the signatures of a PKCS7 object. -// -// If truststore is not nil, it also verifies the chain of trust of -// the end-entity signer cert to a root in the truststore at -// currentTime. It does not use the signing time authenticated -// attribute. -func (p7 *PKCS7) VerifyWithChainAtTime(truststore *x509.CertPool, currentTime time.Time) (err error) { - if len(p7.Signers) == 0 { - return errors.New("pkcs7: Message has no signers") - } - for _, signer := range p7.Signers { - if err := verifySignatureAtTime(p7, signer, truststore, currentTime); err != nil { - return err - } - } - return nil -} - -func verifySignatureAtTime(p7 *PKCS7, signer signerInfo, truststore *x509.CertPool, currentTime time.Time) (err error) { - signedData := p7.Content - ee := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber) - if ee == nil { - return errors.New("pkcs7: No certificate for signer") - } - if len(signer.AuthenticatedAttributes) > 0 { - // TODO(fullsailor): First check the content type match - var ( - digest []byte - signingTime time.Time - ) - err := unmarshalAttribute(signer.AuthenticatedAttributes, OIDAttributeMessageDigest, &digest) - if err != nil { - return err - } - hash, err := getHashForOID(signer.DigestAlgorithm.Algorithm) - if err != nil { - return err - } - h := hash.New() - h.Write(p7.Content) - computed := h.Sum(nil) - if subtle.ConstantTimeCompare(digest, computed) != 1 { - return &MessageDigestMismatchError{ - ExpectedDigest: digest, - ActualDigest: computed, - } - } - signedData, err = marshalAttributes(signer.AuthenticatedAttributes) - if err != nil { - return err - } - err = unmarshalAttribute(signer.AuthenticatedAttributes, OIDAttributeSigningTime, &signingTime) - if err == nil { - // signing time found, performing validity check - if signingTime.After(ee.NotAfter) || signingTime.Before(ee.NotBefore) { - return fmt.Errorf("pkcs7: signing time %q is outside of certificate validity %q to %q", - signingTime.Format(time.RFC3339), - ee.NotBefore.Format(time.RFC3339), - ee.NotAfter.Format(time.RFC3339)) - } - } - } - if truststore != nil { - _, err = verifyCertChain(ee, p7.Certificates, truststore, currentTime) - if err != nil { - return err - } - } - sigalg, err := getSignatureAlgorithm(signer.DigestEncryptionAlgorithm, signer.DigestAlgorithm) - if err != nil { - return err - } - return ee.CheckSignature(sigalg, signedData, signer.EncryptedDigest) -} - -func verifySignature(p7 *PKCS7, signer signerInfo, truststore *x509.CertPool) (err error) { - signedData := p7.Content - ee := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber) - if ee == nil { - return errors.New("pkcs7: No certificate for signer") - } - signingTime := time.Now().UTC() - if len(signer.AuthenticatedAttributes) > 0 { - // TODO(fullsailor): First check the content type match - var digest []byte - err := unmarshalAttribute(signer.AuthenticatedAttributes, OIDAttributeMessageDigest, &digest) - if err != nil { - return err - } - hash, err := getHashForOID(signer.DigestAlgorithm.Algorithm) - if err != nil { - return err - } - h := hash.New() - h.Write(p7.Content) - computed := h.Sum(nil) - if subtle.ConstantTimeCompare(digest, computed) != 1 { - return &MessageDigestMismatchError{ - ExpectedDigest: digest, - ActualDigest: computed, - } - } - signedData, err = marshalAttributes(signer.AuthenticatedAttributes) - if err != nil { - return err - } - err = unmarshalAttribute(signer.AuthenticatedAttributes, OIDAttributeSigningTime, &signingTime) - if err == nil { - // signing time found, performing validity check - if signingTime.After(ee.NotAfter) || signingTime.Before(ee.NotBefore) { - return fmt.Errorf("pkcs7: signing time %q is outside of certificate validity %q to %q", - signingTime.Format(time.RFC3339), - ee.NotBefore.Format(time.RFC3339), - ee.NotAfter.Format(time.RFC3339)) - } - } - } - if truststore != nil { - _, err = verifyCertChain(ee, p7.Certificates, truststore, signingTime) - if err != nil { - return err - } - } - sigalg, err := getSignatureAlgorithm(signer.DigestEncryptionAlgorithm, signer.DigestAlgorithm) - if err != nil { - return err - } - return ee.CheckSignature(sigalg, signedData, signer.EncryptedDigest) -} - -// GetOnlySigner returns an x509.Certificate for the first signer of the signed -// data payload. If there are more or less than one signer, nil is returned -func (p7 *PKCS7) GetOnlySigner() *x509.Certificate { - if len(p7.Signers) != 1 { - return nil - } - signer := p7.Signers[0] - return getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber) -} - -// UnmarshalSignedAttribute decodes a single attribute from the signer info -func (p7 *PKCS7) UnmarshalSignedAttribute(attributeType asn1.ObjectIdentifier, out interface{}) error { - sd, ok := p7.raw.(signedData) - if !ok { - return errors.New("pkcs7: payload is not signedData content") - } - if len(sd.SignerInfos) < 1 { - return errors.New("pkcs7: payload has no signers") - } - attributes := sd.SignerInfos[0].AuthenticatedAttributes - return unmarshalAttribute(attributes, attributeType, out) -} - -func parseSignedData(data []byte) (*PKCS7, error) { - var sd signedData - asn1.Unmarshal(data, &sd) - certs, err := sd.Certificates.Parse() - if err != nil { - return nil, err - } - // fmt.Printf("--> Signed Data Version %d\n", sd.Version) - - var compound asn1.RawValue - var content unsignedData - - // The Content.Bytes maybe empty on PKI responses. - if len(sd.ContentInfo.Content.Bytes) > 0 { - if _, err := asn1.Unmarshal(sd.ContentInfo.Content.Bytes, &compound); err != nil { - return nil, err - } - } - // Compound octet string - if compound.IsCompound { - if compound.Tag == 4 { - if _, err = asn1.Unmarshal(compound.Bytes, &content); err != nil { - return nil, err - } - } else { - content = compound.Bytes - } - } else { - // assuming this is tag 04 - content = compound.Bytes - } - return &PKCS7{ - Content: content, - Certificates: certs, - CRLs: sd.CRLs, - Signers: sd.SignerInfos, - raw: sd}, nil -} - -// verifyCertChain takes an end-entity certs, a list of potential intermediates and a -// truststore, and built all potential chains between the EE and a trusted root. -// -// When verifying chains that may have expired, currentTime can be set to a past date -// to allow the verification to pass. If unset, currentTime is set to the current UTC time. -func verifyCertChain(ee *x509.Certificate, certs []*x509.Certificate, truststore *x509.CertPool, currentTime time.Time) (chains [][]*x509.Certificate, err error) { - intermediates := x509.NewCertPool() - for _, intermediate := range certs { - intermediates.AddCert(intermediate) - } - verifyOptions := x509.VerifyOptions{ - Roots: truststore, - Intermediates: intermediates, - KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny}, - CurrentTime: currentTime, - } - chains, err = ee.Verify(verifyOptions) - if err != nil { - return chains, fmt.Errorf("pkcs7: failed to verify certificate chain: %v", err) - } - return -} - -// MessageDigestMismatchError is returned when the signer data digest does not -// match the computed digest for the contained content -type MessageDigestMismatchError struct { - ExpectedDigest []byte - ActualDigest []byte -} - -func (err *MessageDigestMismatchError) Error() string { - return fmt.Sprintf("pkcs7: Message digest mismatch\n\tExpected: %X\n\tActual : %X", err.ExpectedDigest, err.ActualDigest) -} - -func getSignatureAlgorithm(digestEncryption, digest pkix.AlgorithmIdentifier) (x509.SignatureAlgorithm, error) { - switch { - case digestEncryption.Algorithm.Equal(OIDDigestAlgorithmECDSASHA1): - return x509.ECDSAWithSHA1, nil - case digestEncryption.Algorithm.Equal(OIDDigestAlgorithmECDSASHA256): - return x509.ECDSAWithSHA256, nil - case digestEncryption.Algorithm.Equal(OIDDigestAlgorithmECDSASHA384): - return x509.ECDSAWithSHA384, nil - case digestEncryption.Algorithm.Equal(OIDDigestAlgorithmECDSASHA512): - return x509.ECDSAWithSHA512, nil - case digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmRSA), - digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA1), - digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA256), - digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA384), - digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA512): - switch { - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA1): - return x509.SHA1WithRSA, nil - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA256): - return x509.SHA256WithRSA, nil - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA384): - return x509.SHA384WithRSA, nil - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA512): - return x509.SHA512WithRSA, nil - default: - return -1, fmt.Errorf("pkcs7: unsupported digest %q for encryption algorithm %q", - digest.Algorithm.String(), digestEncryption.Algorithm.String()) - } - case digestEncryption.Algorithm.Equal(OIDDigestAlgorithmDSA), - digestEncryption.Algorithm.Equal(OIDDigestAlgorithmDSASHA1): - switch { - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA1): - return x509.DSAWithSHA1, nil - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA256): - return x509.DSAWithSHA256, nil - default: - return -1, fmt.Errorf("pkcs7: unsupported digest %q for encryption algorithm %q", - digest.Algorithm.String(), digestEncryption.Algorithm.String()) - } - case digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmECDSAP256), - digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmECDSAP384), - digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmECDSAP521): - switch { - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA1): - return x509.ECDSAWithSHA1, nil - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA256): - return x509.ECDSAWithSHA256, nil - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA384): - return x509.ECDSAWithSHA384, nil - case digest.Algorithm.Equal(OIDDigestAlgorithmSHA512): - return x509.ECDSAWithSHA512, nil - default: - return -1, fmt.Errorf("pkcs7: unsupported digest %q for encryption algorithm %q", - digest.Algorithm.String(), digestEncryption.Algorithm.String()) - } - default: - return -1, fmt.Errorf("pkcs7: unsupported algorithm %q", - digestEncryption.Algorithm.String()) - } -} - -func getCertFromCertsByIssuerAndSerial(certs []*x509.Certificate, ias issuerAndSerial) *x509.Certificate { - for _, cert := range certs { - if isCertMatchForIssuerAndSerial(cert, ias) { - return cert - } - } - return nil -} - -func unmarshalAttribute(attrs []attribute, attributeType asn1.ObjectIdentifier, out interface{}) error { - for _, attr := range attrs { - if attr.Type.Equal(attributeType) { - _, err := asn1.Unmarshal(attr.Value.Bytes, out) - return err - } - } - return errors.New("pkcs7: attribute type not in attributes") -} diff --git a/vendor/go.mozilla.org/pkcs7/verify_test_dsa.go b/vendor/go.mozilla.org/pkcs7/verify_test_dsa.go deleted file mode 100644 index 1eb05bc3ea..0000000000 --- a/vendor/go.mozilla.org/pkcs7/verify_test_dsa.go +++ /dev/null @@ -1,182 +0,0 @@ -// +build go1.11 go1.12 go1.13 go1.14 go1.15 - -package pkcs7 - -import ( - "crypto/x509" - "encoding/pem" - "fmt" - "io/ioutil" - "os" - "os/exec" - "testing" -) - -func TestVerifyEC2(t *testing.T) { - fixture := UnmarshalDSATestFixture(EC2IdentityDocumentFixture) - p7, err := Parse(fixture.Input) - if err != nil { - t.Errorf("Parse encountered unexpected error: %v", err) - } - p7.Certificates = []*x509.Certificate{fixture.Certificate} - if err := p7.Verify(); err != nil { - t.Errorf("Verify failed with error: %v", err) - } -} - -var EC2IdentityDocumentFixture = ` ------BEGIN PKCS7----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEggGmewogICJwcml2YXRlSXAiIDogIjE3Mi4zMC4wLjI1MiIsCiAgImRldnBh -eVByb2R1Y3RDb2RlcyIgOiBudWxsLAogICJhdmFpbGFiaWxpdHlab25lIiA6ICJ1 -cy1lYXN0LTFhIiwKICAidmVyc2lvbiIgOiAiMjAxMC0wOC0zMSIsCiAgImluc3Rh -bmNlSWQiIDogImktZjc5ZmU1NmMiLAogICJiaWxsaW5nUHJvZHVjdHMiIDogbnVs -bCwKICAiaW5zdGFuY2VUeXBlIiA6ICJ0Mi5taWNybyIsCiAgImFjY291bnRJZCIg -OiAiMTIxNjU5MDE0MzM0IiwKICAiaW1hZ2VJZCIgOiAiYW1pLWZjZTNjNjk2IiwK -ICAicGVuZGluZ1RpbWUiIDogIjIwMTYtMDQtMDhUMDM6MDE6MzhaIiwKICAiYXJj -aGl0ZWN0dXJlIiA6ICJ4ODZfNjQiLAogICJrZXJuZWxJZCIgOiBudWxsLAogICJy -YW1kaXNrSWQiIDogbnVsbCwKICAicmVnaW9uIiA6ICJ1cy1lYXN0LTEiCn0AAAAA -AAAxggEYMIIBFAIBATBpMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5n -dG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2Vi -IFNlcnZpY2VzIExMQwIJAJa6SNnlXhpnMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0B -CQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNjA0MDgwMzAxNDRaMCMG -CSqGSIb3DQEJBDEWBBTuUc28eBXmImAautC+wOjqcFCBVjAJBgcqhkjOOAQDBC8w -LQIVAKA54NxGHWWCz5InboDmY/GHs33nAhQ6O/ZI86NwjA9Vz3RNMUJrUPU5tAAA -AAAAAA== ------END PKCS7----- ------BEGIN CERTIFICATE----- -MIIC7TCCAq0CCQCWukjZ5V4aZzAJBgcqhkjOOAQDMFwxCzAJBgNVBAYTAlVTMRkw -FwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYD -VQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAeFw0xMjAxMDUxMjU2MTJaFw0z -ODAxMDUxMjU2MTJaMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9u -IFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNl -cnZpY2VzIExMQzCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCjkvcS2bb1VQ4yt/5e -ih5OO6kK/n1Lzllr7D8ZwtQP8fOEpp5E2ng+D6Ud1Z1gYipr58Kj3nssSNpI6bX3 -VyIQzK7wLclnd/YozqNNmgIyZecN7EglK9ITHJLP+x8FtUpt3QbyYXJdmVMegN6P -hviYt5JH/nYl4hh3Pa1HJdskgQIVALVJ3ER11+Ko4tP6nwvHwh6+ERYRAoGBAI1j -k+tkqMVHuAFcvAGKocTgsjJem6/5qomzJuKDmbJNu9Qxw3rAotXau8Qe+MBcJl/U -hhy1KHVpCGl9fueQ2s6IL0CaO/buycU1CiYQk40KNHCcHfNiZbdlx1E9rpUp7bnF -lRa2v1ntMX3caRVDdbtPEWmdxSCYsYFDk4mZrOLBA4GEAAKBgEbmeve5f8LIE/Gf -MNmP9CM5eovQOGx5ho8WqD+aTebs+k2tn92BBPqeZqpWRa5P/+jrdKml1qx4llHW -MXrs3IgIb6+hUIB+S8dz8/mmO0bpr76RoZVCXYab2CZedFut7qc3WUH9+EUAH5mw -vSeDCOUMYQR7R9LINYwouHIziqQYMAkGByqGSM44BAMDLwAwLAIUWXBlk40xTwSw -7HX32MxXYruse9ACFBNGmdX2ZBrVNGrN9N2f6ROk0k9K ------END CERTIFICATE-----` - -func TestDSASignWithOpenSSLAndVerify(t *testing.T) { - content := []byte(` -A ship in port is safe, -but that's not what ships are built for. --- Grace Hopper`) - // write the content to a temp file - tmpContentFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_content") - if err != nil { - t.Fatal(err) - } - ioutil.WriteFile(tmpContentFile.Name(), content, 0755) - - // write the signer cert to a temp file - tmpSignerCertFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_signer") - if err != nil { - t.Fatal(err) - } - ioutil.WriteFile(tmpSignerCertFile.Name(), dsaPublicCert, 0755) - - // write the signer key to a temp file - tmpSignerKeyFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_key") - if err != nil { - t.Fatal(err) - } - ioutil.WriteFile(tmpSignerKeyFile.Name(), dsaPrivateKey, 0755) - - tmpSignedFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_signature") - if err != nil { - t.Fatal(err) - } - // call openssl to sign the content - opensslCMD := exec.Command("openssl", "smime", "-sign", "-nodetach", "-md", "sha1", - "-in", tmpContentFile.Name(), "-out", tmpSignedFile.Name(), - "-signer", tmpSignerCertFile.Name(), "-inkey", tmpSignerKeyFile.Name(), - "-certfile", tmpSignerCertFile.Name(), "-outform", "PEM") - out, err := opensslCMD.CombinedOutput() - if err != nil { - t.Fatalf("openssl command failed with %s: %s", err, out) - } - - // verify the signed content - pemSignature, err := ioutil.ReadFile(tmpSignedFile.Name()) - if err != nil { - t.Fatal(err) - } - fmt.Printf("%s\n", pemSignature) - derBlock, _ := pem.Decode(pemSignature) - if derBlock == nil { - t.Fatalf("failed to read DER block from signature PEM %s", tmpSignedFile.Name()) - } - p7, err := Parse(derBlock.Bytes) - if err != nil { - t.Fatalf("Parse encountered unexpected error: %v", err) - } - if err := p7.Verify(); err != nil { - t.Fatalf("Verify failed with error: %v", err) - } - os.Remove(tmpSignerCertFile.Name()) // clean up - os.Remove(tmpSignerKeyFile.Name()) // clean up - os.Remove(tmpContentFile.Name()) // clean up -} - -var dsaPrivateKey = []byte(`-----BEGIN PRIVATE KEY----- -MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdS -PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVCl -pJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith -1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7L -vKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3 -zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo -g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUfW4aPdQBn9gJZp2KuNpzgHzvfsE= ------END PRIVATE KEY-----`) - -var dsaPublicCert = []byte(`-----BEGIN CERTIFICATE----- -MIIDOjCCAvWgAwIBAgIEPCY/UDANBglghkgBZQMEAwIFADBsMRAwDgYDVQQGEwdV -bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD -VQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdVbmtub3du -MB4XDTE4MTAyMjEzNDMwN1oXDTQ2MDMwOTEzNDMwN1owbDEQMA4GA1UEBhMHVW5r -bm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UE -ChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjCC -AbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADD -Hj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gE -exAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/Ii -Axmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4 -V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozI -puE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4Vrl -nwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDCriMPbEVBoRK4SOUeFwg7+VRf4TTp -rcOQC9IVVoCjXzuWEGrp3ZI7YWJSpFnSch4lk29RH8O0HpI/NOzKnOBtnKr782pt -1k/bJVMH9EaLd6MKnAVjrCDMYBB0MhebZ8QHY2elZZCWoqDYAcIDOsEx+m4NLErT -ypPnjS5M0jm1PKMhMB8wHQYDVR0OBBYEFC0Yt5XdM0Kc95IX8NQ8XRssGPx7MA0G -CWCGSAFlAwQDAgUAAzAAMC0CFQCIgQtrZZ9hdZG1ROhR5hc8nYEmbgIUAIlgC688 -qzy/7yePTlhlpj+ahMM= ------END CERTIFICATE-----`) - -type DSATestFixture struct { - Input []byte - Certificate *x509.Certificate -} - -func UnmarshalDSATestFixture(testPEMBlock string) DSATestFixture { - var result DSATestFixture - var derBlock *pem.Block - var pemBlock = []byte(testPEMBlock) - for { - derBlock, pemBlock = pem.Decode(pemBlock) - if derBlock == nil { - break - } - switch derBlock.Type { - case "PKCS7": - result.Input = derBlock.Bytes - case "CERTIFICATE": - result.Certificate, _ = x509.ParseCertificate(derBlock.Bytes) - } - } - - return result -} diff --git a/vendor/golang.org/x/crypto/LICENSE b/vendor/golang.org/x/crypto/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/crypto/LICENSE +++ b/vendor/golang.org/x/crypto/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/crypto/acme/http.go b/vendor/golang.org/x/crypto/acme/http.go index 58836e5d30..d92ff232fe 100644 --- a/vendor/golang.org/x/crypto/acme/http.go +++ b/vendor/golang.org/x/crypto/acme/http.go @@ -15,6 +15,7 @@ import ( "io" "math/big" "net/http" + "runtime/debug" "strconv" "strings" "time" @@ -271,9 +272,27 @@ func (c *Client) httpClient() *http.Client { } // packageVersion is the version of the module that contains this package, for -// sending as part of the User-Agent header. It's set in version_go112.go. +// sending as part of the User-Agent header. var packageVersion string +func init() { + // Set packageVersion if the binary was built in modules mode and x/crypto + // was not replaced with a different module. + info, ok := debug.ReadBuildInfo() + if !ok { + return + } + for _, m := range info.Deps { + if m.Path != "golang.org/x/crypto" { + continue + } + if m.Replace == nil { + packageVersion = m.Version + } + break + } +} + // userAgent returns the User-Agent header value. It includes the package name, // the module version (if available), and the c.UserAgent value (if set). func (c *Client) userAgent() string { diff --git a/vendor/golang.org/x/crypto/acme/version_go112.go b/vendor/golang.org/x/crypto/acme/version_go112.go deleted file mode 100644 index cc5fab604b..0000000000 --- a/vendor/golang.org/x/crypto/acme/version_go112.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.12 - -package acme - -import "runtime/debug" - -func init() { - // Set packageVersion if the binary was built in modules mode and x/crypto - // was not replaced with a different module. - info, ok := debug.ReadBuildInfo() - if !ok { - return - } - for _, m := range info.Deps { - if m.Path != "golang.org/x/crypto" { - continue - } - if m.Replace == nil { - packageVersion = m.Version - } - break - } -} diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s index 6713accac0..c3895478ed 100644 --- a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s +++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s @@ -1,243 +1,2791 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Code generated by command: go run blamka_amd64.go -out ../blamka_amd64.s -pkg argon2. DO NOT EDIT. //go:build amd64 && gc && !purego #include "textflag.h" -DATA ·c40<>+0x00(SB)/8, $0x0201000706050403 -DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b -GLOBL ·c40<>(SB), (NOPTR+RODATA), $16 - -DATA ·c48<>+0x00(SB)/8, $0x0100070605040302 -DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a -GLOBL ·c48<>(SB), (NOPTR+RODATA), $16 - -#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \ - MOVO v4, t1; \ - MOVO v5, v4; \ - MOVO t1, v5; \ - MOVO v6, t1; \ - PUNPCKLQDQ v6, t2; \ - PUNPCKHQDQ v7, v6; \ - PUNPCKHQDQ t2, v6; \ - PUNPCKLQDQ v7, t2; \ - MOVO t1, v7; \ - MOVO v2, t1; \ - PUNPCKHQDQ t2, v7; \ - PUNPCKLQDQ v3, t2; \ - PUNPCKHQDQ t2, v2; \ - PUNPCKLQDQ t1, t2; \ - PUNPCKHQDQ t2, v3 - -#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \ - MOVO v4, t1; \ - MOVO v5, v4; \ - MOVO t1, v5; \ - MOVO v2, t1; \ - PUNPCKLQDQ v2, t2; \ - PUNPCKHQDQ v3, v2; \ - PUNPCKHQDQ t2, v2; \ - PUNPCKLQDQ v3, t2; \ - MOVO t1, v3; \ - MOVO v6, t1; \ - PUNPCKHQDQ t2, v3; \ - PUNPCKLQDQ v7, t2; \ - PUNPCKHQDQ t2, v6; \ - PUNPCKLQDQ t1, t2; \ - PUNPCKHQDQ t2, v7 - -#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, t0, c40, c48) \ - MOVO v0, t0; \ - PMULULQ v2, t0; \ - PADDQ v2, v0; \ - PADDQ t0, v0; \ - PADDQ t0, v0; \ - PXOR v0, v6; \ - PSHUFD $0xB1, v6, v6; \ - MOVO v4, t0; \ - PMULULQ v6, t0; \ - PADDQ v6, v4; \ - PADDQ t0, v4; \ - PADDQ t0, v4; \ - PXOR v4, v2; \ - PSHUFB c40, v2; \ - MOVO v0, t0; \ - PMULULQ v2, t0; \ - PADDQ v2, v0; \ - PADDQ t0, v0; \ - PADDQ t0, v0; \ - PXOR v0, v6; \ - PSHUFB c48, v6; \ - MOVO v4, t0; \ - PMULULQ v6, t0; \ - PADDQ v6, v4; \ - PADDQ t0, v4; \ - PADDQ t0, v4; \ - PXOR v4, v2; \ - MOVO v2, t0; \ - PADDQ v2, t0; \ - PSRLQ $63, v2; \ - PXOR t0, v2; \ - MOVO v1, t0; \ - PMULULQ v3, t0; \ - PADDQ v3, v1; \ - PADDQ t0, v1; \ - PADDQ t0, v1; \ - PXOR v1, v7; \ - PSHUFD $0xB1, v7, v7; \ - MOVO v5, t0; \ - PMULULQ v7, t0; \ - PADDQ v7, v5; \ - PADDQ t0, v5; \ - PADDQ t0, v5; \ - PXOR v5, v3; \ - PSHUFB c40, v3; \ - MOVO v1, t0; \ - PMULULQ v3, t0; \ - PADDQ v3, v1; \ - PADDQ t0, v1; \ - PADDQ t0, v1; \ - PXOR v1, v7; \ - PSHUFB c48, v7; \ - MOVO v5, t0; \ - PMULULQ v7, t0; \ - PADDQ v7, v5; \ - PADDQ t0, v5; \ - PADDQ t0, v5; \ - PXOR v5, v3; \ - MOVO v3, t0; \ - PADDQ v3, t0; \ - PSRLQ $63, v3; \ - PXOR t0, v3 - -#define LOAD_MSG_0(block, off) \ - MOVOU 8*(off+0)(block), X0; \ - MOVOU 8*(off+2)(block), X1; \ - MOVOU 8*(off+4)(block), X2; \ - MOVOU 8*(off+6)(block), X3; \ - MOVOU 8*(off+8)(block), X4; \ - MOVOU 8*(off+10)(block), X5; \ - MOVOU 8*(off+12)(block), X6; \ - MOVOU 8*(off+14)(block), X7 - -#define STORE_MSG_0(block, off) \ - MOVOU X0, 8*(off+0)(block); \ - MOVOU X1, 8*(off+2)(block); \ - MOVOU X2, 8*(off+4)(block); \ - MOVOU X3, 8*(off+6)(block); \ - MOVOU X4, 8*(off+8)(block); \ - MOVOU X5, 8*(off+10)(block); \ - MOVOU X6, 8*(off+12)(block); \ - MOVOU X7, 8*(off+14)(block) - -#define LOAD_MSG_1(block, off) \ - MOVOU 8*off+0*8(block), X0; \ - MOVOU 8*off+16*8(block), X1; \ - MOVOU 8*off+32*8(block), X2; \ - MOVOU 8*off+48*8(block), X3; \ - MOVOU 8*off+64*8(block), X4; \ - MOVOU 8*off+80*8(block), X5; \ - MOVOU 8*off+96*8(block), X6; \ - MOVOU 8*off+112*8(block), X7 - -#define STORE_MSG_1(block, off) \ - MOVOU X0, 8*off+0*8(block); \ - MOVOU X1, 8*off+16*8(block); \ - MOVOU X2, 8*off+32*8(block); \ - MOVOU X3, 8*off+48*8(block); \ - MOVOU X4, 8*off+64*8(block); \ - MOVOU X5, 8*off+80*8(block); \ - MOVOU X6, 8*off+96*8(block); \ - MOVOU X7, 8*off+112*8(block) - -#define BLAMKA_ROUND_0(block, off, t0, t1, c40, c48) \ - LOAD_MSG_0(block, off); \ - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ - SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \ - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \ - STORE_MSG_0(block, off) - -#define BLAMKA_ROUND_1(block, off, t0, t1, c40, c48) \ - LOAD_MSG_1(block, off); \ - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ - SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \ - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \ - STORE_MSG_1(block, off) - // func blamkaSSE4(b *block) -TEXT ·blamkaSSE4(SB), 4, $0-8 - MOVQ b+0(FP), AX - - MOVOU ·c40<>(SB), X10 - MOVOU ·c48<>(SB), X11 +// Requires: SSE2, SSSE3 +TEXT ·blamkaSSE4(SB), NOSPLIT, $0-8 + MOVQ b+0(FP), AX + MOVOU ·c40<>+0(SB), X10 + MOVOU ·c48<>+0(SB), X11 + MOVOU (AX), X0 + MOVOU 16(AX), X1 + MOVOU 32(AX), X2 + MOVOU 48(AX), X3 + MOVOU 64(AX), X4 + MOVOU 80(AX), X5 + MOVOU 96(AX), X6 + MOVOU 112(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, (AX) + MOVOU X1, 16(AX) + MOVOU X2, 32(AX) + MOVOU X3, 48(AX) + MOVOU X4, 64(AX) + MOVOU X5, 80(AX) + MOVOU X6, 96(AX) + MOVOU X7, 112(AX) + MOVOU 128(AX), X0 + MOVOU 144(AX), X1 + MOVOU 160(AX), X2 + MOVOU 176(AX), X3 + MOVOU 192(AX), X4 + MOVOU 208(AX), X5 + MOVOU 224(AX), X6 + MOVOU 240(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 128(AX) + MOVOU X1, 144(AX) + MOVOU X2, 160(AX) + MOVOU X3, 176(AX) + MOVOU X4, 192(AX) + MOVOU X5, 208(AX) + MOVOU X6, 224(AX) + MOVOU X7, 240(AX) + MOVOU 256(AX), X0 + MOVOU 272(AX), X1 + MOVOU 288(AX), X2 + MOVOU 304(AX), X3 + MOVOU 320(AX), X4 + MOVOU 336(AX), X5 + MOVOU 352(AX), X6 + MOVOU 368(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 256(AX) + MOVOU X1, 272(AX) + MOVOU X2, 288(AX) + MOVOU X3, 304(AX) + MOVOU X4, 320(AX) + MOVOU X5, 336(AX) + MOVOU X6, 352(AX) + MOVOU X7, 368(AX) + MOVOU 384(AX), X0 + MOVOU 400(AX), X1 + MOVOU 416(AX), X2 + MOVOU 432(AX), X3 + MOVOU 448(AX), X4 + MOVOU 464(AX), X5 + MOVOU 480(AX), X6 + MOVOU 496(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 384(AX) + MOVOU X1, 400(AX) + MOVOU X2, 416(AX) + MOVOU X3, 432(AX) + MOVOU X4, 448(AX) + MOVOU X5, 464(AX) + MOVOU X6, 480(AX) + MOVOU X7, 496(AX) + MOVOU 512(AX), X0 + MOVOU 528(AX), X1 + MOVOU 544(AX), X2 + MOVOU 560(AX), X3 + MOVOU 576(AX), X4 + MOVOU 592(AX), X5 + MOVOU 608(AX), X6 + MOVOU 624(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 512(AX) + MOVOU X1, 528(AX) + MOVOU X2, 544(AX) + MOVOU X3, 560(AX) + MOVOU X4, 576(AX) + MOVOU X5, 592(AX) + MOVOU X6, 608(AX) + MOVOU X7, 624(AX) + MOVOU 640(AX), X0 + MOVOU 656(AX), X1 + MOVOU 672(AX), X2 + MOVOU 688(AX), X3 + MOVOU 704(AX), X4 + MOVOU 720(AX), X5 + MOVOU 736(AX), X6 + MOVOU 752(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 640(AX) + MOVOU X1, 656(AX) + MOVOU X2, 672(AX) + MOVOU X3, 688(AX) + MOVOU X4, 704(AX) + MOVOU X5, 720(AX) + MOVOU X6, 736(AX) + MOVOU X7, 752(AX) + MOVOU 768(AX), X0 + MOVOU 784(AX), X1 + MOVOU 800(AX), X2 + MOVOU 816(AX), X3 + MOVOU 832(AX), X4 + MOVOU 848(AX), X5 + MOVOU 864(AX), X6 + MOVOU 880(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 768(AX) + MOVOU X1, 784(AX) + MOVOU X2, 800(AX) + MOVOU X3, 816(AX) + MOVOU X4, 832(AX) + MOVOU X5, 848(AX) + MOVOU X6, 864(AX) + MOVOU X7, 880(AX) + MOVOU 896(AX), X0 + MOVOU 912(AX), X1 + MOVOU 928(AX), X2 + MOVOU 944(AX), X3 + MOVOU 960(AX), X4 + MOVOU 976(AX), X5 + MOVOU 992(AX), X6 + MOVOU 1008(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 896(AX) + MOVOU X1, 912(AX) + MOVOU X2, 928(AX) + MOVOU X3, 944(AX) + MOVOU X4, 960(AX) + MOVOU X5, 976(AX) + MOVOU X6, 992(AX) + MOVOU X7, 1008(AX) + MOVOU (AX), X0 + MOVOU 128(AX), X1 + MOVOU 256(AX), X2 + MOVOU 384(AX), X3 + MOVOU 512(AX), X4 + MOVOU 640(AX), X5 + MOVOU 768(AX), X6 + MOVOU 896(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, (AX) + MOVOU X1, 128(AX) + MOVOU X2, 256(AX) + MOVOU X3, 384(AX) + MOVOU X4, 512(AX) + MOVOU X5, 640(AX) + MOVOU X6, 768(AX) + MOVOU X7, 896(AX) + MOVOU 16(AX), X0 + MOVOU 144(AX), X1 + MOVOU 272(AX), X2 + MOVOU 400(AX), X3 + MOVOU 528(AX), X4 + MOVOU 656(AX), X5 + MOVOU 784(AX), X6 + MOVOU 912(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 16(AX) + MOVOU X1, 144(AX) + MOVOU X2, 272(AX) + MOVOU X3, 400(AX) + MOVOU X4, 528(AX) + MOVOU X5, 656(AX) + MOVOU X6, 784(AX) + MOVOU X7, 912(AX) + MOVOU 32(AX), X0 + MOVOU 160(AX), X1 + MOVOU 288(AX), X2 + MOVOU 416(AX), X3 + MOVOU 544(AX), X4 + MOVOU 672(AX), X5 + MOVOU 800(AX), X6 + MOVOU 928(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 32(AX) + MOVOU X1, 160(AX) + MOVOU X2, 288(AX) + MOVOU X3, 416(AX) + MOVOU X4, 544(AX) + MOVOU X5, 672(AX) + MOVOU X6, 800(AX) + MOVOU X7, 928(AX) + MOVOU 48(AX), X0 + MOVOU 176(AX), X1 + MOVOU 304(AX), X2 + MOVOU 432(AX), X3 + MOVOU 560(AX), X4 + MOVOU 688(AX), X5 + MOVOU 816(AX), X6 + MOVOU 944(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 48(AX) + MOVOU X1, 176(AX) + MOVOU X2, 304(AX) + MOVOU X3, 432(AX) + MOVOU X4, 560(AX) + MOVOU X5, 688(AX) + MOVOU X6, 816(AX) + MOVOU X7, 944(AX) + MOVOU 64(AX), X0 + MOVOU 192(AX), X1 + MOVOU 320(AX), X2 + MOVOU 448(AX), X3 + MOVOU 576(AX), X4 + MOVOU 704(AX), X5 + MOVOU 832(AX), X6 + MOVOU 960(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 64(AX) + MOVOU X1, 192(AX) + MOVOU X2, 320(AX) + MOVOU X3, 448(AX) + MOVOU X4, 576(AX) + MOVOU X5, 704(AX) + MOVOU X6, 832(AX) + MOVOU X7, 960(AX) + MOVOU 80(AX), X0 + MOVOU 208(AX), X1 + MOVOU 336(AX), X2 + MOVOU 464(AX), X3 + MOVOU 592(AX), X4 + MOVOU 720(AX), X5 + MOVOU 848(AX), X6 + MOVOU 976(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 80(AX) + MOVOU X1, 208(AX) + MOVOU X2, 336(AX) + MOVOU X3, 464(AX) + MOVOU X4, 592(AX) + MOVOU X5, 720(AX) + MOVOU X6, 848(AX) + MOVOU X7, 976(AX) + MOVOU 96(AX), X0 + MOVOU 224(AX), X1 + MOVOU 352(AX), X2 + MOVOU 480(AX), X3 + MOVOU 608(AX), X4 + MOVOU 736(AX), X5 + MOVOU 864(AX), X6 + MOVOU 992(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 96(AX) + MOVOU X1, 224(AX) + MOVOU X2, 352(AX) + MOVOU X3, 480(AX) + MOVOU X4, 608(AX) + MOVOU X5, 736(AX) + MOVOU X6, 864(AX) + MOVOU X7, 992(AX) + MOVOU 112(AX), X0 + MOVOU 240(AX), X1 + MOVOU 368(AX), X2 + MOVOU 496(AX), X3 + MOVOU 624(AX), X4 + MOVOU 752(AX), X5 + MOVOU 880(AX), X6 + MOVOU 1008(AX), X7 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFD $0xb1, X6, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + PSHUFB X10, X2 + MOVO X0, X8 + PMULULQ X2, X8 + PADDQ X2, X0 + PADDQ X8, X0 + PADDQ X8, X0 + PXOR X0, X6 + PSHUFB X11, X6 + MOVO X4, X8 + PMULULQ X6, X8 + PADDQ X6, X4 + PADDQ X8, X4 + PADDQ X8, X4 + PXOR X4, X2 + MOVO X2, X8 + PADDQ X2, X8 + PSRLQ $0x3f, X2 + PXOR X8, X2 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFD $0xb1, X7, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + PSHUFB X10, X3 + MOVO X1, X8 + PMULULQ X3, X8 + PADDQ X3, X1 + PADDQ X8, X1 + PADDQ X8, X1 + PXOR X1, X7 + PSHUFB X11, X7 + MOVO X5, X8 + PMULULQ X7, X8 + PADDQ X7, X5 + PADDQ X8, X5 + PADDQ X8, X5 + PXOR X5, X3 + MOVO X3, X8 + PADDQ X3, X8 + PSRLQ $0x3f, X3 + PXOR X8, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU X0, 112(AX) + MOVOU X1, 240(AX) + MOVOU X2, 368(AX) + MOVOU X3, 496(AX) + MOVOU X4, 624(AX) + MOVOU X5, 752(AX) + MOVOU X6, 880(AX) + MOVOU X7, 1008(AX) + RET - BLAMKA_ROUND_0(AX, 0, X8, X9, X10, X11) - BLAMKA_ROUND_0(AX, 16, X8, X9, X10, X11) - BLAMKA_ROUND_0(AX, 32, X8, X9, X10, X11) - BLAMKA_ROUND_0(AX, 48, X8, X9, X10, X11) - BLAMKA_ROUND_0(AX, 64, X8, X9, X10, X11) - BLAMKA_ROUND_0(AX, 80, X8, X9, X10, X11) - BLAMKA_ROUND_0(AX, 96, X8, X9, X10, X11) - BLAMKA_ROUND_0(AX, 112, X8, X9, X10, X11) +DATA ·c40<>+0(SB)/8, $0x0201000706050403 +DATA ·c40<>+8(SB)/8, $0x0a09080f0e0d0c0b +GLOBL ·c40<>(SB), RODATA|NOPTR, $16 - BLAMKA_ROUND_1(AX, 0, X8, X9, X10, X11) - BLAMKA_ROUND_1(AX, 2, X8, X9, X10, X11) - BLAMKA_ROUND_1(AX, 4, X8, X9, X10, X11) - BLAMKA_ROUND_1(AX, 6, X8, X9, X10, X11) - BLAMKA_ROUND_1(AX, 8, X8, X9, X10, X11) - BLAMKA_ROUND_1(AX, 10, X8, X9, X10, X11) - BLAMKA_ROUND_1(AX, 12, X8, X9, X10, X11) - BLAMKA_ROUND_1(AX, 14, X8, X9, X10, X11) - RET +DATA ·c48<>+0(SB)/8, $0x0100070605040302 +DATA ·c48<>+8(SB)/8, $0x09080f0e0d0c0b0a +GLOBL ·c48<>(SB), RODATA|NOPTR, $16 -// func mixBlocksSSE2(out, a, b, c *block) -TEXT ·mixBlocksSSE2(SB), 4, $0-32 +// func mixBlocksSSE2(out *block, a *block, b *block, c *block) +// Requires: SSE2 +TEXT ·mixBlocksSSE2(SB), NOSPLIT, $0-32 MOVQ out+0(FP), DX MOVQ a+8(FP), AX MOVQ b+16(FP), BX MOVQ c+24(FP), CX - MOVQ $128, DI + MOVQ $0x00000080, DI loop: - MOVOU 0(AX), X0 - MOVOU 0(BX), X1 - MOVOU 0(CX), X2 + MOVOU (AX), X0 + MOVOU (BX), X1 + MOVOU (CX), X2 PXOR X1, X0 PXOR X2, X0 - MOVOU X0, 0(DX) - ADDQ $16, AX - ADDQ $16, BX - ADDQ $16, CX - ADDQ $16, DX - SUBQ $2, DI + MOVOU X0, (DX) + ADDQ $0x10, AX + ADDQ $0x10, BX + ADDQ $0x10, CX + ADDQ $0x10, DX + SUBQ $0x02, DI JA loop RET -// func xorBlocksSSE2(out, a, b, c *block) -TEXT ·xorBlocksSSE2(SB), 4, $0-32 +// func xorBlocksSSE2(out *block, a *block, b *block, c *block) +// Requires: SSE2 +TEXT ·xorBlocksSSE2(SB), NOSPLIT, $0-32 MOVQ out+0(FP), DX MOVQ a+8(FP), AX MOVQ b+16(FP), BX MOVQ c+24(FP), CX - MOVQ $128, DI + MOVQ $0x00000080, DI loop: - MOVOU 0(AX), X0 - MOVOU 0(BX), X1 - MOVOU 0(CX), X2 - MOVOU 0(DX), X3 + MOVOU (AX), X0 + MOVOU (BX), X1 + MOVOU (CX), X2 + MOVOU (DX), X3 PXOR X1, X0 PXOR X2, X0 PXOR X3, X0 - MOVOU X0, 0(DX) - ADDQ $16, AX - ADDQ $16, BX - ADDQ $16, CX - ADDQ $16, DX - SUBQ $2, DI + MOVOU X0, (DX) + ADDQ $0x10, AX + ADDQ $0x10, BX + ADDQ $0x10, CX + ADDQ $0x10, DX + SUBQ $0x02, DI JA loop RET diff --git a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s index 9ae8206c20..f75162e039 100644 --- a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s +++ b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s @@ -1,722 +1,4517 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Code generated by command: go run blake2bAVX2_amd64_asm.go -out ../../blake2bAVX2_amd64.s -pkg blake2b. DO NOT EDIT. //go:build amd64 && gc && !purego #include "textflag.h" -DATA ·AVX2_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908 -DATA ·AVX2_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b -DATA ·AVX2_iv0<>+0x10(SB)/8, $0x3c6ef372fe94f82b -DATA ·AVX2_iv0<>+0x18(SB)/8, $0xa54ff53a5f1d36f1 -GLOBL ·AVX2_iv0<>(SB), (NOPTR+RODATA), $32 - -DATA ·AVX2_iv1<>+0x00(SB)/8, $0x510e527fade682d1 -DATA ·AVX2_iv1<>+0x08(SB)/8, $0x9b05688c2b3e6c1f -DATA ·AVX2_iv1<>+0x10(SB)/8, $0x1f83d9abfb41bd6b -DATA ·AVX2_iv1<>+0x18(SB)/8, $0x5be0cd19137e2179 -GLOBL ·AVX2_iv1<>(SB), (NOPTR+RODATA), $32 - -DATA ·AVX2_c40<>+0x00(SB)/8, $0x0201000706050403 -DATA ·AVX2_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b -DATA ·AVX2_c40<>+0x10(SB)/8, $0x0201000706050403 -DATA ·AVX2_c40<>+0x18(SB)/8, $0x0a09080f0e0d0c0b -GLOBL ·AVX2_c40<>(SB), (NOPTR+RODATA), $32 - -DATA ·AVX2_c48<>+0x00(SB)/8, $0x0100070605040302 -DATA ·AVX2_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a -DATA ·AVX2_c48<>+0x10(SB)/8, $0x0100070605040302 -DATA ·AVX2_c48<>+0x18(SB)/8, $0x09080f0e0d0c0b0a -GLOBL ·AVX2_c48<>(SB), (NOPTR+RODATA), $32 - -DATA ·AVX_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908 -DATA ·AVX_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b -GLOBL ·AVX_iv0<>(SB), (NOPTR+RODATA), $16 - -DATA ·AVX_iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b -DATA ·AVX_iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1 -GLOBL ·AVX_iv1<>(SB), (NOPTR+RODATA), $16 - -DATA ·AVX_iv2<>+0x00(SB)/8, $0x510e527fade682d1 -DATA ·AVX_iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f -GLOBL ·AVX_iv2<>(SB), (NOPTR+RODATA), $16 - -DATA ·AVX_iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b -DATA ·AVX_iv3<>+0x08(SB)/8, $0x5be0cd19137e2179 -GLOBL ·AVX_iv3<>(SB), (NOPTR+RODATA), $16 - -DATA ·AVX_c40<>+0x00(SB)/8, $0x0201000706050403 -DATA ·AVX_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b -GLOBL ·AVX_c40<>(SB), (NOPTR+RODATA), $16 - -DATA ·AVX_c48<>+0x00(SB)/8, $0x0100070605040302 -DATA ·AVX_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a -GLOBL ·AVX_c48<>(SB), (NOPTR+RODATA), $16 - -#define VPERMQ_0x39_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x39 -#define VPERMQ_0x93_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x93 -#define VPERMQ_0x4E_Y2_Y2 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2; BYTE $0x4e -#define VPERMQ_0x93_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x93 -#define VPERMQ_0x39_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x39 - -#define ROUND_AVX2(m0, m1, m2, m3, t, c40, c48) \ - VPADDQ m0, Y0, Y0; \ - VPADDQ Y1, Y0, Y0; \ - VPXOR Y0, Y3, Y3; \ - VPSHUFD $-79, Y3, Y3; \ - VPADDQ Y3, Y2, Y2; \ - VPXOR Y2, Y1, Y1; \ - VPSHUFB c40, Y1, Y1; \ - VPADDQ m1, Y0, Y0; \ - VPADDQ Y1, Y0, Y0; \ - VPXOR Y0, Y3, Y3; \ - VPSHUFB c48, Y3, Y3; \ - VPADDQ Y3, Y2, Y2; \ - VPXOR Y2, Y1, Y1; \ - VPADDQ Y1, Y1, t; \ - VPSRLQ $63, Y1, Y1; \ - VPXOR t, Y1, Y1; \ - VPERMQ_0x39_Y1_Y1; \ - VPERMQ_0x4E_Y2_Y2; \ - VPERMQ_0x93_Y3_Y3; \ - VPADDQ m2, Y0, Y0; \ - VPADDQ Y1, Y0, Y0; \ - VPXOR Y0, Y3, Y3; \ - VPSHUFD $-79, Y3, Y3; \ - VPADDQ Y3, Y2, Y2; \ - VPXOR Y2, Y1, Y1; \ - VPSHUFB c40, Y1, Y1; \ - VPADDQ m3, Y0, Y0; \ - VPADDQ Y1, Y0, Y0; \ - VPXOR Y0, Y3, Y3; \ - VPSHUFB c48, Y3, Y3; \ - VPADDQ Y3, Y2, Y2; \ - VPXOR Y2, Y1, Y1; \ - VPADDQ Y1, Y1, t; \ - VPSRLQ $63, Y1, Y1; \ - VPXOR t, Y1, Y1; \ - VPERMQ_0x39_Y3_Y3; \ - VPERMQ_0x4E_Y2_Y2; \ - VPERMQ_0x93_Y1_Y1 - -#define VMOVQ_SI_X11_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x1E -#define VMOVQ_SI_X12_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x26 -#define VMOVQ_SI_X13_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x2E -#define VMOVQ_SI_X14_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x36 -#define VMOVQ_SI_X15_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x3E - -#define VMOVQ_SI_X11(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x5E; BYTE $n -#define VMOVQ_SI_X12(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x66; BYTE $n -#define VMOVQ_SI_X13(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x6E; BYTE $n -#define VMOVQ_SI_X14(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x76; BYTE $n -#define VMOVQ_SI_X15(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x7E; BYTE $n - -#define VPINSRQ_1_SI_X11_0 BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x1E; BYTE $0x01 -#define VPINSRQ_1_SI_X12_0 BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x26; BYTE $0x01 -#define VPINSRQ_1_SI_X13_0 BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x2E; BYTE $0x01 -#define VPINSRQ_1_SI_X14_0 BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x36; BYTE $0x01 -#define VPINSRQ_1_SI_X15_0 BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x3E; BYTE $0x01 - -#define VPINSRQ_1_SI_X11(n) BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x5E; BYTE $n; BYTE $0x01 -#define VPINSRQ_1_SI_X12(n) BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x66; BYTE $n; BYTE $0x01 -#define VPINSRQ_1_SI_X13(n) BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x6E; BYTE $n; BYTE $0x01 -#define VPINSRQ_1_SI_X14(n) BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x76; BYTE $n; BYTE $0x01 -#define VPINSRQ_1_SI_X15(n) BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x7E; BYTE $n; BYTE $0x01 - -#define VMOVQ_R8_X15 BYTE $0xC4; BYTE $0x41; BYTE $0xF9; BYTE $0x6E; BYTE $0xF8 -#define VPINSRQ_1_R9_X15 BYTE $0xC4; BYTE $0x43; BYTE $0x81; BYTE $0x22; BYTE $0xF9; BYTE $0x01 - -// load msg: Y12 = (i0, i1, i2, i3) -// i0, i1, i2, i3 must not be 0 -#define LOAD_MSG_AVX2_Y12(i0, i1, i2, i3) \ - VMOVQ_SI_X12(i0*8); \ - VMOVQ_SI_X11(i2*8); \ - VPINSRQ_1_SI_X12(i1*8); \ - VPINSRQ_1_SI_X11(i3*8); \ - VINSERTI128 $1, X11, Y12, Y12 - -// load msg: Y13 = (i0, i1, i2, i3) -// i0, i1, i2, i3 must not be 0 -#define LOAD_MSG_AVX2_Y13(i0, i1, i2, i3) \ - VMOVQ_SI_X13(i0*8); \ - VMOVQ_SI_X11(i2*8); \ - VPINSRQ_1_SI_X13(i1*8); \ - VPINSRQ_1_SI_X11(i3*8); \ - VINSERTI128 $1, X11, Y13, Y13 - -// load msg: Y14 = (i0, i1, i2, i3) -// i0, i1, i2, i3 must not be 0 -#define LOAD_MSG_AVX2_Y14(i0, i1, i2, i3) \ - VMOVQ_SI_X14(i0*8); \ - VMOVQ_SI_X11(i2*8); \ - VPINSRQ_1_SI_X14(i1*8); \ - VPINSRQ_1_SI_X11(i3*8); \ - VINSERTI128 $1, X11, Y14, Y14 - -// load msg: Y15 = (i0, i1, i2, i3) -// i0, i1, i2, i3 must not be 0 -#define LOAD_MSG_AVX2_Y15(i0, i1, i2, i3) \ - VMOVQ_SI_X15(i0*8); \ - VMOVQ_SI_X11(i2*8); \ - VPINSRQ_1_SI_X15(i1*8); \ - VPINSRQ_1_SI_X11(i3*8); \ - VINSERTI128 $1, X11, Y15, Y15 - -#define LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15() \ - VMOVQ_SI_X12_0; \ - VMOVQ_SI_X11(4*8); \ - VPINSRQ_1_SI_X12(2*8); \ - VPINSRQ_1_SI_X11(6*8); \ - VINSERTI128 $1, X11, Y12, Y12; \ - LOAD_MSG_AVX2_Y13(1, 3, 5, 7); \ - LOAD_MSG_AVX2_Y14(8, 10, 12, 14); \ - LOAD_MSG_AVX2_Y15(9, 11, 13, 15) - -#define LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3() \ - LOAD_MSG_AVX2_Y12(14, 4, 9, 13); \ - LOAD_MSG_AVX2_Y13(10, 8, 15, 6); \ - VMOVQ_SI_X11(11*8); \ - VPSHUFD $0x4E, 0*8(SI), X14; \ - VPINSRQ_1_SI_X11(5*8); \ - VINSERTI128 $1, X11, Y14, Y14; \ - LOAD_MSG_AVX2_Y15(12, 2, 7, 3) - -#define LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4() \ - VMOVQ_SI_X11(5*8); \ - VMOVDQU 11*8(SI), X12; \ - VPINSRQ_1_SI_X11(15*8); \ - VINSERTI128 $1, X11, Y12, Y12; \ - VMOVQ_SI_X13(8*8); \ - VMOVQ_SI_X11(2*8); \ - VPINSRQ_1_SI_X13_0; \ - VPINSRQ_1_SI_X11(13*8); \ - VINSERTI128 $1, X11, Y13, Y13; \ - LOAD_MSG_AVX2_Y14(10, 3, 7, 9); \ - LOAD_MSG_AVX2_Y15(14, 6, 1, 4) - -#define LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8() \ - LOAD_MSG_AVX2_Y12(7, 3, 13, 11); \ - LOAD_MSG_AVX2_Y13(9, 1, 12, 14); \ - LOAD_MSG_AVX2_Y14(2, 5, 4, 15); \ - VMOVQ_SI_X15(6*8); \ - VMOVQ_SI_X11_0; \ - VPINSRQ_1_SI_X15(10*8); \ - VPINSRQ_1_SI_X11(8*8); \ - VINSERTI128 $1, X11, Y15, Y15 - -#define LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13() \ - LOAD_MSG_AVX2_Y12(9, 5, 2, 10); \ - VMOVQ_SI_X13_0; \ - VMOVQ_SI_X11(4*8); \ - VPINSRQ_1_SI_X13(7*8); \ - VPINSRQ_1_SI_X11(15*8); \ - VINSERTI128 $1, X11, Y13, Y13; \ - LOAD_MSG_AVX2_Y14(14, 11, 6, 3); \ - LOAD_MSG_AVX2_Y15(1, 12, 8, 13) - -#define LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9() \ - VMOVQ_SI_X12(2*8); \ - VMOVQ_SI_X11_0; \ - VPINSRQ_1_SI_X12(6*8); \ - VPINSRQ_1_SI_X11(8*8); \ - VINSERTI128 $1, X11, Y12, Y12; \ - LOAD_MSG_AVX2_Y13(12, 10, 11, 3); \ - LOAD_MSG_AVX2_Y14(4, 7, 15, 1); \ - LOAD_MSG_AVX2_Y15(13, 5, 14, 9) - -#define LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11() \ - LOAD_MSG_AVX2_Y12(12, 1, 14, 4); \ - LOAD_MSG_AVX2_Y13(5, 15, 13, 10); \ - VMOVQ_SI_X14_0; \ - VPSHUFD $0x4E, 8*8(SI), X11; \ - VPINSRQ_1_SI_X14(6*8); \ - VINSERTI128 $1, X11, Y14, Y14; \ - LOAD_MSG_AVX2_Y15(7, 3, 2, 11) - -#define LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10() \ - LOAD_MSG_AVX2_Y12(13, 7, 12, 3); \ - LOAD_MSG_AVX2_Y13(11, 14, 1, 9); \ - LOAD_MSG_AVX2_Y14(5, 15, 8, 2); \ - VMOVQ_SI_X15_0; \ - VMOVQ_SI_X11(6*8); \ - VPINSRQ_1_SI_X15(4*8); \ - VPINSRQ_1_SI_X11(10*8); \ - VINSERTI128 $1, X11, Y15, Y15 - -#define LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5() \ - VMOVQ_SI_X12(6*8); \ - VMOVQ_SI_X11(11*8); \ - VPINSRQ_1_SI_X12(14*8); \ - VPINSRQ_1_SI_X11_0; \ - VINSERTI128 $1, X11, Y12, Y12; \ - LOAD_MSG_AVX2_Y13(15, 9, 3, 8); \ - VMOVQ_SI_X11(1*8); \ - VMOVDQU 12*8(SI), X14; \ - VPINSRQ_1_SI_X11(10*8); \ - VINSERTI128 $1, X11, Y14, Y14; \ - VMOVQ_SI_X15(2*8); \ - VMOVDQU 4*8(SI), X11; \ - VPINSRQ_1_SI_X15(7*8); \ - VINSERTI128 $1, X11, Y15, Y15 - -#define LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0() \ - LOAD_MSG_AVX2_Y12(10, 8, 7, 1); \ - VMOVQ_SI_X13(2*8); \ - VPSHUFD $0x4E, 5*8(SI), X11; \ - VPINSRQ_1_SI_X13(4*8); \ - VINSERTI128 $1, X11, Y13, Y13; \ - LOAD_MSG_AVX2_Y14(15, 9, 3, 13); \ - VMOVQ_SI_X15(11*8); \ - VMOVQ_SI_X11(12*8); \ - VPINSRQ_1_SI_X15(14*8); \ - VPINSRQ_1_SI_X11_0; \ - VINSERTI128 $1, X11, Y15, Y15 - // func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) -TEXT ·hashBlocksAVX2(SB), 4, $320-48 // frame size = 288 + 32 byte alignment - MOVQ h+0(FP), AX - MOVQ c+8(FP), BX - MOVQ flag+16(FP), CX - MOVQ blocks_base+24(FP), SI - MOVQ blocks_len+32(FP), DI - - MOVQ SP, DX - ADDQ $31, DX - ANDQ $~31, DX - - MOVQ CX, 16(DX) - XORQ CX, CX - MOVQ CX, 24(DX) - - VMOVDQU ·AVX2_c40<>(SB), Y4 - VMOVDQU ·AVX2_c48<>(SB), Y5 - - VMOVDQU 0(AX), Y8 +// Requires: AVX, AVX2 +TEXT ·hashBlocksAVX2(SB), NOSPLIT, $320-48 + MOVQ h+0(FP), AX + MOVQ c+8(FP), BX + MOVQ flag+16(FP), CX + MOVQ blocks_base+24(FP), SI + MOVQ blocks_len+32(FP), DI + MOVQ SP, DX + ADDQ $+31, DX + ANDQ $-32, DX + MOVQ CX, 16(DX) + XORQ CX, CX + MOVQ CX, 24(DX) + VMOVDQU ·AVX2_c40<>+0(SB), Y4 + VMOVDQU ·AVX2_c48<>+0(SB), Y5 + VMOVDQU (AX), Y8 VMOVDQU 32(AX), Y9 - VMOVDQU ·AVX2_iv0<>(SB), Y6 - VMOVDQU ·AVX2_iv1<>(SB), Y7 - - MOVQ 0(BX), R8 - MOVQ 8(BX), R9 - MOVQ R9, 8(DX) + VMOVDQU ·AVX2_iv0<>+0(SB), Y6 + VMOVDQU ·AVX2_iv1<>+0(SB), Y7 + MOVQ (BX), R8 + MOVQ 8(BX), R9 + MOVQ R9, 8(DX) loop: - ADDQ $128, R8 - MOVQ R8, 0(DX) - CMPQ R8, $128 + ADDQ $0x80, R8 + MOVQ R8, (DX) + CMPQ R8, $0x80 JGE noinc INCQ R9 MOVQ R9, 8(DX) noinc: - VMOVDQA Y8, Y0 - VMOVDQA Y9, Y1 - VMOVDQA Y6, Y2 - VPXOR 0(DX), Y7, Y3 - - LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15() - VMOVDQA Y12, 32(DX) - VMOVDQA Y13, 64(DX) - VMOVDQA Y14, 96(DX) - VMOVDQA Y15, 128(DX) - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3() - VMOVDQA Y12, 160(DX) - VMOVDQA Y13, 192(DX) - VMOVDQA Y14, 224(DX) - VMOVDQA Y15, 256(DX) - - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4() - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8() - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13() - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9() - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11() - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10() - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5() - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0() - ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) - - ROUND_AVX2(32(DX), 64(DX), 96(DX), 128(DX), Y10, Y4, Y5) - ROUND_AVX2(160(DX), 192(DX), 224(DX), 256(DX), Y10, Y4, Y5) - - VPXOR Y0, Y8, Y8 - VPXOR Y1, Y9, Y9 - VPXOR Y2, Y8, Y8 - VPXOR Y3, Y9, Y9 - - LEAQ 128(SI), SI - SUBQ $128, DI - JNE loop - - MOVQ R8, 0(BX) - MOVQ R9, 8(BX) - - VMOVDQU Y8, 0(AX) - VMOVDQU Y9, 32(AX) + VMOVDQA Y8, Y0 + VMOVDQA Y9, Y1 + VMOVDQA Y6, Y2 + VPXOR (DX), Y7, Y3 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x26 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x20 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x10 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x30 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x08 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x28 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x38 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x40 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x60 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x50 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x70 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x48 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x68 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x58 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x78 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VMOVDQA Y12, 32(DX) + VMOVDQA Y13, 64(DX) + VMOVDQA Y14, 96(DX) + VMOVDQA Y15, 128(DX) + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x70 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x48 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x20 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x68 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x50 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x78 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x40 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x30 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x58 + VPSHUFD $0x4e, (SI), X14 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x28 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x60 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x38 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x10 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x18 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VMOVDQA Y12, 160(DX) + VMOVDQA Y13, 192(DX) + VMOVDQA Y14, 224(DX) + VMOVDQA Y15, 256(DX) + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x28 + VMOVDQU 88(SI), X12 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x78 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x40 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x10 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x2e + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x68 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x50 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x38 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x48 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x70 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x08 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x30 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x20 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x38 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x68 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x58 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x48 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x60 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x08 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x70 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x10 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x20 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x28 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x78 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x30 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x1e + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x50 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x40 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x48 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x10 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x28 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x50 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x2e + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x20 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x38 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x78 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x70 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x30 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x58 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x18 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x08 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x40 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x60 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x68 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x10 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x1e + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x30 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x40 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x60 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x58 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x50 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x18 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x20 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x78 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x38 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x08 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x68 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x70 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x28 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x48 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x60 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x70 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x08 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x20 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x28 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x68 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x78 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x50 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x36 + VPSHUFD $0x4e, 64(SI), X11 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x30 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x38 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x10 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x58 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x68 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x60 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x38 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x18 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x58 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x08 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x70 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x48 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x28 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x40 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x78 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x10 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x3e + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x30 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x20 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x50 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x30 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x58 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x70 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x1e + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x78 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x18 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x48 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x40 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x08 + VMOVDQU 96(SI), X14 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x50 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x10 + VMOVDQU 32(SI), X11 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x38 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x50 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x38 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x40 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x08 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y12, Y12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x10 + VPSHUFD $0x4e, 40(SI), X11 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x20 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y13, Y13 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x78 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x18 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x48 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x5e + BYTE $0x68 + BYTE $0x01 + VINSERTI128 $0x01, X11, Y14, Y14 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x58 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x5e + BYTE $0x60 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x70 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0xa1 + BYTE $0x22 + BYTE $0x1e + BYTE $0x01 + VINSERTI128 $0x01, X11, Y15, Y15 + VPADDQ Y12, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y13, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ Y14, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ Y15, Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + VPADDQ 32(DX), Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ 64(DX), Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ 96(DX), Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ 128(DX), Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + VPADDQ 160(DX), Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ 192(DX), Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x93 + VPADDQ 224(DX), Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFD $-79, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPSHUFB Y4, Y1, Y1 + VPADDQ 256(DX), Y0, Y0 + VPADDQ Y1, Y0, Y0 + VPXOR Y0, Y3, Y3 + VPSHUFB Y5, Y3, Y3 + VPADDQ Y3, Y2, Y2 + VPXOR Y2, Y1, Y1 + VPADDQ Y1, Y1, Y10 + VPSRLQ $0x3f, Y1, Y1 + VPXOR Y10, Y1, Y1 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xdb + BYTE $0x39 + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xd2 + BYTE $0x4e + BYTE $0xc4 + BYTE $0xe3 + BYTE $0xfd + BYTE $0x00 + BYTE $0xc9 + BYTE $0x93 + VPXOR Y0, Y8, Y8 + VPXOR Y1, Y9, Y9 + VPXOR Y2, Y8, Y8 + VPXOR Y3, Y9, Y9 + LEAQ 128(SI), SI + SUBQ $0x80, DI + JNE loop + MOVQ R8, (BX) + MOVQ R9, 8(BX) + VMOVDQU Y8, (AX) + VMOVDQU Y9, 32(AX) VZEROUPPER - RET -#define VPUNPCKLQDQ_X2_X2_X15 BYTE $0xC5; BYTE $0x69; BYTE $0x6C; BYTE $0xFA -#define VPUNPCKLQDQ_X3_X3_X15 BYTE $0xC5; BYTE $0x61; BYTE $0x6C; BYTE $0xFB -#define VPUNPCKLQDQ_X7_X7_X15 BYTE $0xC5; BYTE $0x41; BYTE $0x6C; BYTE $0xFF -#define VPUNPCKLQDQ_X13_X13_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x11; BYTE $0x6C; BYTE $0xFD -#define VPUNPCKLQDQ_X14_X14_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x09; BYTE $0x6C; BYTE $0xFE - -#define VPUNPCKHQDQ_X15_X2_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x69; BYTE $0x6D; BYTE $0xD7 -#define VPUNPCKHQDQ_X15_X3_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xDF -#define VPUNPCKHQDQ_X15_X6_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x49; BYTE $0x6D; BYTE $0xF7 -#define VPUNPCKHQDQ_X15_X7_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xFF -#define VPUNPCKHQDQ_X15_X3_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xD7 -#define VPUNPCKHQDQ_X15_X7_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xF7 -#define VPUNPCKHQDQ_X15_X13_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xDF -#define VPUNPCKHQDQ_X15_X13_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xFF - -#define SHUFFLE_AVX() \ - VMOVDQA X6, X13; \ - VMOVDQA X2, X14; \ - VMOVDQA X4, X6; \ - VPUNPCKLQDQ_X13_X13_X15; \ - VMOVDQA X5, X4; \ - VMOVDQA X6, X5; \ - VPUNPCKHQDQ_X15_X7_X6; \ - VPUNPCKLQDQ_X7_X7_X15; \ - VPUNPCKHQDQ_X15_X13_X7; \ - VPUNPCKLQDQ_X3_X3_X15; \ - VPUNPCKHQDQ_X15_X2_X2; \ - VPUNPCKLQDQ_X14_X14_X15; \ - VPUNPCKHQDQ_X15_X3_X3; \ - -#define SHUFFLE_AVX_INV() \ - VMOVDQA X2, X13; \ - VMOVDQA X4, X14; \ - VPUNPCKLQDQ_X2_X2_X15; \ - VMOVDQA X5, X4; \ - VPUNPCKHQDQ_X15_X3_X2; \ - VMOVDQA X14, X5; \ - VPUNPCKLQDQ_X3_X3_X15; \ - VMOVDQA X6, X14; \ - VPUNPCKHQDQ_X15_X13_X3; \ - VPUNPCKLQDQ_X7_X7_X15; \ - VPUNPCKHQDQ_X15_X6_X6; \ - VPUNPCKLQDQ_X14_X14_X15; \ - VPUNPCKHQDQ_X15_X7_X7; \ - -#define HALF_ROUND_AVX(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \ - VPADDQ m0, v0, v0; \ - VPADDQ v2, v0, v0; \ - VPADDQ m1, v1, v1; \ - VPADDQ v3, v1, v1; \ - VPXOR v0, v6, v6; \ - VPXOR v1, v7, v7; \ - VPSHUFD $-79, v6, v6; \ - VPSHUFD $-79, v7, v7; \ - VPADDQ v6, v4, v4; \ - VPADDQ v7, v5, v5; \ - VPXOR v4, v2, v2; \ - VPXOR v5, v3, v3; \ - VPSHUFB c40, v2, v2; \ - VPSHUFB c40, v3, v3; \ - VPADDQ m2, v0, v0; \ - VPADDQ v2, v0, v0; \ - VPADDQ m3, v1, v1; \ - VPADDQ v3, v1, v1; \ - VPXOR v0, v6, v6; \ - VPXOR v1, v7, v7; \ - VPSHUFB c48, v6, v6; \ - VPSHUFB c48, v7, v7; \ - VPADDQ v6, v4, v4; \ - VPADDQ v7, v5, v5; \ - VPXOR v4, v2, v2; \ - VPXOR v5, v3, v3; \ - VPADDQ v2, v2, t0; \ - VPSRLQ $63, v2, v2; \ - VPXOR t0, v2, v2; \ - VPADDQ v3, v3, t0; \ - VPSRLQ $63, v3, v3; \ - VPXOR t0, v3, v3 - -// load msg: X12 = (i0, i1), X13 = (i2, i3), X14 = (i4, i5), X15 = (i6, i7) -// i0, i1, i2, i3, i4, i5, i6, i7 must not be 0 -#define LOAD_MSG_AVX(i0, i1, i2, i3, i4, i5, i6, i7) \ - VMOVQ_SI_X12(i0*8); \ - VMOVQ_SI_X13(i2*8); \ - VMOVQ_SI_X14(i4*8); \ - VMOVQ_SI_X15(i6*8); \ - VPINSRQ_1_SI_X12(i1*8); \ - VPINSRQ_1_SI_X13(i3*8); \ - VPINSRQ_1_SI_X14(i5*8); \ - VPINSRQ_1_SI_X15(i7*8) - -// load msg: X12 = (0, 2), X13 = (4, 6), X14 = (1, 3), X15 = (5, 7) -#define LOAD_MSG_AVX_0_2_4_6_1_3_5_7() \ - VMOVQ_SI_X12_0; \ - VMOVQ_SI_X13(4*8); \ - VMOVQ_SI_X14(1*8); \ - VMOVQ_SI_X15(5*8); \ - VPINSRQ_1_SI_X12(2*8); \ - VPINSRQ_1_SI_X13(6*8); \ - VPINSRQ_1_SI_X14(3*8); \ - VPINSRQ_1_SI_X15(7*8) - -// load msg: X12 = (1, 0), X13 = (11, 5), X14 = (12, 2), X15 = (7, 3) -#define LOAD_MSG_AVX_1_0_11_5_12_2_7_3() \ - VPSHUFD $0x4E, 0*8(SI), X12; \ - VMOVQ_SI_X13(11*8); \ - VMOVQ_SI_X14(12*8); \ - VMOVQ_SI_X15(7*8); \ - VPINSRQ_1_SI_X13(5*8); \ - VPINSRQ_1_SI_X14(2*8); \ - VPINSRQ_1_SI_X15(3*8) - -// load msg: X12 = (11, 12), X13 = (5, 15), X14 = (8, 0), X15 = (2, 13) -#define LOAD_MSG_AVX_11_12_5_15_8_0_2_13() \ - VMOVDQU 11*8(SI), X12; \ - VMOVQ_SI_X13(5*8); \ - VMOVQ_SI_X14(8*8); \ - VMOVQ_SI_X15(2*8); \ - VPINSRQ_1_SI_X13(15*8); \ - VPINSRQ_1_SI_X14_0; \ - VPINSRQ_1_SI_X15(13*8) - -// load msg: X12 = (2, 5), X13 = (4, 15), X14 = (6, 10), X15 = (0, 8) -#define LOAD_MSG_AVX_2_5_4_15_6_10_0_8() \ - VMOVQ_SI_X12(2*8); \ - VMOVQ_SI_X13(4*8); \ - VMOVQ_SI_X14(6*8); \ - VMOVQ_SI_X15_0; \ - VPINSRQ_1_SI_X12(5*8); \ - VPINSRQ_1_SI_X13(15*8); \ - VPINSRQ_1_SI_X14(10*8); \ - VPINSRQ_1_SI_X15(8*8) +DATA ·AVX2_c40<>+0(SB)/8, $0x0201000706050403 +DATA ·AVX2_c40<>+8(SB)/8, $0x0a09080f0e0d0c0b +DATA ·AVX2_c40<>+16(SB)/8, $0x0201000706050403 +DATA ·AVX2_c40<>+24(SB)/8, $0x0a09080f0e0d0c0b +GLOBL ·AVX2_c40<>(SB), RODATA|NOPTR, $32 -// load msg: X12 = (9, 5), X13 = (2, 10), X14 = (0, 7), X15 = (4, 15) -#define LOAD_MSG_AVX_9_5_2_10_0_7_4_15() \ - VMOVQ_SI_X12(9*8); \ - VMOVQ_SI_X13(2*8); \ - VMOVQ_SI_X14_0; \ - VMOVQ_SI_X15(4*8); \ - VPINSRQ_1_SI_X12(5*8); \ - VPINSRQ_1_SI_X13(10*8); \ - VPINSRQ_1_SI_X14(7*8); \ - VPINSRQ_1_SI_X15(15*8) +DATA ·AVX2_c48<>+0(SB)/8, $0x0100070605040302 +DATA ·AVX2_c48<>+8(SB)/8, $0x09080f0e0d0c0b0a +DATA ·AVX2_c48<>+16(SB)/8, $0x0100070605040302 +DATA ·AVX2_c48<>+24(SB)/8, $0x09080f0e0d0c0b0a +GLOBL ·AVX2_c48<>(SB), RODATA|NOPTR, $32 -// load msg: X12 = (2, 6), X13 = (0, 8), X14 = (12, 10), X15 = (11, 3) -#define LOAD_MSG_AVX_2_6_0_8_12_10_11_3() \ - VMOVQ_SI_X12(2*8); \ - VMOVQ_SI_X13_0; \ - VMOVQ_SI_X14(12*8); \ - VMOVQ_SI_X15(11*8); \ - VPINSRQ_1_SI_X12(6*8); \ - VPINSRQ_1_SI_X13(8*8); \ - VPINSRQ_1_SI_X14(10*8); \ - VPINSRQ_1_SI_X15(3*8) +DATA ·AVX2_iv0<>+0(SB)/8, $0x6a09e667f3bcc908 +DATA ·AVX2_iv0<>+8(SB)/8, $0xbb67ae8584caa73b +DATA ·AVX2_iv0<>+16(SB)/8, $0x3c6ef372fe94f82b +DATA ·AVX2_iv0<>+24(SB)/8, $0xa54ff53a5f1d36f1 +GLOBL ·AVX2_iv0<>(SB), RODATA|NOPTR, $32 -// load msg: X12 = (0, 6), X13 = (9, 8), X14 = (7, 3), X15 = (2, 11) -#define LOAD_MSG_AVX_0_6_9_8_7_3_2_11() \ - MOVQ 0*8(SI), X12; \ - VPSHUFD $0x4E, 8*8(SI), X13; \ - MOVQ 7*8(SI), X14; \ - MOVQ 2*8(SI), X15; \ - VPINSRQ_1_SI_X12(6*8); \ - VPINSRQ_1_SI_X14(3*8); \ - VPINSRQ_1_SI_X15(11*8) - -// load msg: X12 = (6, 14), X13 = (11, 0), X14 = (15, 9), X15 = (3, 8) -#define LOAD_MSG_AVX_6_14_11_0_15_9_3_8() \ - MOVQ 6*8(SI), X12; \ - MOVQ 11*8(SI), X13; \ - MOVQ 15*8(SI), X14; \ - MOVQ 3*8(SI), X15; \ - VPINSRQ_1_SI_X12(14*8); \ - VPINSRQ_1_SI_X13_0; \ - VPINSRQ_1_SI_X14(9*8); \ - VPINSRQ_1_SI_X15(8*8) - -// load msg: X12 = (5, 15), X13 = (8, 2), X14 = (0, 4), X15 = (6, 10) -#define LOAD_MSG_AVX_5_15_8_2_0_4_6_10() \ - MOVQ 5*8(SI), X12; \ - MOVQ 8*8(SI), X13; \ - MOVQ 0*8(SI), X14; \ - MOVQ 6*8(SI), X15; \ - VPINSRQ_1_SI_X12(15*8); \ - VPINSRQ_1_SI_X13(2*8); \ - VPINSRQ_1_SI_X14(4*8); \ - VPINSRQ_1_SI_X15(10*8) - -// load msg: X12 = (12, 13), X13 = (1, 10), X14 = (2, 7), X15 = (4, 5) -#define LOAD_MSG_AVX_12_13_1_10_2_7_4_5() \ - VMOVDQU 12*8(SI), X12; \ - MOVQ 1*8(SI), X13; \ - MOVQ 2*8(SI), X14; \ - VPINSRQ_1_SI_X13(10*8); \ - VPINSRQ_1_SI_X14(7*8); \ - VMOVDQU 4*8(SI), X15 - -// load msg: X12 = (15, 9), X13 = (3, 13), X14 = (11, 14), X15 = (12, 0) -#define LOAD_MSG_AVX_15_9_3_13_11_14_12_0() \ - MOVQ 15*8(SI), X12; \ - MOVQ 3*8(SI), X13; \ - MOVQ 11*8(SI), X14; \ - MOVQ 12*8(SI), X15; \ - VPINSRQ_1_SI_X12(9*8); \ - VPINSRQ_1_SI_X13(13*8); \ - VPINSRQ_1_SI_X14(14*8); \ - VPINSRQ_1_SI_X15_0 +DATA ·AVX2_iv1<>+0(SB)/8, $0x510e527fade682d1 +DATA ·AVX2_iv1<>+8(SB)/8, $0x9b05688c2b3e6c1f +DATA ·AVX2_iv1<>+16(SB)/8, $0x1f83d9abfb41bd6b +DATA ·AVX2_iv1<>+24(SB)/8, $0x5be0cd19137e2179 +GLOBL ·AVX2_iv1<>(SB), RODATA|NOPTR, $32 // func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) -TEXT ·hashBlocksAVX(SB), 4, $288-48 // frame size = 272 + 16 byte alignment - MOVQ h+0(FP), AX - MOVQ c+8(FP), BX - MOVQ flag+16(FP), CX - MOVQ blocks_base+24(FP), SI - MOVQ blocks_len+32(FP), DI - - MOVQ SP, R10 - ADDQ $15, R10 - ANDQ $~15, R10 - - VMOVDQU ·AVX_c40<>(SB), X0 - VMOVDQU ·AVX_c48<>(SB), X1 +// Requires: AVX, SSE2 +TEXT ·hashBlocksAVX(SB), NOSPLIT, $288-48 + MOVQ h+0(FP), AX + MOVQ c+8(FP), BX + MOVQ flag+16(FP), CX + MOVQ blocks_base+24(FP), SI + MOVQ blocks_len+32(FP), DI + MOVQ SP, R10 + ADDQ $0x0f, R10 + ANDQ $-16, R10 + VMOVDQU ·AVX_c40<>+0(SB), X0 + VMOVDQU ·AVX_c48<>+0(SB), X1 VMOVDQA X0, X8 VMOVDQA X1, X9 - - VMOVDQU ·AVX_iv3<>(SB), X0 - VMOVDQA X0, 0(R10) - XORQ CX, 0(R10) // 0(R10) = ·AVX_iv3 ^ (CX || 0) - - VMOVDQU 0(AX), X10 + VMOVDQU ·AVX_iv3<>+0(SB), X0 + VMOVDQA X0, (R10) + XORQ CX, (R10) + VMOVDQU (AX), X10 VMOVDQU 16(AX), X11 VMOVDQU 32(AX), X2 VMOVDQU 48(AX), X3 - - MOVQ 0(BX), R8 - MOVQ 8(BX), R9 + MOVQ (BX), R8 + MOVQ 8(BX), R9 loop: - ADDQ $128, R8 - CMPQ R8, $128 + ADDQ $0x80, R8 + CMPQ R8, $0x80 JGE noinc INCQ R9 noinc: - VMOVQ_R8_X15 - VPINSRQ_1_R9_X15 - + BYTE $0xc4 + BYTE $0x41 + BYTE $0xf9 + BYTE $0x6e + BYTE $0xf8 + BYTE $0xc4 + BYTE $0x43 + BYTE $0x81 + BYTE $0x22 + BYTE $0xf9 + BYTE $0x01 VMOVDQA X10, X0 VMOVDQA X11, X1 - VMOVDQU ·AVX_iv0<>(SB), X4 - VMOVDQU ·AVX_iv1<>(SB), X5 - VMOVDQU ·AVX_iv2<>(SB), X6 - + VMOVDQU ·AVX_iv0<>+0(SB), X4 + VMOVDQU ·AVX_iv1<>+0(SB), X5 + VMOVDQU ·AVX_iv2<>+0(SB), X6 VPXOR X15, X6, X6 - VMOVDQA 0(R10), X7 - - LOAD_MSG_AVX_0_2_4_6_1_3_5_7() + VMOVDQA (R10), X7 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x26 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x20 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x08 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x28 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x10 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x30 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x38 + BYTE $0x01 VMOVDQA X12, 16(R10) VMOVDQA X13, 32(R10) VMOVDQA X14, 48(R10) VMOVDQA X15, 64(R10) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX(8, 10, 12, 14, 9, 11, 13, 15) + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x40 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x60 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x48 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x68 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x50 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x70 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x58 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x78 + BYTE $0x01 VMOVDQA X12, 80(R10) VMOVDQA X13, 96(R10) VMOVDQA X14, 112(R10) VMOVDQA X15, 128(R10) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - LOAD_MSG_AVX(14, 4, 9, 13, 10, 8, 15, 6) + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x70 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x48 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x50 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x78 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x20 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x68 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x40 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x30 + BYTE $0x01 VMOVDQA X12, 144(R10) VMOVDQA X13, 160(R10) VMOVDQA X14, 176(R10) VMOVDQA X15, 192(R10) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX_1_0_11_5_12_2_7_3() + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + VPSHUFD $0x4e, (SI), X12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x58 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x60 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x38 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x28 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x10 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x18 + BYTE $0x01 VMOVDQA X12, 208(R10) VMOVDQA X13, 224(R10) VMOVDQA X14, 240(R10) VMOVDQA X15, 256(R10) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - LOAD_MSG_AVX_11_12_5_15_8_0_2_13() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX(10, 3, 7, 9, 14, 6, 1, 4) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - LOAD_MSG_AVX(7, 3, 13, 11, 9, 1, 12, 14) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX_2_5_4_15_6_10_0_8() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - LOAD_MSG_AVX_9_5_2_10_0_7_4_15() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX(14, 11, 6, 3, 1, 12, 8, 13) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - LOAD_MSG_AVX_2_6_0_8_12_10_11_3() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX(4, 7, 15, 1, 13, 5, 14, 9) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - LOAD_MSG_AVX(12, 1, 14, 4, 5, 15, 13, 10) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX_0_6_9_8_7_3_2_11() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - LOAD_MSG_AVX(13, 7, 12, 3, 11, 14, 1, 9) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX_5_15_8_2_0_4_6_10() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - LOAD_MSG_AVX_6_14_11_0_15_9_3_8() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX_12_13_1_10_2_7_4_5() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - LOAD_MSG_AVX(10, 8, 7, 1, 2, 4, 6, 5) - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX() - LOAD_MSG_AVX_15_9_3_13_11_14_12_0() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) - SHUFFLE_AVX_INV() - - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X15, X8, X9) - SHUFFLE_AVX() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X15, X8, X9) - SHUFFLE_AVX_INV() - - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X15, X8, X9) - SHUFFLE_AVX() - HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X15, X8, X9) - SHUFFLE_AVX_INV() - + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + VMOVDQU 88(SI), X12 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x28 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x40 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x10 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x78 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x36 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x68 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x50 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x38 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x70 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x08 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x48 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x30 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x20 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x38 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x68 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x48 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x60 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x58 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x08 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x70 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x10 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x20 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x30 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x3e + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x28 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x78 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x50 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x40 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x48 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x10 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x36 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x20 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x28 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x50 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x38 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x78 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x70 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x30 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x08 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x40 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x58 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x60 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x68 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x10 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x2e + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x60 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x58 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x30 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x40 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x50 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x18 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x20 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x78 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x68 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x70 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x38 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x08 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x28 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x48 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x60 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x70 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x28 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x68 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x08 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x20 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x78 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x50 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + MOVQ (SI), X12 + VPSHUFD $0x4e, 64(SI), X13 + MOVQ 56(SI), X14 + MOVQ 16(SI), X15 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x30 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x58 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x68 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x60 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x58 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x08 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x38 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x18 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x70 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x48 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + MOVQ 40(SI), X12 + MOVQ 64(SI), X13 + MOVQ (SI), X14 + MOVQ 48(SI), X15 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x78 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x10 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x20 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x50 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + MOVQ 48(SI), X12 + MOVQ 88(SI), X13 + MOVQ 120(SI), X14 + MOVQ 24(SI), X15 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x70 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x2e + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x48 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x40 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + VMOVDQU 96(SI), X12 + MOVQ 8(SI), X13 + MOVQ 16(SI), X14 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x50 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x38 + BYTE $0x01 + VMOVDQU 32(SI), X15 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x66 + BYTE $0x50 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x6e + BYTE $0x38 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x76 + BYTE $0x10 + BYTE $0xc5 + BYTE $0x7a + BYTE $0x7e + BYTE $0x7e + BYTE $0x30 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x40 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x08 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x20 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x7e + BYTE $0x28 + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + MOVQ 120(SI), X12 + MOVQ 24(SI), X13 + MOVQ 88(SI), X14 + MOVQ 96(SI), X15 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x99 + BYTE $0x22 + BYTE $0x66 + BYTE $0x48 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x91 + BYTE $0x22 + BYTE $0x6e + BYTE $0x68 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x89 + BYTE $0x22 + BYTE $0x76 + BYTE $0x70 + BYTE $0x01 + BYTE $0xc4 + BYTE $0x63 + BYTE $0x81 + BYTE $0x22 + BYTE $0x3e + BYTE $0x01 + VPADDQ X12, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X13, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ X14, X0, X0 + VPADDQ X2, X0, X0 + VPADDQ X15, X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + VPADDQ 16(R10), X0, X0 + VPADDQ X2, X0, X0 + VPADDQ 32(R10), X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ 48(R10), X0, X0 + VPADDQ X2, X0, X0 + VPADDQ 64(R10), X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + VPADDQ 80(R10), X0, X0 + VPADDQ X2, X0, X0 + VPADDQ 96(R10), X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ 112(R10), X0, X0 + VPADDQ X2, X0, X0 + VPADDQ 128(R10), X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff + VPADDQ 144(R10), X0, X0 + VPADDQ X2, X0, X0 + VPADDQ 160(R10), X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ 176(R10), X0, X0 + VPADDQ X2, X0, X0 + VPADDQ 192(R10), X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X6, X13 + VMOVDQA X2, X14 + VMOVDQA X4, X6 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x11 + BYTE $0x6c + BYTE $0xfd + VMOVDQA X5, X4 + VMOVDQA X6, X5 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xff + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x69 + BYTE $0x6d + BYTE $0xd7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xdf + VPADDQ 208(R10), X0, X0 + VPADDQ X2, X0, X0 + VPADDQ 224(R10), X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFD $-79, X6, X6 + VPSHUFD $-79, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPSHUFB X8, X2, X2 + VPSHUFB X8, X3, X3 + VPADDQ 240(R10), X0, X0 + VPADDQ X2, X0, X0 + VPADDQ 256(R10), X1, X1 + VPADDQ X3, X1, X1 + VPXOR X0, X6, X6 + VPXOR X1, X7, X7 + VPSHUFB X9, X6, X6 + VPSHUFB X9, X7, X7 + VPADDQ X6, X4, X4 + VPADDQ X7, X5, X5 + VPXOR X4, X2, X2 + VPXOR X5, X3, X3 + VPADDQ X2, X2, X15 + VPSRLQ $0x3f, X2, X2 + VPXOR X15, X2, X2 + VPADDQ X3, X3, X15 + VPSRLQ $0x3f, X3, X3 + VPXOR X15, X3, X3 + VMOVDQA X2, X13 + VMOVDQA X4, X14 + BYTE $0xc5 + BYTE $0x69 + BYTE $0x6c + BYTE $0xfa + VMOVDQA X5, X4 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x61 + BYTE $0x6d + BYTE $0xd7 + VMOVDQA X14, X5 + BYTE $0xc5 + BYTE $0x61 + BYTE $0x6c + BYTE $0xfb + VMOVDQA X6, X14 + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x11 + BYTE $0x6d + BYTE $0xdf + BYTE $0xc5 + BYTE $0x41 + BYTE $0x6c + BYTE $0xff + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x49 + BYTE $0x6d + BYTE $0xf7 + BYTE $0xc4 + BYTE $0x41 + BYTE $0x09 + BYTE $0x6c + BYTE $0xfe + BYTE $0xc4 + BYTE $0xc1 + BYTE $0x41 + BYTE $0x6d + BYTE $0xff VMOVDQU 32(AX), X14 VMOVDQU 48(AX), X15 VPXOR X0, X10, X10 @@ -729,16 +4524,36 @@ noinc: VPXOR X7, X15, X3 VMOVDQU X2, 32(AX) VMOVDQU X3, 48(AX) + LEAQ 128(SI), SI + SUBQ $0x80, DI + JNE loop + VMOVDQU X10, (AX) + VMOVDQU X11, 16(AX) + MOVQ R8, (BX) + MOVQ R9, 8(BX) + VZEROUPPER + RET - LEAQ 128(SI), SI - SUBQ $128, DI - JNE loop +DATA ·AVX_c40<>+0(SB)/8, $0x0201000706050403 +DATA ·AVX_c40<>+8(SB)/8, $0x0a09080f0e0d0c0b +GLOBL ·AVX_c40<>(SB), RODATA|NOPTR, $16 - VMOVDQU X10, 0(AX) - VMOVDQU X11, 16(AX) +DATA ·AVX_c48<>+0(SB)/8, $0x0100070605040302 +DATA ·AVX_c48<>+8(SB)/8, $0x09080f0e0d0c0b0a +GLOBL ·AVX_c48<>(SB), RODATA|NOPTR, $16 - MOVQ R8, 0(BX) - MOVQ R9, 8(BX) - VZEROUPPER +DATA ·AVX_iv3<>+0(SB)/8, $0x1f83d9abfb41bd6b +DATA ·AVX_iv3<>+8(SB)/8, $0x5be0cd19137e2179 +GLOBL ·AVX_iv3<>(SB), RODATA|NOPTR, $16 - RET +DATA ·AVX_iv0<>+0(SB)/8, $0x6a09e667f3bcc908 +DATA ·AVX_iv0<>+8(SB)/8, $0xbb67ae8584caa73b +GLOBL ·AVX_iv0<>(SB), RODATA|NOPTR, $16 + +DATA ·AVX_iv1<>+0(SB)/8, $0x3c6ef372fe94f82b +DATA ·AVX_iv1<>+8(SB)/8, $0xa54ff53a5f1d36f1 +GLOBL ·AVX_iv1<>(SB), RODATA|NOPTR, $16 + +DATA ·AVX_iv2<>+0(SB)/8, $0x510e527fade682d1 +DATA ·AVX_iv2<>+8(SB)/8, $0x9b05688c2b3e6c1f +GLOBL ·AVX_iv2<>(SB), RODATA|NOPTR, $16 diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s index adfac00c15..9a0ce21244 100644 --- a/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s +++ b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s @@ -1,278 +1,1441 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Code generated by command: go run blake2b_amd64_asm.go -out ../../blake2b_amd64.s -pkg blake2b. DO NOT EDIT. //go:build amd64 && gc && !purego #include "textflag.h" -DATA ·iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908 -DATA ·iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b -GLOBL ·iv0<>(SB), (NOPTR+RODATA), $16 - -DATA ·iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b -DATA ·iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1 -GLOBL ·iv1<>(SB), (NOPTR+RODATA), $16 - -DATA ·iv2<>+0x00(SB)/8, $0x510e527fade682d1 -DATA ·iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f -GLOBL ·iv2<>(SB), (NOPTR+RODATA), $16 - -DATA ·iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b -DATA ·iv3<>+0x08(SB)/8, $0x5be0cd19137e2179 -GLOBL ·iv3<>(SB), (NOPTR+RODATA), $16 - -DATA ·c40<>+0x00(SB)/8, $0x0201000706050403 -DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b -GLOBL ·c40<>(SB), (NOPTR+RODATA), $16 - -DATA ·c48<>+0x00(SB)/8, $0x0100070605040302 -DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a -GLOBL ·c48<>(SB), (NOPTR+RODATA), $16 - -#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \ - MOVO v4, t1; \ - MOVO v5, v4; \ - MOVO t1, v5; \ - MOVO v6, t1; \ - PUNPCKLQDQ v6, t2; \ - PUNPCKHQDQ v7, v6; \ - PUNPCKHQDQ t2, v6; \ - PUNPCKLQDQ v7, t2; \ - MOVO t1, v7; \ - MOVO v2, t1; \ - PUNPCKHQDQ t2, v7; \ - PUNPCKLQDQ v3, t2; \ - PUNPCKHQDQ t2, v2; \ - PUNPCKLQDQ t1, t2; \ - PUNPCKHQDQ t2, v3 - -#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \ - MOVO v4, t1; \ - MOVO v5, v4; \ - MOVO t1, v5; \ - MOVO v2, t1; \ - PUNPCKLQDQ v2, t2; \ - PUNPCKHQDQ v3, v2; \ - PUNPCKHQDQ t2, v2; \ - PUNPCKLQDQ v3, t2; \ - MOVO t1, v3; \ - MOVO v6, t1; \ - PUNPCKHQDQ t2, v3; \ - PUNPCKLQDQ v7, t2; \ - PUNPCKHQDQ t2, v6; \ - PUNPCKLQDQ t1, t2; \ - PUNPCKHQDQ t2, v7 - -#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \ - PADDQ m0, v0; \ - PADDQ m1, v1; \ - PADDQ v2, v0; \ - PADDQ v3, v1; \ - PXOR v0, v6; \ - PXOR v1, v7; \ - PSHUFD $0xB1, v6, v6; \ - PSHUFD $0xB1, v7, v7; \ - PADDQ v6, v4; \ - PADDQ v7, v5; \ - PXOR v4, v2; \ - PXOR v5, v3; \ - PSHUFB c40, v2; \ - PSHUFB c40, v3; \ - PADDQ m2, v0; \ - PADDQ m3, v1; \ - PADDQ v2, v0; \ - PADDQ v3, v1; \ - PXOR v0, v6; \ - PXOR v1, v7; \ - PSHUFB c48, v6; \ - PSHUFB c48, v7; \ - PADDQ v6, v4; \ - PADDQ v7, v5; \ - PXOR v4, v2; \ - PXOR v5, v3; \ - MOVOU v2, t0; \ - PADDQ v2, t0; \ - PSRLQ $63, v2; \ - PXOR t0, v2; \ - MOVOU v3, t0; \ - PADDQ v3, t0; \ - PSRLQ $63, v3; \ - PXOR t0, v3 - -#define LOAD_MSG(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7) \ - MOVQ i0*8(src), m0; \ - PINSRQ $1, i1*8(src), m0; \ - MOVQ i2*8(src), m1; \ - PINSRQ $1, i3*8(src), m1; \ - MOVQ i4*8(src), m2; \ - PINSRQ $1, i5*8(src), m2; \ - MOVQ i6*8(src), m3; \ - PINSRQ $1, i7*8(src), m3 - // func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) -TEXT ·hashBlocksSSE4(SB), 4, $288-48 // frame size = 272 + 16 byte alignment - MOVQ h+0(FP), AX - MOVQ c+8(FP), BX - MOVQ flag+16(FP), CX - MOVQ blocks_base+24(FP), SI - MOVQ blocks_len+32(FP), DI - - MOVQ SP, R10 - ADDQ $15, R10 - ANDQ $~15, R10 - - MOVOU ·iv3<>(SB), X0 - MOVO X0, 0(R10) - XORQ CX, 0(R10) // 0(R10) = ·iv3 ^ (CX || 0) - - MOVOU ·c40<>(SB), X13 - MOVOU ·c48<>(SB), X14 - - MOVOU 0(AX), X12 +// Requires: SSE2, SSE4.1, SSSE3 +TEXT ·hashBlocksSSE4(SB), NOSPLIT, $288-48 + MOVQ h+0(FP), AX + MOVQ c+8(FP), BX + MOVQ flag+16(FP), CX + MOVQ blocks_base+24(FP), SI + MOVQ blocks_len+32(FP), DI + MOVQ SP, R10 + ADDQ $0x0f, R10 + ANDQ $-16, R10 + MOVOU ·iv3<>+0(SB), X0 + MOVO X0, (R10) + XORQ CX, (R10) + MOVOU ·c40<>+0(SB), X13 + MOVOU ·c48<>+0(SB), X14 + MOVOU (AX), X12 MOVOU 16(AX), X15 - - MOVQ 0(BX), R8 - MOVQ 8(BX), R9 + MOVQ (BX), R8 + MOVQ 8(BX), R9 loop: - ADDQ $128, R8 - CMPQ R8, $128 + ADDQ $0x80, R8 + CMPQ R8, $0x80 JGE noinc INCQ R9 noinc: - MOVQ R8, X8 - PINSRQ $1, R9, X8 - - MOVO X12, X0 - MOVO X15, X1 - MOVOU 32(AX), X2 - MOVOU 48(AX), X3 - MOVOU ·iv0<>(SB), X4 - MOVOU ·iv1<>(SB), X5 - MOVOU ·iv2<>(SB), X6 - - PXOR X8, X6 - MOVO 0(R10), X7 - - LOAD_MSG(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7) - MOVO X8, 16(R10) - MOVO X9, 32(R10) - MOVO X10, 48(R10) - MOVO X11, 64(R10) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 8, 10, 12, 14, 9, 11, 13, 15) - MOVO X8, 80(R10) - MOVO X9, 96(R10) - MOVO X10, 112(R10) - MOVO X11, 128(R10) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - LOAD_MSG(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6) - MOVO X8, 144(R10) - MOVO X9, 160(R10) - MOVO X10, 176(R10) - MOVO X11, 192(R10) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 1, 0, 11, 5, 12, 2, 7, 3) - MOVO X8, 208(R10) - MOVO X9, 224(R10) - MOVO X10, 240(R10) - MOVO X11, 256(R10) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - LOAD_MSG(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 10, 3, 7, 9, 14, 6, 1, 4) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - LOAD_MSG(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 2, 5, 4, 15, 6, 10, 0, 8) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - LOAD_MSG(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 14, 11, 6, 3, 1, 12, 8, 13) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - LOAD_MSG(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 4, 7, 15, 1, 13, 5, 14, 9) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - LOAD_MSG(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 0, 6, 9, 8, 7, 3, 2, 11) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - LOAD_MSG(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 5, 15, 8, 2, 0, 4, 6, 10) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - LOAD_MSG(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 12, 13, 1, 10, 2, 7, 4, 5) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - LOAD_MSG(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - LOAD_MSG(X8, X9, X10, X11, SI, 15, 9, 3, 13, 11, 14, 12, 0) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) - - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + MOVQ R8, X8 + PINSRQ $0x01, R9, X8 + MOVO X12, X0 + MOVO X15, X1 + MOVOU 32(AX), X2 + MOVOU 48(AX), X3 + MOVOU ·iv0<>+0(SB), X4 + MOVOU ·iv1<>+0(SB), X5 + MOVOU ·iv2<>+0(SB), X6 + PXOR X8, X6 + MOVO (R10), X7 + MOVQ (SI), X8 + PINSRQ $0x01, 16(SI), X8 + MOVQ 32(SI), X9 + PINSRQ $0x01, 48(SI), X9 + MOVQ 8(SI), X10 + PINSRQ $0x01, 24(SI), X10 + MOVQ 40(SI), X11 + PINSRQ $0x01, 56(SI), X11 + MOVO X8, 16(R10) + MOVO X9, 32(R10) + MOVO X10, 48(R10) + MOVO X11, 64(R10) + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ 64(SI), X8 + PINSRQ $0x01, 80(SI), X8 + MOVQ 96(SI), X9 + PINSRQ $0x01, 112(SI), X9 + MOVQ 72(SI), X10 + PINSRQ $0x01, 88(SI), X10 + MOVQ 104(SI), X11 + PINSRQ $0x01, 120(SI), X11 + MOVO X8, 80(R10) + MOVO X9, 96(R10) + MOVO X10, 112(R10) + MOVO X11, 128(R10) + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVQ 112(SI), X8 + PINSRQ $0x01, 32(SI), X8 + MOVQ 72(SI), X9 + PINSRQ $0x01, 104(SI), X9 + MOVQ 80(SI), X10 + PINSRQ $0x01, 64(SI), X10 + MOVQ 120(SI), X11 + PINSRQ $0x01, 48(SI), X11 + MOVO X8, 144(R10) + MOVO X9, 160(R10) + MOVO X10, 176(R10) + MOVO X11, 192(R10) + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ 8(SI), X8 + PINSRQ $0x01, (SI), X8 + MOVQ 88(SI), X9 + PINSRQ $0x01, 40(SI), X9 + MOVQ 96(SI), X10 + PINSRQ $0x01, 16(SI), X10 + MOVQ 56(SI), X11 + PINSRQ $0x01, 24(SI), X11 + MOVO X8, 208(R10) + MOVO X9, 224(R10) + MOVO X10, 240(R10) + MOVO X11, 256(R10) + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVQ 88(SI), X8 + PINSRQ $0x01, 96(SI), X8 + MOVQ 40(SI), X9 + PINSRQ $0x01, 120(SI), X9 + MOVQ 64(SI), X10 + PINSRQ $0x01, (SI), X10 + MOVQ 16(SI), X11 + PINSRQ $0x01, 104(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ 80(SI), X8 + PINSRQ $0x01, 24(SI), X8 + MOVQ 56(SI), X9 + PINSRQ $0x01, 72(SI), X9 + MOVQ 112(SI), X10 + PINSRQ $0x01, 48(SI), X10 + MOVQ 8(SI), X11 + PINSRQ $0x01, 32(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVQ 56(SI), X8 + PINSRQ $0x01, 24(SI), X8 + MOVQ 104(SI), X9 + PINSRQ $0x01, 88(SI), X9 + MOVQ 72(SI), X10 + PINSRQ $0x01, 8(SI), X10 + MOVQ 96(SI), X11 + PINSRQ $0x01, 112(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ 16(SI), X8 + PINSRQ $0x01, 40(SI), X8 + MOVQ 32(SI), X9 + PINSRQ $0x01, 120(SI), X9 + MOVQ 48(SI), X10 + PINSRQ $0x01, 80(SI), X10 + MOVQ (SI), X11 + PINSRQ $0x01, 64(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVQ 72(SI), X8 + PINSRQ $0x01, 40(SI), X8 + MOVQ 16(SI), X9 + PINSRQ $0x01, 80(SI), X9 + MOVQ (SI), X10 + PINSRQ $0x01, 56(SI), X10 + MOVQ 32(SI), X11 + PINSRQ $0x01, 120(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ 112(SI), X8 + PINSRQ $0x01, 88(SI), X8 + MOVQ 48(SI), X9 + PINSRQ $0x01, 24(SI), X9 + MOVQ 8(SI), X10 + PINSRQ $0x01, 96(SI), X10 + MOVQ 64(SI), X11 + PINSRQ $0x01, 104(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVQ 16(SI), X8 + PINSRQ $0x01, 48(SI), X8 + MOVQ (SI), X9 + PINSRQ $0x01, 64(SI), X9 + MOVQ 96(SI), X10 + PINSRQ $0x01, 80(SI), X10 + MOVQ 88(SI), X11 + PINSRQ $0x01, 24(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ 32(SI), X8 + PINSRQ $0x01, 56(SI), X8 + MOVQ 120(SI), X9 + PINSRQ $0x01, 8(SI), X9 + MOVQ 104(SI), X10 + PINSRQ $0x01, 40(SI), X10 + MOVQ 112(SI), X11 + PINSRQ $0x01, 72(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVQ 96(SI), X8 + PINSRQ $0x01, 8(SI), X8 + MOVQ 112(SI), X9 + PINSRQ $0x01, 32(SI), X9 + MOVQ 40(SI), X10 + PINSRQ $0x01, 120(SI), X10 + MOVQ 104(SI), X11 + PINSRQ $0x01, 80(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ (SI), X8 + PINSRQ $0x01, 48(SI), X8 + MOVQ 72(SI), X9 + PINSRQ $0x01, 64(SI), X9 + MOVQ 56(SI), X10 + PINSRQ $0x01, 24(SI), X10 + MOVQ 16(SI), X11 + PINSRQ $0x01, 88(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVQ 104(SI), X8 + PINSRQ $0x01, 56(SI), X8 + MOVQ 96(SI), X9 + PINSRQ $0x01, 24(SI), X9 + MOVQ 88(SI), X10 + PINSRQ $0x01, 112(SI), X10 + MOVQ 8(SI), X11 + PINSRQ $0x01, 72(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ 40(SI), X8 + PINSRQ $0x01, 120(SI), X8 + MOVQ 64(SI), X9 + PINSRQ $0x01, 16(SI), X9 + MOVQ (SI), X10 + PINSRQ $0x01, 32(SI), X10 + MOVQ 48(SI), X11 + PINSRQ $0x01, 80(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVQ 48(SI), X8 + PINSRQ $0x01, 112(SI), X8 + MOVQ 88(SI), X9 + PINSRQ $0x01, (SI), X9 + MOVQ 120(SI), X10 + PINSRQ $0x01, 72(SI), X10 + MOVQ 24(SI), X11 + PINSRQ $0x01, 64(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ 96(SI), X8 + PINSRQ $0x01, 104(SI), X8 + MOVQ 8(SI), X9 + PINSRQ $0x01, 80(SI), X9 + MOVQ 16(SI), X10 + PINSRQ $0x01, 56(SI), X10 + MOVQ 32(SI), X11 + PINSRQ $0x01, 40(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVQ 80(SI), X8 + PINSRQ $0x01, 64(SI), X8 + MOVQ 56(SI), X9 + PINSRQ $0x01, 8(SI), X9 + MOVQ 16(SI), X10 + PINSRQ $0x01, 32(SI), X10 + MOVQ 48(SI), X11 + PINSRQ $0x01, 40(SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + MOVQ 120(SI), X8 + PINSRQ $0x01, 72(SI), X8 + MOVQ 24(SI), X9 + PINSRQ $0x01, 104(SI), X9 + MOVQ 88(SI), X10 + PINSRQ $0x01, 112(SI), X10 + MOVQ 96(SI), X11 + PINSRQ $0x01, (SI), X11 + PADDQ X8, X0 + PADDQ X9, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ X10, X0 + PADDQ X11, X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + PADDQ 16(R10), X0 + PADDQ 32(R10), X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ 48(R10), X0 + PADDQ 64(R10), X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + PADDQ 80(R10), X0 + PADDQ 96(R10), X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ 112(R10), X0 + PADDQ 128(R10), X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + PADDQ 144(R10), X0 + PADDQ 160(R10), X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ 176(R10), X0 + PADDQ 192(R10), X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X6, X8 + PUNPCKLQDQ X6, X9 + PUNPCKHQDQ X7, X6 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X7, X9 + MOVO X8, X7 + MOVO X2, X8 + PUNPCKHQDQ X9, X7 + PUNPCKLQDQ X3, X9 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X3 + PADDQ 208(R10), X0 + PADDQ 224(R10), X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFD $0xb1, X6, X6 + PSHUFD $0xb1, X7, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + PSHUFB X13, X2 + PSHUFB X13, X3 + PADDQ 240(R10), X0 + PADDQ 256(R10), X1 + PADDQ X2, X0 + PADDQ X3, X1 + PXOR X0, X6 + PXOR X1, X7 + PSHUFB X14, X6 + PSHUFB X14, X7 + PADDQ X6, X4 + PADDQ X7, X5 + PXOR X4, X2 + PXOR X5, X3 + MOVOU X2, X11 + PADDQ X2, X11 + PSRLQ $0x3f, X2 + PXOR X11, X2 + MOVOU X3, X11 + PADDQ X3, X11 + PSRLQ $0x3f, X3 + PXOR X11, X3 + MOVO X4, X8 + MOVO X5, X4 + MOVO X8, X5 + MOVO X2, X8 + PUNPCKLQDQ X2, X9 + PUNPCKHQDQ X3, X2 + PUNPCKHQDQ X9, X2 + PUNPCKLQDQ X3, X9 + MOVO X8, X3 + MOVO X6, X8 + PUNPCKHQDQ X9, X3 + PUNPCKLQDQ X7, X9 + PUNPCKHQDQ X9, X6 + PUNPCKLQDQ X8, X9 + PUNPCKHQDQ X9, X7 + MOVOU 32(AX), X10 + MOVOU 48(AX), X11 + PXOR X0, X12 + PXOR X1, X15 + PXOR X2, X10 + PXOR X3, X11 + PXOR X4, X12 + PXOR X5, X15 + PXOR X6, X10 + PXOR X7, X11 + MOVOU X10, 32(AX) + MOVOU X11, 48(AX) + LEAQ 128(SI), SI + SUBQ $0x80, DI + JNE loop + MOVOU X12, (AX) + MOVOU X15, 16(AX) + MOVQ R8, (BX) + MOVQ R9, 8(BX) + RET - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X11, X13, X14) - SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) - HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X11, X13, X14) - SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) +DATA ·iv3<>+0(SB)/8, $0x1f83d9abfb41bd6b +DATA ·iv3<>+8(SB)/8, $0x5be0cd19137e2179 +GLOBL ·iv3<>(SB), RODATA|NOPTR, $16 - MOVOU 32(AX), X10 - MOVOU 48(AX), X11 - PXOR X0, X12 - PXOR X1, X15 - PXOR X2, X10 - PXOR X3, X11 - PXOR X4, X12 - PXOR X5, X15 - PXOR X6, X10 - PXOR X7, X11 - MOVOU X10, 32(AX) - MOVOU X11, 48(AX) +DATA ·c40<>+0(SB)/8, $0x0201000706050403 +DATA ·c40<>+8(SB)/8, $0x0a09080f0e0d0c0b +GLOBL ·c40<>(SB), RODATA|NOPTR, $16 - LEAQ 128(SI), SI - SUBQ $128, DI - JNE loop +DATA ·c48<>+0(SB)/8, $0x0100070605040302 +DATA ·c48<>+8(SB)/8, $0x09080f0e0d0c0b0a +GLOBL ·c48<>(SB), RODATA|NOPTR, $16 - MOVOU X12, 0(AX) - MOVOU X15, 16(AX) +DATA ·iv0<>+0(SB)/8, $0x6a09e667f3bcc908 +DATA ·iv0<>+8(SB)/8, $0xbb67ae8584caa73b +GLOBL ·iv0<>(SB), RODATA|NOPTR, $16 - MOVQ R8, 0(BX) - MOVQ R9, 8(BX) +DATA ·iv1<>+0(SB)/8, $0x3c6ef372fe94f82b +DATA ·iv1<>+8(SB)/8, $0xa54ff53a5f1d36f1 +GLOBL ·iv1<>(SB), RODATA|NOPTR, $16 - RET +DATA ·iv2<>+0(SB)/8, $0x510e527fade682d1 +DATA ·iv2<>+8(SB)/8, $0x9b05688c2b3e6c1f +GLOBL ·iv2<>(SB), RODATA|NOPTR, $16 diff --git a/vendor/golang.org/x/crypto/blowfish/cipher.go b/vendor/golang.org/x/crypto/blowfish/cipher.go index 213bf204af..0898956807 100644 --- a/vendor/golang.org/x/crypto/blowfish/cipher.go +++ b/vendor/golang.org/x/crypto/blowfish/cipher.go @@ -11,7 +11,7 @@ // Deprecated: any new system should use AES (from crypto/aes, if necessary in // an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from // golang.org/x/crypto/chacha20poly1305). -package blowfish // import "golang.org/x/crypto/blowfish" +package blowfish // The code is a port of Bruce Schneier's C implementation. // See https://www.schneier.com/blowfish.html. diff --git a/vendor/golang.org/x/crypto/cast5/cast5.go b/vendor/golang.org/x/crypto/cast5/cast5.go index 425e8eecb0..016e90215c 100644 --- a/vendor/golang.org/x/crypto/cast5/cast5.go +++ b/vendor/golang.org/x/crypto/cast5/cast5.go @@ -11,7 +11,7 @@ // Deprecated: any new system should use AES (from crypto/aes, if necessary in // an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from // golang.org/x/crypto/chacha20poly1305). -package cast5 // import "golang.org/x/crypto/cast5" +package cast5 import ( "errors" diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go index 00f963ea20..21ca3b2ee4 100644 --- a/vendor/golang.org/x/crypto/curve25519/curve25519.go +++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go @@ -6,9 +6,11 @@ // performs scalar multiplication on the elliptic curve known as Curve25519. // See RFC 7748. // -// Starting in Go 1.20, this package is a wrapper for the X25519 implementation +// This package is a wrapper for the X25519 implementation // in the crypto/ecdh package. -package curve25519 // import "golang.org/x/crypto/curve25519" +package curve25519 + +import "crypto/ecdh" // ScalarMult sets dst to the product scalar * point. // @@ -16,7 +18,13 @@ package curve25519 // import "golang.org/x/crypto/curve25519" // zeroes, irrespective of the scalar. Instead, use the X25519 function, which // will return an error. func ScalarMult(dst, scalar, point *[32]byte) { - scalarMult(dst, scalar, point) + if _, err := x25519(dst, scalar[:], point[:]); err != nil { + // The only error condition for x25519 when the inputs are 32 bytes long + // is if the output would have been the all-zero value. + for i := range dst { + dst[i] = 0 + } + } } // ScalarBaseMult sets dst to the product scalar * base where base is the @@ -25,7 +33,12 @@ func ScalarMult(dst, scalar, point *[32]byte) { // It is recommended to use the X25519 function with Basepoint instead, as // copying into fixed size arrays can lead to unexpected bugs. func ScalarBaseMult(dst, scalar *[32]byte) { - scalarBaseMult(dst, scalar) + curve := ecdh.X25519() + priv, err := curve.NewPrivateKey(scalar[:]) + if err != nil { + panic("curve25519: internal error: scalarBaseMult was not 32 bytes") + } + copy(dst[:], priv.PublicKey().Bytes()) } const ( @@ -57,3 +70,21 @@ func X25519(scalar, point []byte) ([]byte, error) { var dst [32]byte return x25519(&dst, scalar, point) } + +func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { + curve := ecdh.X25519() + pub, err := curve.NewPublicKey(point) + if err != nil { + return nil, err + } + priv, err := curve.NewPrivateKey(scalar) + if err != nil { + return nil, err + } + out, err := priv.ECDH(pub) + if err != nil { + return nil, err + } + copy(dst[:], out) + return dst[:], nil +} diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go b/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go deleted file mode 100644 index ba647e8d77..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.20 - -package curve25519 - -import ( - "crypto/subtle" - "errors" - "strconv" - - "golang.org/x/crypto/curve25519/internal/field" -) - -func scalarMult(dst, scalar, point *[32]byte) { - var e [32]byte - - copy(e[:], scalar[:]) - e[0] &= 248 - e[31] &= 127 - e[31] |= 64 - - var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element - x1.SetBytes(point[:]) - x2.One() - x3.Set(&x1) - z3.One() - - swap := 0 - for pos := 254; pos >= 0; pos-- { - b := e[pos/8] >> uint(pos&7) - b &= 1 - swap ^= int(b) - x2.Swap(&x3, swap) - z2.Swap(&z3, swap) - swap = int(b) - - tmp0.Subtract(&x3, &z3) - tmp1.Subtract(&x2, &z2) - x2.Add(&x2, &z2) - z2.Add(&x3, &z3) - z3.Multiply(&tmp0, &x2) - z2.Multiply(&z2, &tmp1) - tmp0.Square(&tmp1) - tmp1.Square(&x2) - x3.Add(&z3, &z2) - z2.Subtract(&z3, &z2) - x2.Multiply(&tmp1, &tmp0) - tmp1.Subtract(&tmp1, &tmp0) - z2.Square(&z2) - - z3.Mult32(&tmp1, 121666) - x3.Square(&x3) - tmp0.Add(&tmp0, &z3) - z3.Multiply(&x1, &z2) - z2.Multiply(&tmp1, &tmp0) - } - - x2.Swap(&x3, swap) - z2.Swap(&z3, swap) - - z2.Invert(&z2) - x2.Multiply(&x2, &z2) - copy(dst[:], x2.Bytes()) -} - -func scalarBaseMult(dst, scalar *[32]byte) { - checkBasepoint() - scalarMult(dst, scalar, &basePoint) -} - -func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { - var in [32]byte - if l := len(scalar); l != 32 { - return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32") - } - if l := len(point); l != 32 { - return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32") - } - copy(in[:], scalar) - if &point[0] == &Basepoint[0] { - scalarBaseMult(dst, &in) - } else { - var base, zero [32]byte - copy(base[:], point) - scalarMult(dst, &in, &base) - if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 { - return nil, errors.New("bad input point: low order point") - } - } - return dst[:], nil -} - -func checkBasepoint() { - if subtle.ConstantTimeCompare(Basepoint, []byte{ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }) != 1 { - panic("curve25519: global Basepoint value was modified") - } -} diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go b/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go deleted file mode 100644 index 627df49727..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.20 - -package curve25519 - -import "crypto/ecdh" - -func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { - curve := ecdh.X25519() - pub, err := curve.NewPublicKey(point) - if err != nil { - return nil, err - } - priv, err := curve.NewPrivateKey(scalar) - if err != nil { - return nil, err - } - out, err := priv.ECDH(pub) - if err != nil { - return nil, err - } - copy(dst[:], out) - return dst[:], nil -} - -func scalarMult(dst, scalar, point *[32]byte) { - if _, err := x25519(dst, scalar[:], point[:]); err != nil { - // The only error condition for x25519 when the inputs are 32 bytes long - // is if the output would have been the all-zero value. - for i := range dst { - dst[i] = 0 - } - } -} - -func scalarBaseMult(dst, scalar *[32]byte) { - curve := ecdh.X25519() - priv, err := curve.NewPrivateKey(scalar[:]) - if err != nil { - panic("curve25519: internal error: scalarBaseMult was not 32 bytes") - } - copy(dst[:], priv.PublicKey().Bytes()) -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/README b/vendor/golang.org/x/crypto/curve25519/internal/field/README deleted file mode 100644 index e25bca7dc8..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/README +++ /dev/null @@ -1,7 +0,0 @@ -This package is kept in sync with crypto/ed25519/internal/edwards25519/field in -the standard library. - -If there are any changes in the standard library that need to be synced to this -package, run sync.sh. It will not overwrite any local changes made since the -previous sync, so it's ok to land changes in this package first, and then sync -to the standard library later. diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go deleted file mode 100644 index ca841ad99e..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go +++ /dev/null @@ -1,416 +0,0 @@ -// Copyright (c) 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package field implements fast arithmetic modulo 2^255-19. -package field - -import ( - "crypto/subtle" - "encoding/binary" - "math/bits" -) - -// Element represents an element of the field GF(2^255-19). Note that this -// is not a cryptographically secure group, and should only be used to interact -// with edwards25519.Point coordinates. -// -// This type works similarly to math/big.Int, and all arguments and receivers -// are allowed to alias. -// -// The zero value is a valid zero element. -type Element struct { - // An element t represents the integer - // t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204 - // - // Between operations, all limbs are expected to be lower than 2^52. - l0 uint64 - l1 uint64 - l2 uint64 - l3 uint64 - l4 uint64 -} - -const maskLow51Bits uint64 = (1 << 51) - 1 - -var feZero = &Element{0, 0, 0, 0, 0} - -// Zero sets v = 0, and returns v. -func (v *Element) Zero() *Element { - *v = *feZero - return v -} - -var feOne = &Element{1, 0, 0, 0, 0} - -// One sets v = 1, and returns v. -func (v *Element) One() *Element { - *v = *feOne - return v -} - -// reduce reduces v modulo 2^255 - 19 and returns it. -func (v *Element) reduce() *Element { - v.carryPropagate() - - // After the light reduction we now have a field element representation - // v < 2^255 + 2^13 * 19, but need v < 2^255 - 19. - - // If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1, - // generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise. - c := (v.l0 + 19) >> 51 - c = (v.l1 + c) >> 51 - c = (v.l2 + c) >> 51 - c = (v.l3 + c) >> 51 - c = (v.l4 + c) >> 51 - - // If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's - // effectively applying the reduction identity to the carry. - v.l0 += 19 * c - - v.l1 += v.l0 >> 51 - v.l0 = v.l0 & maskLow51Bits - v.l2 += v.l1 >> 51 - v.l1 = v.l1 & maskLow51Bits - v.l3 += v.l2 >> 51 - v.l2 = v.l2 & maskLow51Bits - v.l4 += v.l3 >> 51 - v.l3 = v.l3 & maskLow51Bits - // no additional carry - v.l4 = v.l4 & maskLow51Bits - - return v -} - -// Add sets v = a + b, and returns v. -func (v *Element) Add(a, b *Element) *Element { - v.l0 = a.l0 + b.l0 - v.l1 = a.l1 + b.l1 - v.l2 = a.l2 + b.l2 - v.l3 = a.l3 + b.l3 - v.l4 = a.l4 + b.l4 - // Using the generic implementation here is actually faster than the - // assembly. Probably because the body of this function is so simple that - // the compiler can figure out better optimizations by inlining the carry - // propagation. TODO - return v.carryPropagateGeneric() -} - -// Subtract sets v = a - b, and returns v. -func (v *Element) Subtract(a, b *Element) *Element { - // We first add 2 * p, to guarantee the subtraction won't underflow, and - // then subtract b (which can be up to 2^255 + 2^13 * 19). - v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0 - v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1 - v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2 - v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3 - v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4 - return v.carryPropagate() -} - -// Negate sets v = -a, and returns v. -func (v *Element) Negate(a *Element) *Element { - return v.Subtract(feZero, a) -} - -// Invert sets v = 1/z mod p, and returns v. -// -// If z == 0, Invert returns v = 0. -func (v *Element) Invert(z *Element) *Element { - // Inversion is implemented as exponentiation with exponent p − 2. It uses the - // same sequence of 255 squarings and 11 multiplications as [Curve25519]. - var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element - - z2.Square(z) // 2 - t.Square(&z2) // 4 - t.Square(&t) // 8 - z9.Multiply(&t, z) // 9 - z11.Multiply(&z9, &z2) // 11 - t.Square(&z11) // 22 - z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0 - - t.Square(&z2_5_0) // 2^6 - 2^1 - for i := 0; i < 4; i++ { - t.Square(&t) // 2^10 - 2^5 - } - z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0 - - t.Square(&z2_10_0) // 2^11 - 2^1 - for i := 0; i < 9; i++ { - t.Square(&t) // 2^20 - 2^10 - } - z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0 - - t.Square(&z2_20_0) // 2^21 - 2^1 - for i := 0; i < 19; i++ { - t.Square(&t) // 2^40 - 2^20 - } - t.Multiply(&t, &z2_20_0) // 2^40 - 2^0 - - t.Square(&t) // 2^41 - 2^1 - for i := 0; i < 9; i++ { - t.Square(&t) // 2^50 - 2^10 - } - z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0 - - t.Square(&z2_50_0) // 2^51 - 2^1 - for i := 0; i < 49; i++ { - t.Square(&t) // 2^100 - 2^50 - } - z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0 - - t.Square(&z2_100_0) // 2^101 - 2^1 - for i := 0; i < 99; i++ { - t.Square(&t) // 2^200 - 2^100 - } - t.Multiply(&t, &z2_100_0) // 2^200 - 2^0 - - t.Square(&t) // 2^201 - 2^1 - for i := 0; i < 49; i++ { - t.Square(&t) // 2^250 - 2^50 - } - t.Multiply(&t, &z2_50_0) // 2^250 - 2^0 - - t.Square(&t) // 2^251 - 2^1 - t.Square(&t) // 2^252 - 2^2 - t.Square(&t) // 2^253 - 2^3 - t.Square(&t) // 2^254 - 2^4 - t.Square(&t) // 2^255 - 2^5 - - return v.Multiply(&t, &z11) // 2^255 - 21 -} - -// Set sets v = a, and returns v. -func (v *Element) Set(a *Element) *Element { - *v = *a - return v -} - -// SetBytes sets v to x, which must be a 32-byte little-endian encoding. -// -// Consistent with RFC 7748, the most significant bit (the high bit of the -// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1) -// are accepted. Note that this is laxer than specified by RFC 8032. -func (v *Element) SetBytes(x []byte) *Element { - if len(x) != 32 { - panic("edwards25519: invalid field element input size") - } - - // Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51). - v.l0 = binary.LittleEndian.Uint64(x[0:8]) - v.l0 &= maskLow51Bits - // Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51). - v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3 - v.l1 &= maskLow51Bits - // Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51). - v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6 - v.l2 &= maskLow51Bits - // Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51). - v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1 - v.l3 &= maskLow51Bits - // Bits 204:251 (bytes 24:32, bits 192:256, shift 12, mask 51). - // Note: not bytes 25:33, shift 4, to avoid overread. - v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12 - v.l4 &= maskLow51Bits - - return v -} - -// Bytes returns the canonical 32-byte little-endian encoding of v. -func (v *Element) Bytes() []byte { - // This function is outlined to make the allocations inline in the caller - // rather than happen on the heap. - var out [32]byte - return v.bytes(&out) -} - -func (v *Element) bytes(out *[32]byte) []byte { - t := *v - t.reduce() - - var buf [8]byte - for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} { - bitsOffset := i * 51 - binary.LittleEndian.PutUint64(buf[:], l<= len(out) { - break - } - out[off] |= bb - } - } - - return out[:] -} - -// Equal returns 1 if v and u are equal, and 0 otherwise. -func (v *Element) Equal(u *Element) int { - sa, sv := u.Bytes(), v.Bytes() - return subtle.ConstantTimeCompare(sa, sv) -} - -// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise. -func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) } - -// Select sets v to a if cond == 1, and to b if cond == 0. -func (v *Element) Select(a, b *Element, cond int) *Element { - m := mask64Bits(cond) - v.l0 = (m & a.l0) | (^m & b.l0) - v.l1 = (m & a.l1) | (^m & b.l1) - v.l2 = (m & a.l2) | (^m & b.l2) - v.l3 = (m & a.l3) | (^m & b.l3) - v.l4 = (m & a.l4) | (^m & b.l4) - return v -} - -// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v. -func (v *Element) Swap(u *Element, cond int) { - m := mask64Bits(cond) - t := m & (v.l0 ^ u.l0) - v.l0 ^= t - u.l0 ^= t - t = m & (v.l1 ^ u.l1) - v.l1 ^= t - u.l1 ^= t - t = m & (v.l2 ^ u.l2) - v.l2 ^= t - u.l2 ^= t - t = m & (v.l3 ^ u.l3) - v.l3 ^= t - u.l3 ^= t - t = m & (v.l4 ^ u.l4) - v.l4 ^= t - u.l4 ^= t -} - -// IsNegative returns 1 if v is negative, and 0 otherwise. -func (v *Element) IsNegative() int { - return int(v.Bytes()[0] & 1) -} - -// Absolute sets v to |u|, and returns v. -func (v *Element) Absolute(u *Element) *Element { - return v.Select(new(Element).Negate(u), u, u.IsNegative()) -} - -// Multiply sets v = x * y, and returns v. -func (v *Element) Multiply(x, y *Element) *Element { - feMul(v, x, y) - return v -} - -// Square sets v = x * x, and returns v. -func (v *Element) Square(x *Element) *Element { - feSquare(v, x) - return v -} - -// Mult32 sets v = x * y, and returns v. -func (v *Element) Mult32(x *Element, y uint32) *Element { - x0lo, x0hi := mul51(x.l0, y) - x1lo, x1hi := mul51(x.l1, y) - x2lo, x2hi := mul51(x.l2, y) - x3lo, x3hi := mul51(x.l3, y) - x4lo, x4hi := mul51(x.l4, y) - v.l0 = x0lo + 19*x4hi // carried over per the reduction identity - v.l1 = x1lo + x0hi - v.l2 = x2lo + x1hi - v.l3 = x3lo + x2hi - v.l4 = x4lo + x3hi - // The hi portions are going to be only 32 bits, plus any previous excess, - // so we can skip the carry propagation. - return v -} - -// mul51 returns lo + hi * 2⁵¹ = a * b. -func mul51(a uint64, b uint32) (lo uint64, hi uint64) { - mh, ml := bits.Mul64(a, uint64(b)) - lo = ml & maskLow51Bits - hi = (mh << 13) | (ml >> 51) - return -} - -// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3. -func (v *Element) Pow22523(x *Element) *Element { - var t0, t1, t2 Element - - t0.Square(x) // x^2 - t1.Square(&t0) // x^4 - t1.Square(&t1) // x^8 - t1.Multiply(x, &t1) // x^9 - t0.Multiply(&t0, &t1) // x^11 - t0.Square(&t0) // x^22 - t0.Multiply(&t1, &t0) // x^31 - t1.Square(&t0) // x^62 - for i := 1; i < 5; i++ { // x^992 - t1.Square(&t1) - } - t0.Multiply(&t1, &t0) // x^1023 -> 1023 = 2^10 - 1 - t1.Square(&t0) // 2^11 - 2 - for i := 1; i < 10; i++ { // 2^20 - 2^10 - t1.Square(&t1) - } - t1.Multiply(&t1, &t0) // 2^20 - 1 - t2.Square(&t1) // 2^21 - 2 - for i := 1; i < 20; i++ { // 2^40 - 2^20 - t2.Square(&t2) - } - t1.Multiply(&t2, &t1) // 2^40 - 1 - t1.Square(&t1) // 2^41 - 2 - for i := 1; i < 10; i++ { // 2^50 - 2^10 - t1.Square(&t1) - } - t0.Multiply(&t1, &t0) // 2^50 - 1 - t1.Square(&t0) // 2^51 - 2 - for i := 1; i < 50; i++ { // 2^100 - 2^50 - t1.Square(&t1) - } - t1.Multiply(&t1, &t0) // 2^100 - 1 - t2.Square(&t1) // 2^101 - 2 - for i := 1; i < 100; i++ { // 2^200 - 2^100 - t2.Square(&t2) - } - t1.Multiply(&t2, &t1) // 2^200 - 1 - t1.Square(&t1) // 2^201 - 2 - for i := 1; i < 50; i++ { // 2^250 - 2^50 - t1.Square(&t1) - } - t0.Multiply(&t1, &t0) // 2^250 - 1 - t0.Square(&t0) // 2^251 - 2 - t0.Square(&t0) // 2^252 - 4 - return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3) -} - -// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion. -var sqrtM1 = &Element{1718705420411056, 234908883556509, - 2233514472574048, 2117202627021982, 765476049583133} - -// SqrtRatio sets r to the non-negative square root of the ratio of u and v. -// -// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio -// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00, -// and returns r and 0. -func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) { - var a, b Element - - // r = (u * v3) * (u * v7)^((p-5)/8) - v2 := a.Square(v) - uv3 := b.Multiply(u, b.Multiply(v2, v)) - uv7 := a.Multiply(uv3, a.Square(v2)) - r.Multiply(uv3, r.Pow22523(uv7)) - - check := a.Multiply(v, a.Square(r)) // check = v * r^2 - - uNeg := b.Negate(u) - correctSignSqrt := check.Equal(u) - flippedSignSqrt := check.Equal(uNeg) - flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1)) - - rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r - // r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r) - r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI) - - r.Absolute(r) // Choose the nonnegative square root. - return r, correctSignSqrt | flippedSignSqrt -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go deleted file mode 100644 index 70c541692c..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go +++ /dev/null @@ -1,15 +0,0 @@ -// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT. - -//go:build amd64 && gc && !purego - -package field - -// feMul sets out = a * b. It works like feMulGeneric. -// -//go:noescape -func feMul(out *Element, a *Element, b *Element) - -// feSquare sets out = a * a. It works like feSquareGeneric. -// -//go:noescape -func feSquare(out *Element, a *Element) diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s deleted file mode 100644 index 60817acc41..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s +++ /dev/null @@ -1,378 +0,0 @@ -// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT. - -//go:build amd64 && gc && !purego - -#include "textflag.h" - -// func feMul(out *Element, a *Element, b *Element) -TEXT ·feMul(SB), NOSPLIT, $0-24 - MOVQ a+8(FP), CX - MOVQ b+16(FP), BX - - // r0 = a0×b0 - MOVQ (CX), AX - MULQ (BX) - MOVQ AX, DI - MOVQ DX, SI - - // r0 += 19×a1×b4 - MOVQ 8(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r0 += 19×a2×b3 - MOVQ 16(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r0 += 19×a3×b2 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 16(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r0 += 19×a4×b1 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 8(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r1 = a0×b1 - MOVQ (CX), AX - MULQ 8(BX) - MOVQ AX, R9 - MOVQ DX, R8 - - // r1 += a1×b0 - MOVQ 8(CX), AX - MULQ (BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r1 += 19×a2×b4 - MOVQ 16(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r1 += 19×a3×b3 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r1 += 19×a4×b2 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 16(BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r2 = a0×b2 - MOVQ (CX), AX - MULQ 16(BX) - MOVQ AX, R11 - MOVQ DX, R10 - - // r2 += a1×b1 - MOVQ 8(CX), AX - MULQ 8(BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r2 += a2×b0 - MOVQ 16(CX), AX - MULQ (BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r2 += 19×a3×b4 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r2 += 19×a4×b3 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r3 = a0×b3 - MOVQ (CX), AX - MULQ 24(BX) - MOVQ AX, R13 - MOVQ DX, R12 - - // r3 += a1×b2 - MOVQ 8(CX), AX - MULQ 16(BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r3 += a2×b1 - MOVQ 16(CX), AX - MULQ 8(BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r3 += a3×b0 - MOVQ 24(CX), AX - MULQ (BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r3 += 19×a4×b4 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r4 = a0×b4 - MOVQ (CX), AX - MULQ 32(BX) - MOVQ AX, R15 - MOVQ DX, R14 - - // r4 += a1×b3 - MOVQ 8(CX), AX - MULQ 24(BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // r4 += a2×b2 - MOVQ 16(CX), AX - MULQ 16(BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // r4 += a3×b1 - MOVQ 24(CX), AX - MULQ 8(BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // r4 += a4×b0 - MOVQ 32(CX), AX - MULQ (BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // First reduction chain - MOVQ $0x0007ffffffffffff, AX - SHLQ $0x0d, DI, SI - SHLQ $0x0d, R9, R8 - SHLQ $0x0d, R11, R10 - SHLQ $0x0d, R13, R12 - SHLQ $0x0d, R15, R14 - ANDQ AX, DI - IMUL3Q $0x13, R14, R14 - ADDQ R14, DI - ANDQ AX, R9 - ADDQ SI, R9 - ANDQ AX, R11 - ADDQ R8, R11 - ANDQ AX, R13 - ADDQ R10, R13 - ANDQ AX, R15 - ADDQ R12, R15 - - // Second reduction chain (carryPropagate) - MOVQ DI, SI - SHRQ $0x33, SI - MOVQ R9, R8 - SHRQ $0x33, R8 - MOVQ R11, R10 - SHRQ $0x33, R10 - MOVQ R13, R12 - SHRQ $0x33, R12 - MOVQ R15, R14 - SHRQ $0x33, R14 - ANDQ AX, DI - IMUL3Q $0x13, R14, R14 - ADDQ R14, DI - ANDQ AX, R9 - ADDQ SI, R9 - ANDQ AX, R11 - ADDQ R8, R11 - ANDQ AX, R13 - ADDQ R10, R13 - ANDQ AX, R15 - ADDQ R12, R15 - - // Store output - MOVQ out+0(FP), AX - MOVQ DI, (AX) - MOVQ R9, 8(AX) - MOVQ R11, 16(AX) - MOVQ R13, 24(AX) - MOVQ R15, 32(AX) - RET - -// func feSquare(out *Element, a *Element) -TEXT ·feSquare(SB), NOSPLIT, $0-16 - MOVQ a+8(FP), CX - - // r0 = l0×l0 - MOVQ (CX), AX - MULQ (CX) - MOVQ AX, SI - MOVQ DX, BX - - // r0 += 38×l1×l4 - MOVQ 8(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, SI - ADCQ DX, BX - - // r0 += 38×l2×l3 - MOVQ 16(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 24(CX) - ADDQ AX, SI - ADCQ DX, BX - - // r1 = 2×l0×l1 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 8(CX) - MOVQ AX, R8 - MOVQ DX, DI - - // r1 += 38×l2×l4 - MOVQ 16(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, R8 - ADCQ DX, DI - - // r1 += 19×l3×l3 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(CX) - ADDQ AX, R8 - ADCQ DX, DI - - // r2 = 2×l0×l2 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 16(CX) - MOVQ AX, R10 - MOVQ DX, R9 - - // r2 += l1×l1 - MOVQ 8(CX), AX - MULQ 8(CX) - ADDQ AX, R10 - ADCQ DX, R9 - - // r2 += 38×l3×l4 - MOVQ 24(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, R10 - ADCQ DX, R9 - - // r3 = 2×l0×l3 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 24(CX) - MOVQ AX, R12 - MOVQ DX, R11 - - // r3 += 2×l1×l2 - MOVQ 8(CX), AX - IMUL3Q $0x02, AX, AX - MULQ 16(CX) - ADDQ AX, R12 - ADCQ DX, R11 - - // r3 += 19×l4×l4 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(CX) - ADDQ AX, R12 - ADCQ DX, R11 - - // r4 = 2×l0×l4 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 32(CX) - MOVQ AX, R14 - MOVQ DX, R13 - - // r4 += 2×l1×l3 - MOVQ 8(CX), AX - IMUL3Q $0x02, AX, AX - MULQ 24(CX) - ADDQ AX, R14 - ADCQ DX, R13 - - // r4 += l2×l2 - MOVQ 16(CX), AX - MULQ 16(CX) - ADDQ AX, R14 - ADCQ DX, R13 - - // First reduction chain - MOVQ $0x0007ffffffffffff, AX - SHLQ $0x0d, SI, BX - SHLQ $0x0d, R8, DI - SHLQ $0x0d, R10, R9 - SHLQ $0x0d, R12, R11 - SHLQ $0x0d, R14, R13 - ANDQ AX, SI - IMUL3Q $0x13, R13, R13 - ADDQ R13, SI - ANDQ AX, R8 - ADDQ BX, R8 - ANDQ AX, R10 - ADDQ DI, R10 - ANDQ AX, R12 - ADDQ R9, R12 - ANDQ AX, R14 - ADDQ R11, R14 - - // Second reduction chain (carryPropagate) - MOVQ SI, BX - SHRQ $0x33, BX - MOVQ R8, DI - SHRQ $0x33, DI - MOVQ R10, R9 - SHRQ $0x33, R9 - MOVQ R12, R11 - SHRQ $0x33, R11 - MOVQ R14, R13 - SHRQ $0x33, R13 - ANDQ AX, SI - IMUL3Q $0x13, R13, R13 - ADDQ R13, SI - ANDQ AX, R8 - ADDQ BX, R8 - ANDQ AX, R10 - ADDQ DI, R10 - ANDQ AX, R12 - ADDQ R9, R12 - ANDQ AX, R14 - ADDQ R11, R14 - - // Store output - MOVQ out+0(FP), AX - MOVQ SI, (AX) - MOVQ R8, 8(AX) - MOVQ R10, 16(AX) - MOVQ R12, 24(AX) - MOVQ R14, 32(AX) - RET diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go deleted file mode 100644 index 9da280d1d8..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !amd64 || !gc || purego - -package field - -func feMul(v, x, y *Element) { feMulGeneric(v, x, y) } - -func feSquare(v, x *Element) { feSquareGeneric(v, x) } diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go deleted file mode 100644 index 075fe9b925..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build arm64 && gc && !purego - -package field - -//go:noescape -func carryPropagate(v *Element) - -func (v *Element) carryPropagate() *Element { - carryPropagate(v) - return v -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s deleted file mode 100644 index 3126a43419..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build arm64 && gc && !purego - -#include "textflag.h" - -// carryPropagate works exactly like carryPropagateGeneric and uses the -// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but -// avoids loading R0-R4 twice and uses LDP and STP. -// -// See https://golang.org/issues/43145 for the main compiler issue. -// -// func carryPropagate(v *Element) -TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8 - MOVD v+0(FP), R20 - - LDP 0(R20), (R0, R1) - LDP 16(R20), (R2, R3) - MOVD 32(R20), R4 - - AND $0x7ffffffffffff, R0, R10 - AND $0x7ffffffffffff, R1, R11 - AND $0x7ffffffffffff, R2, R12 - AND $0x7ffffffffffff, R3, R13 - AND $0x7ffffffffffff, R4, R14 - - ADD R0>>51, R11, R11 - ADD R1>>51, R12, R12 - ADD R2>>51, R13, R13 - ADD R3>>51, R14, R14 - // R4>>51 * 19 + R10 -> R10 - LSR $51, R4, R21 - MOVD $19, R22 - MADD R22, R10, R21, R10 - - STP (R10, R11), 0(R20) - STP (R12, R13), 16(R20) - MOVD R14, 32(R20) - - RET diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go deleted file mode 100644 index fc029ac12d..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !arm64 || !gc || purego - -package field - -func (v *Element) carryPropagate() *Element { - return v.carryPropagateGeneric() -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go deleted file mode 100644 index 2671217da5..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package field - -import "math/bits" - -// uint128 holds a 128-bit number as two 64-bit limbs, for use with the -// bits.Mul64 and bits.Add64 intrinsics. -type uint128 struct { - lo, hi uint64 -} - -// mul64 returns a * b. -func mul64(a, b uint64) uint128 { - hi, lo := bits.Mul64(a, b) - return uint128{lo, hi} -} - -// addMul64 returns v + a * b. -func addMul64(v uint128, a, b uint64) uint128 { - hi, lo := bits.Mul64(a, b) - lo, c := bits.Add64(lo, v.lo, 0) - hi, _ = bits.Add64(hi, v.hi, c) - return uint128{lo, hi} -} - -// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits. -func shiftRightBy51(a uint128) uint64 { - return (a.hi << (64 - 51)) | (a.lo >> 51) -} - -func feMulGeneric(v, a, b *Element) { - a0 := a.l0 - a1 := a.l1 - a2 := a.l2 - a3 := a.l3 - a4 := a.l4 - - b0 := b.l0 - b1 := b.l1 - b2 := b.l2 - b3 := b.l3 - b4 := b.l4 - - // Limb multiplication works like pen-and-paper columnar multiplication, but - // with 51-bit limbs instead of digits. - // - // a4 a3 a2 a1 a0 x - // b4 b3 b2 b1 b0 = - // ------------------------ - // a4b0 a3b0 a2b0 a1b0 a0b0 + - // a4b1 a3b1 a2b1 a1b1 a0b1 + - // a4b2 a3b2 a2b2 a1b2 a0b2 + - // a4b3 a3b3 a2b3 a1b3 a0b3 + - // a4b4 a3b4 a2b4 a1b4 a0b4 = - // ---------------------------------------------- - // r8 r7 r6 r5 r4 r3 r2 r1 r0 - // - // We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to - // reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5, - // r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc. - // - // Reduction can be carried out simultaneously to multiplication. For - // example, we do not compute r5: whenever the result of a multiplication - // belongs to r5, like a1b4, we multiply it by 19 and add the result to r0. - // - // a4b0 a3b0 a2b0 a1b0 a0b0 + - // a3b1 a2b1 a1b1 a0b1 19×a4b1 + - // a2b2 a1b2 a0b2 19×a4b2 19×a3b2 + - // a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 + - // a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 = - // -------------------------------------- - // r4 r3 r2 r1 r0 - // - // Finally we add up the columns into wide, overlapping limbs. - - a1_19 := a1 * 19 - a2_19 := a2 * 19 - a3_19 := a3 * 19 - a4_19 := a4 * 19 - - // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1) - r0 := mul64(a0, b0) - r0 = addMul64(r0, a1_19, b4) - r0 = addMul64(r0, a2_19, b3) - r0 = addMul64(r0, a3_19, b2) - r0 = addMul64(r0, a4_19, b1) - - // r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2) - r1 := mul64(a0, b1) - r1 = addMul64(r1, a1, b0) - r1 = addMul64(r1, a2_19, b4) - r1 = addMul64(r1, a3_19, b3) - r1 = addMul64(r1, a4_19, b2) - - // r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3) - r2 := mul64(a0, b2) - r2 = addMul64(r2, a1, b1) - r2 = addMul64(r2, a2, b0) - r2 = addMul64(r2, a3_19, b4) - r2 = addMul64(r2, a4_19, b3) - - // r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4 - r3 := mul64(a0, b3) - r3 = addMul64(r3, a1, b2) - r3 = addMul64(r3, a2, b1) - r3 = addMul64(r3, a3, b0) - r3 = addMul64(r3, a4_19, b4) - - // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0 - r4 := mul64(a0, b4) - r4 = addMul64(r4, a1, b3) - r4 = addMul64(r4, a2, b2) - r4 = addMul64(r4, a3, b1) - r4 = addMul64(r4, a4, b0) - - // After the multiplication, we need to reduce (carry) the five coefficients - // to obtain a result with limbs that are at most slightly larger than 2⁵¹, - // to respect the Element invariant. - // - // Overall, the reduction works the same as carryPropagate, except with - // wider inputs: we take the carry for each coefficient by shifting it right - // by 51, and add it to the limb above it. The top carry is multiplied by 19 - // according to the reduction identity and added to the lowest limb. - // - // The largest coefficient (r0) will be at most 111 bits, which guarantees - // that all carries are at most 111 - 51 = 60 bits, which fits in a uint64. - // - // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1) - // r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²) - // r0 < (1 + 19 × 4) × 2⁵² × 2⁵² - // r0 < 2⁷ × 2⁵² × 2⁵² - // r0 < 2¹¹¹ - // - // Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most - // 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and - // allows us to easily apply the reduction identity. - // - // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0 - // r4 < 5 × 2⁵² × 2⁵² - // r4 < 2¹⁰⁷ - // - - c0 := shiftRightBy51(r0) - c1 := shiftRightBy51(r1) - c2 := shiftRightBy51(r2) - c3 := shiftRightBy51(r3) - c4 := shiftRightBy51(r4) - - rr0 := r0.lo&maskLow51Bits + c4*19 - rr1 := r1.lo&maskLow51Bits + c0 - rr2 := r2.lo&maskLow51Bits + c1 - rr3 := r3.lo&maskLow51Bits + c2 - rr4 := r4.lo&maskLow51Bits + c3 - - // Now all coefficients fit into 64-bit registers but are still too large to - // be passed around as a Element. We therefore do one last carry chain, - // where the carries will be small enough to fit in the wiggle room above 2⁵¹. - *v = Element{rr0, rr1, rr2, rr3, rr4} - v.carryPropagate() -} - -func feSquareGeneric(v, a *Element) { - l0 := a.l0 - l1 := a.l1 - l2 := a.l2 - l3 := a.l3 - l4 := a.l4 - - // Squaring works precisely like multiplication above, but thanks to its - // symmetry we get to group a few terms together. - // - // l4 l3 l2 l1 l0 x - // l4 l3 l2 l1 l0 = - // ------------------------ - // l4l0 l3l0 l2l0 l1l0 l0l0 + - // l4l1 l3l1 l2l1 l1l1 l0l1 + - // l4l2 l3l2 l2l2 l1l2 l0l2 + - // l4l3 l3l3 l2l3 l1l3 l0l3 + - // l4l4 l3l4 l2l4 l1l4 l0l4 = - // ---------------------------------------------- - // r8 r7 r6 r5 r4 r3 r2 r1 r0 - // - // l4l0 l3l0 l2l0 l1l0 l0l0 + - // l3l1 l2l1 l1l1 l0l1 19×l4l1 + - // l2l2 l1l2 l0l2 19×l4l2 19×l3l2 + - // l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 + - // l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 = - // -------------------------------------- - // r4 r3 r2 r1 r0 - // - // With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with - // only three Mul64 and four Add64, instead of five and eight. - - l0_2 := l0 * 2 - l1_2 := l1 * 2 - - l1_38 := l1 * 38 - l2_38 := l2 * 38 - l3_38 := l3 * 38 - - l3_19 := l3 * 19 - l4_19 := l4 * 19 - - // r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3) - r0 := mul64(l0, l0) - r0 = addMul64(r0, l1_38, l4) - r0 = addMul64(r0, l2_38, l3) - - // r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3 - r1 := mul64(l0_2, l1) - r1 = addMul64(r1, l2_38, l4) - r1 = addMul64(r1, l3_19, l3) - - // r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4 - r2 := mul64(l0_2, l2) - r2 = addMul64(r2, l1, l1) - r2 = addMul64(r2, l3_38, l4) - - // r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4 - r3 := mul64(l0_2, l3) - r3 = addMul64(r3, l1_2, l2) - r3 = addMul64(r3, l4_19, l4) - - // r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2 - r4 := mul64(l0_2, l4) - r4 = addMul64(r4, l1_2, l3) - r4 = addMul64(r4, l2, l2) - - c0 := shiftRightBy51(r0) - c1 := shiftRightBy51(r1) - c2 := shiftRightBy51(r2) - c3 := shiftRightBy51(r3) - c4 := shiftRightBy51(r4) - - rr0 := r0.lo&maskLow51Bits + c4*19 - rr1 := r1.lo&maskLow51Bits + c0 - rr2 := r2.lo&maskLow51Bits + c1 - rr3 := r3.lo&maskLow51Bits + c2 - rr4 := r4.lo&maskLow51Bits + c3 - - *v = Element{rr0, rr1, rr2, rr3, rr4} - v.carryPropagate() -} - -// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction -// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline -func (v *Element) carryPropagateGeneric() *Element { - c0 := v.l0 >> 51 - c1 := v.l1 >> 51 - c2 := v.l2 >> 51 - c3 := v.l3 >> 51 - c4 := v.l4 >> 51 - - v.l0 = v.l0&maskLow51Bits + c4*19 - v.l1 = v.l1&maskLow51Bits + c0 - v.l2 = v.l2&maskLow51Bits + c1 - v.l3 = v.l3&maskLow51Bits + c2 - v.l4 = v.l4&maskLow51Bits + c3 - - return v -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint deleted file mode 100644 index e3685f95ca..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint +++ /dev/null @@ -1 +0,0 @@ -b0c49ae9f59d233526f8934262c5bbbe14d4358d diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh deleted file mode 100644 index 1ba22a8b4c..0000000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh +++ /dev/null @@ -1,19 +0,0 @@ -#! /bin/bash -set -euo pipefail - -cd "$(git rev-parse --show-toplevel)" - -STD_PATH=src/crypto/ed25519/internal/edwards25519/field -LOCAL_PATH=curve25519/internal/field -LAST_SYNC_REF=$(cat $LOCAL_PATH/sync.checkpoint) - -git fetch https://go.googlesource.com/go master - -if git diff --quiet $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH; then - echo "No changes." -else - NEW_REF=$(git rev-parse FETCH_HEAD | tee $LOCAL_PATH/sync.checkpoint) - echo "Applying changes from $LAST_SYNC_REF to $NEW_REF..." - git diff $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH | \ - git apply -3 --directory=$LOCAL_PATH -fi diff --git a/vendor/golang.org/x/crypto/hkdf/hkdf.go b/vendor/golang.org/x/crypto/hkdf/hkdf.go index f4ded5fee2..3bee66294e 100644 --- a/vendor/golang.org/x/crypto/hkdf/hkdf.go +++ b/vendor/golang.org/x/crypto/hkdf/hkdf.go @@ -8,7 +8,7 @@ // HKDF is a cryptographic key derivation function (KDF) with the goal of // expanding limited input keying material into one or more cryptographically // strong secret keys. -package hkdf // import "golang.org/x/crypto/hkdf" +package hkdf import ( "crypto/hmac" diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s index e0d3c64756..133757384b 100644 --- a/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s @@ -1,108 +1,93 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Code generated by command: go run sum_amd64_asm.go -out ../sum_amd64.s -pkg poly1305. DO NOT EDIT. //go:build gc && !purego -#include "textflag.h" - -#define POLY1305_ADD(msg, h0, h1, h2) \ - ADDQ 0(msg), h0; \ - ADCQ 8(msg), h1; \ - ADCQ $1, h2; \ - LEAQ 16(msg), msg - -#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3) \ - MOVQ r0, AX; \ - MULQ h0; \ - MOVQ AX, t0; \ - MOVQ DX, t1; \ - MOVQ r0, AX; \ - MULQ h1; \ - ADDQ AX, t1; \ - ADCQ $0, DX; \ - MOVQ r0, t2; \ - IMULQ h2, t2; \ - ADDQ DX, t2; \ - \ - MOVQ r1, AX; \ - MULQ h0; \ - ADDQ AX, t1; \ - ADCQ $0, DX; \ - MOVQ DX, h0; \ - MOVQ r1, t3; \ - IMULQ h2, t3; \ - MOVQ r1, AX; \ - MULQ h1; \ - ADDQ AX, t2; \ - ADCQ DX, t3; \ - ADDQ h0, t2; \ - ADCQ $0, t3; \ - \ - MOVQ t0, h0; \ - MOVQ t1, h1; \ - MOVQ t2, h2; \ - ANDQ $3, h2; \ - MOVQ t2, t0; \ - ANDQ $0xFFFFFFFFFFFFFFFC, t0; \ - ADDQ t0, h0; \ - ADCQ t3, h1; \ - ADCQ $0, h2; \ - SHRQ $2, t3, t2; \ - SHRQ $2, t3; \ - ADDQ t2, h0; \ - ADCQ t3, h1; \ - ADCQ $0, h2 - -// func update(state *[7]uint64, msg []byte) +// func update(state *macState, msg []byte) TEXT ·update(SB), $0-32 MOVQ state+0(FP), DI MOVQ msg_base+8(FP), SI MOVQ msg_len+16(FP), R15 - - MOVQ 0(DI), R8 // h0 - MOVQ 8(DI), R9 // h1 - MOVQ 16(DI), R10 // h2 - MOVQ 24(DI), R11 // r0 - MOVQ 32(DI), R12 // r1 - - CMPQ R15, $16 + MOVQ (DI), R8 + MOVQ 8(DI), R9 + MOVQ 16(DI), R10 + MOVQ 24(DI), R11 + MOVQ 32(DI), R12 + CMPQ R15, $0x10 JB bytes_between_0_and_15 loop: - POLY1305_ADD(SI, R8, R9, R10) + ADDQ (SI), R8 + ADCQ 8(SI), R9 + ADCQ $0x01, R10 + LEAQ 16(SI), SI multiply: - POLY1305_MUL(R8, R9, R10, R11, R12, BX, CX, R13, R14) - SUBQ $16, R15 - CMPQ R15, $16 - JAE loop + MOVQ R11, AX + MULQ R8 + MOVQ AX, BX + MOVQ DX, CX + MOVQ R11, AX + MULQ R9 + ADDQ AX, CX + ADCQ $0x00, DX + MOVQ R11, R13 + IMULQ R10, R13 + ADDQ DX, R13 + MOVQ R12, AX + MULQ R8 + ADDQ AX, CX + ADCQ $0x00, DX + MOVQ DX, R8 + MOVQ R12, R14 + IMULQ R10, R14 + MOVQ R12, AX + MULQ R9 + ADDQ AX, R13 + ADCQ DX, R14 + ADDQ R8, R13 + ADCQ $0x00, R14 + MOVQ BX, R8 + MOVQ CX, R9 + MOVQ R13, R10 + ANDQ $0x03, R10 + MOVQ R13, BX + ANDQ $-4, BX + ADDQ BX, R8 + ADCQ R14, R9 + ADCQ $0x00, R10 + SHRQ $0x02, R14, R13 + SHRQ $0x02, R14 + ADDQ R13, R8 + ADCQ R14, R9 + ADCQ $0x00, R10 + SUBQ $0x10, R15 + CMPQ R15, $0x10 + JAE loop bytes_between_0_and_15: TESTQ R15, R15 JZ done - MOVQ $1, BX + MOVQ $0x00000001, BX XORQ CX, CX XORQ R13, R13 ADDQ R15, SI flush_buffer: - SHLQ $8, BX, CX - SHLQ $8, BX + SHLQ $0x08, BX, CX + SHLQ $0x08, BX MOVB -1(SI), R13 XORQ R13, BX DECQ SI DECQ R15 JNZ flush_buffer - ADDQ BX, R8 ADCQ CX, R9 - ADCQ $0, R10 - MOVQ $16, R15 + ADCQ $0x00, R10 + MOVQ $0x00000010, R15 JMP multiply done: - MOVQ R8, 0(DI) + MOVQ R8, (DI) MOVQ R9, 8(DI) MOVQ R10, 16(DI) RET diff --git a/vendor/golang.org/x/crypto/openpgp/armor/armor.go b/vendor/golang.org/x/crypto/openpgp/armor/armor.go index 8907183ec0..e664d127cb 100644 --- a/vendor/golang.org/x/crypto/openpgp/armor/armor.go +++ b/vendor/golang.org/x/crypto/openpgp/armor/armor.go @@ -10,14 +10,15 @@ // for their specific task. If you are required to interoperate with OpenPGP // systems and need a maintained package, consider a community fork. // See https://golang.org/issue/44226. -package armor // import "golang.org/x/crypto/openpgp/armor" +package armor import ( "bufio" "bytes" "encoding/base64" - "golang.org/x/crypto/openpgp/errors" "io" + + "golang.org/x/crypto/openpgp/errors" ) // A Block represents an OpenPGP armored structure. diff --git a/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go index 743b35a120..f922bdbcaa 100644 --- a/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go +++ b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go @@ -16,7 +16,7 @@ // https://golang.org/issue/44226), and ElGamal in the OpenPGP ecosystem has // compatibility and security issues (see https://eprint.iacr.org/2021/923). // Moreover, this package doesn't protect against side-channel attacks. -package elgamal // import "golang.org/x/crypto/openpgp/elgamal" +package elgamal import ( "crypto/rand" diff --git a/vendor/golang.org/x/crypto/openpgp/errors/errors.go b/vendor/golang.org/x/crypto/openpgp/errors/errors.go index 1d7a0ea05a..a328749471 100644 --- a/vendor/golang.org/x/crypto/openpgp/errors/errors.go +++ b/vendor/golang.org/x/crypto/openpgp/errors/errors.go @@ -9,7 +9,7 @@ // for their specific task. If you are required to interoperate with OpenPGP // systems and need a maintained package, consider a community fork. // See https://golang.org/issue/44226. -package errors // import "golang.org/x/crypto/openpgp/errors" +package errors import ( "strconv" diff --git a/vendor/golang.org/x/crypto/openpgp/packet/packet.go b/vendor/golang.org/x/crypto/openpgp/packet/packet.go index 0a19794a8e..a84a1a214e 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/packet.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/packet.go @@ -10,7 +10,7 @@ // for their specific task. If you are required to interoperate with OpenPGP // systems and need a maintained package, consider a community fork. // See https://golang.org/issue/44226. -package packet // import "golang.org/x/crypto/openpgp/packet" +package packet import ( "bufio" diff --git a/vendor/golang.org/x/crypto/openpgp/read.go b/vendor/golang.org/x/crypto/openpgp/read.go index 48a8931468..cff3db9196 100644 --- a/vendor/golang.org/x/crypto/openpgp/read.go +++ b/vendor/golang.org/x/crypto/openpgp/read.go @@ -9,7 +9,7 @@ // for their specific task. If you are required to interoperate with OpenPGP // systems and need a maintained package, consider a community fork. // See https://golang.org/issue/44226. -package openpgp // import "golang.org/x/crypto/openpgp" +package openpgp import ( "crypto" diff --git a/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go b/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go index f53244a1c7..fa1a919079 100644 --- a/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go +++ b/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go @@ -10,7 +10,7 @@ // for their specific task. If you are required to interoperate with OpenPGP // systems and need a maintained package, consider a community fork. // See https://golang.org/issue/44226. -package s2k // import "golang.org/x/crypto/openpgp/s2k" +package s2k import ( "crypto" diff --git a/vendor/golang.org/x/crypto/sha3/doc.go b/vendor/golang.org/x/crypto/sha3/doc.go index decd8cf9bf..7e02309070 100644 --- a/vendor/golang.org/x/crypto/sha3/doc.go +++ b/vendor/golang.org/x/crypto/sha3/doc.go @@ -59,4 +59,4 @@ // They produce output of the same length, with the same security strengths // against all attacks. This means, in particular, that SHA3-256 only has // 128-bit collision resistance, because its output length is 32 bytes. -package sha3 // import "golang.org/x/crypto/sha3" +package sha3 diff --git a/vendor/golang.org/x/crypto/sha3/hashes.go b/vendor/golang.org/x/crypto/sha3/hashes.go index 0d8043fd2a..c544b29e5f 100644 --- a/vendor/golang.org/x/crypto/sha3/hashes.go +++ b/vendor/golang.org/x/crypto/sha3/hashes.go @@ -9,6 +9,7 @@ package sha3 // bytes. import ( + "crypto" "hash" ) @@ -16,39 +17,50 @@ import ( // Its generic security strength is 224 bits against preimage attacks, // and 112 bits against collision attacks. func New224() hash.Hash { - if h := new224Asm(); h != nil { - return h - } - return &state{rate: 144, outputLen: 28, dsbyte: 0x06} + return new224() } // New256 creates a new SHA3-256 hash. // Its generic security strength is 256 bits against preimage attacks, // and 128 bits against collision attacks. func New256() hash.Hash { - if h := new256Asm(); h != nil { - return h - } - return &state{rate: 136, outputLen: 32, dsbyte: 0x06} + return new256() } // New384 creates a new SHA3-384 hash. // Its generic security strength is 384 bits against preimage attacks, // and 192 bits against collision attacks. func New384() hash.Hash { - if h := new384Asm(); h != nil { - return h - } - return &state{rate: 104, outputLen: 48, dsbyte: 0x06} + return new384() } // New512 creates a new SHA3-512 hash. // Its generic security strength is 512 bits against preimage attacks, // and 256 bits against collision attacks. func New512() hash.Hash { - if h := new512Asm(); h != nil { - return h - } + return new512() +} + +func init() { + crypto.RegisterHash(crypto.SHA3_224, New224) + crypto.RegisterHash(crypto.SHA3_256, New256) + crypto.RegisterHash(crypto.SHA3_384, New384) + crypto.RegisterHash(crypto.SHA3_512, New512) +} + +func new224Generic() *state { + return &state{rate: 144, outputLen: 28, dsbyte: 0x06} +} + +func new256Generic() *state { + return &state{rate: 136, outputLen: 32, dsbyte: 0x06} +} + +func new384Generic() *state { + return &state{rate: 104, outputLen: 48, dsbyte: 0x06} +} + +func new512Generic() *state { return &state{rate: 72, outputLen: 64, dsbyte: 0x06} } diff --git a/vendor/golang.org/x/crypto/sha3/hashes_generic.go b/vendor/golang.org/x/crypto/sha3/hashes_generic.go deleted file mode 100644 index fe8c84793c..0000000000 --- a/vendor/golang.org/x/crypto/sha3/hashes_generic.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !gc || purego || !s390x - -package sha3 - -import ( - "hash" -) - -// new224Asm returns an assembly implementation of SHA3-224 if available, -// otherwise it returns nil. -func new224Asm() hash.Hash { return nil } - -// new256Asm returns an assembly implementation of SHA3-256 if available, -// otherwise it returns nil. -func new256Asm() hash.Hash { return nil } - -// new384Asm returns an assembly implementation of SHA3-384 if available, -// otherwise it returns nil. -func new384Asm() hash.Hash { return nil } - -// new512Asm returns an assembly implementation of SHA3-512 if available, -// otherwise it returns nil. -func new512Asm() hash.Hash { return nil } diff --git a/vendor/golang.org/x/crypto/sha3/hashes_noasm.go b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go new file mode 100644 index 0000000000..9d85fb6214 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go @@ -0,0 +1,23 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !gc || purego || !s390x + +package sha3 + +func new224() *state { + return new224Generic() +} + +func new256() *state { + return new256Generic() +} + +func new384() *state { + return new384Generic() +} + +func new512() *state { + return new512Generic() +} diff --git a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s index 1f53938861..99e2f16e97 100644 --- a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s +++ b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s @@ -1,390 +1,5419 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Code generated by command: go run keccakf_amd64_asm.go -out ../keccakf_amd64.s -pkg sha3. DO NOT EDIT. //go:build amd64 && !purego && gc -// This code was translated into a form compatible with 6a from the public -// domain sources at https://github.com/gvanas/KeccakCodePackage - -// Offsets in state -#define _ba (0*8) -#define _be (1*8) -#define _bi (2*8) -#define _bo (3*8) -#define _bu (4*8) -#define _ga (5*8) -#define _ge (6*8) -#define _gi (7*8) -#define _go (8*8) -#define _gu (9*8) -#define _ka (10*8) -#define _ke (11*8) -#define _ki (12*8) -#define _ko (13*8) -#define _ku (14*8) -#define _ma (15*8) -#define _me (16*8) -#define _mi (17*8) -#define _mo (18*8) -#define _mu (19*8) -#define _sa (20*8) -#define _se (21*8) -#define _si (22*8) -#define _so (23*8) -#define _su (24*8) - -// Temporary registers -#define rT1 AX - -// Round vars -#define rpState DI -#define rpStack SP - -#define rDa BX -#define rDe CX -#define rDi DX -#define rDo R8 -#define rDu R9 - -#define rBa R10 -#define rBe R11 -#define rBi R12 -#define rBo R13 -#define rBu R14 - -#define rCa SI -#define rCe BP -#define rCi rBi -#define rCo rBo -#define rCu R15 - -#define MOVQ_RBI_RCE MOVQ rBi, rCe -#define XORQ_RT1_RCA XORQ rT1, rCa -#define XORQ_RT1_RCE XORQ rT1, rCe -#define XORQ_RBA_RCU XORQ rBa, rCu -#define XORQ_RBE_RCU XORQ rBe, rCu -#define XORQ_RDU_RCU XORQ rDu, rCu -#define XORQ_RDA_RCA XORQ rDa, rCa -#define XORQ_RDE_RCE XORQ rDe, rCe - -#define mKeccakRound(iState, oState, rc, B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU, K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA, M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA, S_RDE_RCE) \ - /* Prepare round */ \ - MOVQ rCe, rDa; \ - ROLQ $1, rDa; \ - \ - MOVQ _bi(iState), rCi; \ - XORQ _gi(iState), rDi; \ - XORQ rCu, rDa; \ - XORQ _ki(iState), rCi; \ - XORQ _mi(iState), rDi; \ - XORQ rDi, rCi; \ - \ - MOVQ rCi, rDe; \ - ROLQ $1, rDe; \ - \ - MOVQ _bo(iState), rCo; \ - XORQ _go(iState), rDo; \ - XORQ rCa, rDe; \ - XORQ _ko(iState), rCo; \ - XORQ _mo(iState), rDo; \ - XORQ rDo, rCo; \ - \ - MOVQ rCo, rDi; \ - ROLQ $1, rDi; \ - \ - MOVQ rCu, rDo; \ - XORQ rCe, rDi; \ - ROLQ $1, rDo; \ - \ - MOVQ rCa, rDu; \ - XORQ rCi, rDo; \ - ROLQ $1, rDu; \ - \ - /* Result b */ \ - MOVQ _ba(iState), rBa; \ - MOVQ _ge(iState), rBe; \ - XORQ rCo, rDu; \ - MOVQ _ki(iState), rBi; \ - MOVQ _mo(iState), rBo; \ - MOVQ _su(iState), rBu; \ - XORQ rDe, rBe; \ - ROLQ $44, rBe; \ - XORQ rDi, rBi; \ - XORQ rDa, rBa; \ - ROLQ $43, rBi; \ - \ - MOVQ rBe, rCa; \ - MOVQ rc, rT1; \ - ORQ rBi, rCa; \ - XORQ rBa, rT1; \ - XORQ rT1, rCa; \ - MOVQ rCa, _ba(oState); \ - \ - XORQ rDu, rBu; \ - ROLQ $14, rBu; \ - MOVQ rBa, rCu; \ - ANDQ rBe, rCu; \ - XORQ rBu, rCu; \ - MOVQ rCu, _bu(oState); \ - \ - XORQ rDo, rBo; \ - ROLQ $21, rBo; \ - MOVQ rBo, rT1; \ - ANDQ rBu, rT1; \ - XORQ rBi, rT1; \ - MOVQ rT1, _bi(oState); \ - \ - NOTQ rBi; \ - ORQ rBa, rBu; \ - ORQ rBo, rBi; \ - XORQ rBo, rBu; \ - XORQ rBe, rBi; \ - MOVQ rBu, _bo(oState); \ - MOVQ rBi, _be(oState); \ - B_RBI_RCE; \ - \ - /* Result g */ \ - MOVQ _gu(iState), rBe; \ - XORQ rDu, rBe; \ - MOVQ _ka(iState), rBi; \ - ROLQ $20, rBe; \ - XORQ rDa, rBi; \ - ROLQ $3, rBi; \ - MOVQ _bo(iState), rBa; \ - MOVQ rBe, rT1; \ - ORQ rBi, rT1; \ - XORQ rDo, rBa; \ - MOVQ _me(iState), rBo; \ - MOVQ _si(iState), rBu; \ - ROLQ $28, rBa; \ - XORQ rBa, rT1; \ - MOVQ rT1, _ga(oState); \ - G_RT1_RCA; \ - \ - XORQ rDe, rBo; \ - ROLQ $45, rBo; \ - MOVQ rBi, rT1; \ - ANDQ rBo, rT1; \ - XORQ rBe, rT1; \ - MOVQ rT1, _ge(oState); \ - G_RT1_RCE; \ - \ - XORQ rDi, rBu; \ - ROLQ $61, rBu; \ - MOVQ rBu, rT1; \ - ORQ rBa, rT1; \ - XORQ rBo, rT1; \ - MOVQ rT1, _go(oState); \ - \ - ANDQ rBe, rBa; \ - XORQ rBu, rBa; \ - MOVQ rBa, _gu(oState); \ - NOTQ rBu; \ - G_RBA_RCU; \ - \ - ORQ rBu, rBo; \ - XORQ rBi, rBo; \ - MOVQ rBo, _gi(oState); \ - \ - /* Result k */ \ - MOVQ _be(iState), rBa; \ - MOVQ _gi(iState), rBe; \ - MOVQ _ko(iState), rBi; \ - MOVQ _mu(iState), rBo; \ - MOVQ _sa(iState), rBu; \ - XORQ rDi, rBe; \ - ROLQ $6, rBe; \ - XORQ rDo, rBi; \ - ROLQ $25, rBi; \ - MOVQ rBe, rT1; \ - ORQ rBi, rT1; \ - XORQ rDe, rBa; \ - ROLQ $1, rBa; \ - XORQ rBa, rT1; \ - MOVQ rT1, _ka(oState); \ - K_RT1_RCA; \ - \ - XORQ rDu, rBo; \ - ROLQ $8, rBo; \ - MOVQ rBi, rT1; \ - ANDQ rBo, rT1; \ - XORQ rBe, rT1; \ - MOVQ rT1, _ke(oState); \ - K_RT1_RCE; \ - \ - XORQ rDa, rBu; \ - ROLQ $18, rBu; \ - NOTQ rBo; \ - MOVQ rBo, rT1; \ - ANDQ rBu, rT1; \ - XORQ rBi, rT1; \ - MOVQ rT1, _ki(oState); \ - \ - MOVQ rBu, rT1; \ - ORQ rBa, rT1; \ - XORQ rBo, rT1; \ - MOVQ rT1, _ko(oState); \ - \ - ANDQ rBe, rBa; \ - XORQ rBu, rBa; \ - MOVQ rBa, _ku(oState); \ - K_RBA_RCU; \ - \ - /* Result m */ \ - MOVQ _ga(iState), rBe; \ - XORQ rDa, rBe; \ - MOVQ _ke(iState), rBi; \ - ROLQ $36, rBe; \ - XORQ rDe, rBi; \ - MOVQ _bu(iState), rBa; \ - ROLQ $10, rBi; \ - MOVQ rBe, rT1; \ - MOVQ _mi(iState), rBo; \ - ANDQ rBi, rT1; \ - XORQ rDu, rBa; \ - MOVQ _so(iState), rBu; \ - ROLQ $27, rBa; \ - XORQ rBa, rT1; \ - MOVQ rT1, _ma(oState); \ - M_RT1_RCA; \ - \ - XORQ rDi, rBo; \ - ROLQ $15, rBo; \ - MOVQ rBi, rT1; \ - ORQ rBo, rT1; \ - XORQ rBe, rT1; \ - MOVQ rT1, _me(oState); \ - M_RT1_RCE; \ - \ - XORQ rDo, rBu; \ - ROLQ $56, rBu; \ - NOTQ rBo; \ - MOVQ rBo, rT1; \ - ORQ rBu, rT1; \ - XORQ rBi, rT1; \ - MOVQ rT1, _mi(oState); \ - \ - ORQ rBa, rBe; \ - XORQ rBu, rBe; \ - MOVQ rBe, _mu(oState); \ - \ - ANDQ rBa, rBu; \ - XORQ rBo, rBu; \ - MOVQ rBu, _mo(oState); \ - M_RBE_RCU; \ - \ - /* Result s */ \ - MOVQ _bi(iState), rBa; \ - MOVQ _go(iState), rBe; \ - MOVQ _ku(iState), rBi; \ - XORQ rDi, rBa; \ - MOVQ _ma(iState), rBo; \ - ROLQ $62, rBa; \ - XORQ rDo, rBe; \ - MOVQ _se(iState), rBu; \ - ROLQ $55, rBe; \ - \ - XORQ rDu, rBi; \ - MOVQ rBa, rDu; \ - XORQ rDe, rBu; \ - ROLQ $2, rBu; \ - ANDQ rBe, rDu; \ - XORQ rBu, rDu; \ - MOVQ rDu, _su(oState); \ - \ - ROLQ $39, rBi; \ - S_RDU_RCU; \ - NOTQ rBe; \ - XORQ rDa, rBo; \ - MOVQ rBe, rDa; \ - ANDQ rBi, rDa; \ - XORQ rBa, rDa; \ - MOVQ rDa, _sa(oState); \ - S_RDA_RCA; \ - \ - ROLQ $41, rBo; \ - MOVQ rBi, rDe; \ - ORQ rBo, rDe; \ - XORQ rBe, rDe; \ - MOVQ rDe, _se(oState); \ - S_RDE_RCE; \ - \ - MOVQ rBo, rDi; \ - MOVQ rBu, rDo; \ - ANDQ rBu, rDi; \ - ORQ rBa, rDo; \ - XORQ rBi, rDi; \ - XORQ rBo, rDo; \ - MOVQ rDi, _si(oState); \ - MOVQ rDo, _so(oState) \ - // func keccakF1600(a *[25]uint64) -TEXT ·keccakF1600(SB), 0, $200-8 - MOVQ a+0(FP), rpState +TEXT ·keccakF1600(SB), $200-8 + MOVQ a+0(FP), DI // Convert the user state into an internal state - NOTQ _be(rpState) - NOTQ _bi(rpState) - NOTQ _go(rpState) - NOTQ _ki(rpState) - NOTQ _mi(rpState) - NOTQ _sa(rpState) + NOTQ 8(DI) + NOTQ 16(DI) + NOTQ 64(DI) + NOTQ 96(DI) + NOTQ 136(DI) + NOTQ 160(DI) // Execute the KeccakF permutation - MOVQ _ba(rpState), rCa - MOVQ _be(rpState), rCe - MOVQ _bu(rpState), rCu - - XORQ _ga(rpState), rCa - XORQ _ge(rpState), rCe - XORQ _gu(rpState), rCu - - XORQ _ka(rpState), rCa - XORQ _ke(rpState), rCe - XORQ _ku(rpState), rCu - - XORQ _ma(rpState), rCa - XORQ _me(rpState), rCe - XORQ _mu(rpState), rCu - - XORQ _sa(rpState), rCa - XORQ _se(rpState), rCe - MOVQ _si(rpState), rDi - MOVQ _so(rpState), rDo - XORQ _su(rpState), rCu - - mKeccakRound(rpState, rpStack, $0x0000000000000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x0000000000008082, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x800000000000808a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x8000000080008000, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x000000000000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x8000000000008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x000000000000008a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x0000000000000088, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x0000000080008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x000000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x000000008000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x800000000000008b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x8000000000008089, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x8000000000008003, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x8000000000008002, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x8000000000000080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x000000000000800a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x800000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x8000000000008080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpState, rpStack, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) - mKeccakRound(rpStack, rpState, $0x8000000080008008, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP) + MOVQ (DI), SI + MOVQ 8(DI), BP + MOVQ 32(DI), R15 + XORQ 40(DI), SI + XORQ 48(DI), BP + XORQ 72(DI), R15 + XORQ 80(DI), SI + XORQ 88(DI), BP + XORQ 112(DI), R15 + XORQ 120(DI), SI + XORQ 128(DI), BP + XORQ 152(DI), R15 + XORQ 160(DI), SI + XORQ 168(DI), BP + MOVQ 176(DI), DX + MOVQ 184(DI), R8 + XORQ 192(DI), R15 - // Revert the internal state to the user state - NOTQ _be(rpState) - NOTQ _bi(rpState) - NOTQ _go(rpState) - NOTQ _ki(rpState) - NOTQ _mi(rpState) - NOTQ _sa(rpState) + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000000000001, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000000008082, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x800000000000808a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000080008000, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000000000808b, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000080000001, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000080008081, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008009, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000000000008a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000000000088, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000080008009, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000008000000a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000008000808b, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x800000000000008b, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008089, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008003, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008002, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000000080, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000000000800a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x800000008000000a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000080008081, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008080, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000080000001, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000080008008, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + NOP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + NOP + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + NOP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + NOP + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + NOP + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + NOP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + NOP + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + NOP + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + NOP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + NOP + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + NOP + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + NOP + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + NOP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Revert the internal state to the user state + NOTQ 8(DI) + NOTQ 16(DI) + NOTQ 64(DI) + NOTQ 96(DI) + NOTQ 136(DI) + NOTQ 160(DI) RET diff --git a/vendor/golang.org/x/crypto/sha3/register.go b/vendor/golang.org/x/crypto/sha3/register.go deleted file mode 100644 index addfd5049b..0000000000 --- a/vendor/golang.org/x/crypto/sha3/register.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.4 - -package sha3 - -import ( - "crypto" -) - -func init() { - crypto.RegisterHash(crypto.SHA3_224, New224) - crypto.RegisterHash(crypto.SHA3_256, New256) - crypto.RegisterHash(crypto.SHA3_384, New384) - crypto.RegisterHash(crypto.SHA3_512, New512) -} diff --git a/vendor/golang.org/x/crypto/sha3/sha3.go b/vendor/golang.org/x/crypto/sha3/sha3.go index 4884d172a4..afedde5abf 100644 --- a/vendor/golang.org/x/crypto/sha3/sha3.go +++ b/vendor/golang.org/x/crypto/sha3/sha3.go @@ -23,7 +23,6 @@ const ( type state struct { // Generic sponge components. a [25]uint64 // main state of the hash - buf []byte // points into storage rate int // the number of bytes of state to use // dsbyte contains the "domain separation" bits and the first bit of @@ -40,7 +39,8 @@ type state struct { // Extendable-Output Functions (May 2014)" dsbyte byte - storage storageBuf + i, n int // storage[i:n] is the buffer, i is only used while squeezing + storage [maxRate]byte // Specific to SHA-3 and SHAKE. outputLen int // the default output size in bytes @@ -54,24 +54,18 @@ func (d *state) BlockSize() int { return d.rate } func (d *state) Size() int { return d.outputLen } // Reset clears the internal state by zeroing the sponge state and -// the byte buffer, and setting Sponge.state to absorbing. +// the buffer indexes, and setting Sponge.state to absorbing. func (d *state) Reset() { // Zero the permutation's state. for i := range d.a { d.a[i] = 0 } d.state = spongeAbsorbing - d.buf = d.storage.asBytes()[:0] + d.i, d.n = 0, 0 } func (d *state) clone() *state { ret := *d - if ret.state == spongeAbsorbing { - ret.buf = ret.storage.asBytes()[:len(ret.buf)] - } else { - ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate] - } - return &ret } @@ -82,43 +76,40 @@ func (d *state) permute() { case spongeAbsorbing: // If we're absorbing, we need to xor the input into the state // before applying the permutation. - xorIn(d, d.buf) - d.buf = d.storage.asBytes()[:0] + xorIn(d, d.storage[:d.rate]) + d.n = 0 keccakF1600(&d.a) case spongeSqueezing: // If we're squeezing, we need to apply the permutation before // copying more output. keccakF1600(&d.a) - d.buf = d.storage.asBytes()[:d.rate] - copyOut(d, d.buf) + d.i = 0 + copyOut(d, d.storage[:d.rate]) } } // pads appends the domain separation bits in dsbyte, applies // the multi-bitrate 10..1 padding rule, and permutes the state. -func (d *state) padAndPermute(dsbyte byte) { - if d.buf == nil { - d.buf = d.storage.asBytes()[:0] - } +func (d *state) padAndPermute() { // Pad with this instance's domain-separator bits. We know that there's // at least one byte of space in d.buf because, if it were full, // permute would have been called to empty it. dsbyte also contains the // first one bit for the padding. See the comment in the state struct. - d.buf = append(d.buf, dsbyte) - zerosStart := len(d.buf) - d.buf = d.storage.asBytes()[:d.rate] - for i := zerosStart; i < d.rate; i++ { - d.buf[i] = 0 + d.storage[d.n] = d.dsbyte + d.n++ + for d.n < d.rate { + d.storage[d.n] = 0 + d.n++ } // This adds the final one bit for the padding. Because of the way that // bits are numbered from the LSB upwards, the final bit is the MSB of // the last byte. - d.buf[d.rate-1] ^= 0x80 + d.storage[d.rate-1] ^= 0x80 // Apply the permutation d.permute() d.state = spongeSqueezing - d.buf = d.storage.asBytes()[:d.rate] - copyOut(d, d.buf) + d.n = d.rate + copyOut(d, d.storage[:d.rate]) } // Write absorbs more data into the hash's state. It panics if any @@ -127,28 +118,25 @@ func (d *state) Write(p []byte) (written int, err error) { if d.state != spongeAbsorbing { panic("sha3: Write after Read") } - if d.buf == nil { - d.buf = d.storage.asBytes()[:0] - } written = len(p) for len(p) > 0 { - if len(d.buf) == 0 && len(p) >= d.rate { + if d.n == 0 && len(p) >= d.rate { // The fast path; absorb a full "rate" bytes of input and apply the permutation. xorIn(d, p[:d.rate]) p = p[d.rate:] keccakF1600(&d.a) } else { // The slow path; buffer the input until we can fill the sponge, and then xor it in. - todo := d.rate - len(d.buf) + todo := d.rate - d.n if todo > len(p) { todo = len(p) } - d.buf = append(d.buf, p[:todo]...) + d.n += copy(d.storage[d.n:], p[:todo]) p = p[todo:] // If the sponge is full, apply the permutation. - if len(d.buf) == d.rate { + if d.n == d.rate { d.permute() } } @@ -161,19 +149,19 @@ func (d *state) Write(p []byte) (written int, err error) { func (d *state) Read(out []byte) (n int, err error) { // If we're still absorbing, pad and apply the permutation. if d.state == spongeAbsorbing { - d.padAndPermute(d.dsbyte) + d.padAndPermute() } n = len(out) // Now, do the squeezing. for len(out) > 0 { - n := copy(out, d.buf) - d.buf = d.buf[n:] + n := copy(out, d.storage[d.i:d.n]) + d.i += n out = out[n:] // Apply the permutation if we've squeezed the sponge dry. - if len(d.buf) == 0 { + if d.i == d.rate { d.permute() } } diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go index b4fbbf8695..00d8034ae6 100644 --- a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go +++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go @@ -248,56 +248,56 @@ func (s *asmState) Clone() ShakeHash { return s.clone() } -// new224Asm returns an assembly implementation of SHA3-224 if available, -// otherwise it returns nil. -func new224Asm() hash.Hash { +// new224 returns an assembly implementation of SHA3-224 if available, +// otherwise it returns a generic implementation. +func new224() hash.Hash { if cpu.S390X.HasSHA3 { return newAsmState(sha3_224) } - return nil + return new224Generic() } -// new256Asm returns an assembly implementation of SHA3-256 if available, -// otherwise it returns nil. -func new256Asm() hash.Hash { +// new256 returns an assembly implementation of SHA3-256 if available, +// otherwise it returns a generic implementation. +func new256() hash.Hash { if cpu.S390X.HasSHA3 { return newAsmState(sha3_256) } - return nil + return new256Generic() } -// new384Asm returns an assembly implementation of SHA3-384 if available, -// otherwise it returns nil. -func new384Asm() hash.Hash { +// new384 returns an assembly implementation of SHA3-384 if available, +// otherwise it returns a generic implementation. +func new384() hash.Hash { if cpu.S390X.HasSHA3 { return newAsmState(sha3_384) } - return nil + return new384Generic() } -// new512Asm returns an assembly implementation of SHA3-512 if available, -// otherwise it returns nil. -func new512Asm() hash.Hash { +// new512 returns an assembly implementation of SHA3-512 if available, +// otherwise it returns a generic implementation. +func new512() hash.Hash { if cpu.S390X.HasSHA3 { return newAsmState(sha3_512) } - return nil + return new512Generic() } -// newShake128Asm returns an assembly implementation of SHAKE-128 if available, -// otherwise it returns nil. -func newShake128Asm() ShakeHash { +// newShake128 returns an assembly implementation of SHAKE-128 if available, +// otherwise it returns a generic implementation. +func newShake128() ShakeHash { if cpu.S390X.HasSHA3 { return newAsmState(shake_128) } - return nil + return newShake128Generic() } -// newShake256Asm returns an assembly implementation of SHAKE-256 if available, -// otherwise it returns nil. -func newShake256Asm() ShakeHash { +// newShake256 returns an assembly implementation of SHAKE-256 if available, +// otherwise it returns a generic implementation. +func newShake256() ShakeHash { if cpu.S390X.HasSHA3 { return newAsmState(shake_256) } - return nil + return newShake256Generic() } diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go index bb69984027..1ea9275b8b 100644 --- a/vendor/golang.org/x/crypto/sha3/shake.go +++ b/vendor/golang.org/x/crypto/sha3/shake.go @@ -115,19 +115,21 @@ func (c *state) Clone() ShakeHash { // Its generic security strength is 128 bits against all attacks if at // least 32 bytes of its output are used. func NewShake128() ShakeHash { - if h := newShake128Asm(); h != nil { - return h - } - return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake} + return newShake128() } // NewShake256 creates a new SHAKE256 variable-output-length ShakeHash. // Its generic security strength is 256 bits against all attacks if // at least 64 bytes of its output are used. func NewShake256() ShakeHash { - if h := newShake256Asm(); h != nil { - return h - } + return newShake256() +} + +func newShake128Generic() *state { + return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake} +} + +func newShake256Generic() *state { return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake} } diff --git a/vendor/golang.org/x/crypto/sha3/shake_generic.go b/vendor/golang.org/x/crypto/sha3/shake_generic.go deleted file mode 100644 index 8d31cf5be2..0000000000 --- a/vendor/golang.org/x/crypto/sha3/shake_generic.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !gc || purego || !s390x - -package sha3 - -// newShake128Asm returns an assembly implementation of SHAKE-128 if available, -// otherwise it returns nil. -func newShake128Asm() ShakeHash { - return nil -} - -// newShake256Asm returns an assembly implementation of SHAKE-256 if available, -// otherwise it returns nil. -func newShake256Asm() ShakeHash { - return nil -} diff --git a/vendor/golang.org/x/crypto/sha3/shake_noasm.go b/vendor/golang.org/x/crypto/sha3/shake_noasm.go new file mode 100644 index 0000000000..4276ba4ab2 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/shake_noasm.go @@ -0,0 +1,15 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !gc || purego || !s390x + +package sha3 + +func newShake128() *state { + return newShake128Generic() +} + +func newShake256() *state { + return newShake256Generic() +} diff --git a/vendor/golang.org/x/crypto/sha3/xor.go b/vendor/golang.org/x/crypto/sha3/xor.go index 7337cca88e..6ada5c9574 100644 --- a/vendor/golang.org/x/crypto/sha3/xor.go +++ b/vendor/golang.org/x/crypto/sha3/xor.go @@ -2,22 +2,39 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (!amd64 && !386 && !ppc64le) || purego - package sha3 -// A storageBuf is an aligned array of maxRate bytes. -type storageBuf [maxRate]byte - -func (b *storageBuf) asBytes() *[maxRate]byte { - return (*[maxRate]byte)(b) -} +import ( + "crypto/subtle" + "encoding/binary" + "unsafe" -var ( - xorIn = xorInGeneric - copyOut = copyOutGeneric - xorInUnaligned = xorInGeneric - copyOutUnaligned = copyOutGeneric + "golang.org/x/sys/cpu" ) -const xorImplementationUnaligned = "generic" +// xorIn xors the bytes in buf into the state. +func xorIn(d *state, buf []byte) { + if cpu.IsBigEndian { + for i := 0; len(buf) >= 8; i++ { + a := binary.LittleEndian.Uint64(buf) + d.a[i] ^= a + buf = buf[8:] + } + } else { + ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a)) + subtle.XORBytes(ab[:], ab[:], buf) + } +} + +// copyOut copies uint64s to a byte buffer. +func copyOut(d *state, b []byte) { + if cpu.IsBigEndian { + for i := 0; len(b) >= 8; i++ { + binary.LittleEndian.PutUint64(b, d.a[i]) + b = b[8:] + } + } else { + ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a)) + copy(b, ab[:]) + } +} diff --git a/vendor/golang.org/x/crypto/sha3/xor_generic.go b/vendor/golang.org/x/crypto/sha3/xor_generic.go deleted file mode 100644 index 8d94771127..0000000000 --- a/vendor/golang.org/x/crypto/sha3/xor_generic.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sha3 - -import "encoding/binary" - -// xorInGeneric xors the bytes in buf into the state; it -// makes no non-portable assumptions about memory layout -// or alignment. -func xorInGeneric(d *state, buf []byte) { - n := len(buf) / 8 - - for i := 0; i < n; i++ { - a := binary.LittleEndian.Uint64(buf) - d.a[i] ^= a - buf = buf[8:] - } -} - -// copyOutGeneric copies uint64s to a byte buffer. -func copyOutGeneric(d *state, b []byte) { - for i := 0; len(b) >= 8; i++ { - binary.LittleEndian.PutUint64(b, d.a[i]) - b = b[8:] - } -} diff --git a/vendor/golang.org/x/crypto/sha3/xor_unaligned.go b/vendor/golang.org/x/crypto/sha3/xor_unaligned.go deleted file mode 100644 index 870e2d16e0..0000000000 --- a/vendor/golang.org/x/crypto/sha3/xor_unaligned.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build (amd64 || 386 || ppc64le) && !purego - -package sha3 - -import "unsafe" - -// A storageBuf is an aligned array of maxRate bytes. -type storageBuf [maxRate / 8]uint64 - -func (b *storageBuf) asBytes() *[maxRate]byte { - return (*[maxRate]byte)(unsafe.Pointer(b)) -} - -// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a -// XOR buf. -func xorInUnaligned(d *state, buf []byte) { - n := len(buf) - bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8] - if n >= 72 { - d.a[0] ^= bw[0] - d.a[1] ^= bw[1] - d.a[2] ^= bw[2] - d.a[3] ^= bw[3] - d.a[4] ^= bw[4] - d.a[5] ^= bw[5] - d.a[6] ^= bw[6] - d.a[7] ^= bw[7] - d.a[8] ^= bw[8] - } - if n >= 104 { - d.a[9] ^= bw[9] - d.a[10] ^= bw[10] - d.a[11] ^= bw[11] - d.a[12] ^= bw[12] - } - if n >= 136 { - d.a[13] ^= bw[13] - d.a[14] ^= bw[14] - d.a[15] ^= bw[15] - d.a[16] ^= bw[16] - } - if n >= 144 { - d.a[17] ^= bw[17] - } - if n >= 168 { - d.a[18] ^= bw[18] - d.a[19] ^= bw[19] - d.a[20] ^= bw[20] - } -} - -func copyOutUnaligned(d *state, buf []byte) { - ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0])) - copy(buf, ab[:]) -} - -var ( - xorIn = xorInUnaligned - copyOut = copyOutUnaligned -) - -const xorImplementationUnaligned = "unaligned" diff --git a/vendor/golang.org/x/crypto/ssh/agent/client.go b/vendor/golang.org/x/crypto/ssh/agent/client.go index fecba8eb38..106708d289 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/client.go +++ b/vendor/golang.org/x/crypto/ssh/agent/client.go @@ -10,7 +10,7 @@ // References: // // [PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00 -package agent // import "golang.org/x/crypto/ssh/agent" +package agent import ( "bytes" diff --git a/vendor/golang.org/x/crypto/ssh/agent/keyring.go b/vendor/golang.org/x/crypto/ssh/agent/keyring.go index 21bfa870fa..c1b4361087 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/keyring.go +++ b/vendor/golang.org/x/crypto/ssh/agent/keyring.go @@ -175,6 +175,15 @@ func (r *keyring) Add(key AddedKey) error { p.expire = &t } + // If we already have a Signer with the same public key, replace it with the + // new one. + for idx, k := range r.keys { + if bytes.Equal(k.signer.PublicKey().Marshal(), p.signer.PublicKey().Marshal()) { + r.keys[idx] = p + return nil + } + } + r.keys = append(r.keys, p) return nil diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go index 9486c59862..b93961010d 100644 --- a/vendor/golang.org/x/crypto/ssh/client_auth.go +++ b/vendor/golang.org/x/crypto/ssh/client_auth.go @@ -71,6 +71,10 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { for auth := AuthMethod(new(noneAuth)); auth != nil; { ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions) if err != nil { + // On disconnect, return error immediately + if _, ok := err.(*disconnectMsg); ok { + return err + } // We return the error later if there is no other method left to // try. ok = authFailure diff --git a/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go index edbe63340d..f5d352fe3a 100644 --- a/vendor/golang.org/x/crypto/ssh/doc.go +++ b/vendor/golang.org/x/crypto/ssh/doc.go @@ -20,4 +20,4 @@ References: This package does not fall under the stability promise of the Go language itself, so its API may be changed when pressing needs arise. */ -package ssh // import "golang.org/x/crypto/ssh" +package ssh diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index df4ebdada5..98e6706d5d 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -488,7 +488,49 @@ func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error { h := hash.New() h.Write(data) digest := h.Sum(nil) - return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), hash, digest, sig.Blob) + + // Signatures in PKCS1v15 must match the key's modulus in + // length. However with SSH, some signers provide RSA + // signatures which are missing the MSB 0's of the bignum + // represented. With ssh-rsa signatures, this is encouraged by + // the spec (even though e.g. OpenSSH will give the full + // length unconditionally). With rsa-sha2-* signatures, the + // verifier is allowed to support these, even though they are + // out of spec. See RFC 4253 Section 6.6 for ssh-rsa and RFC + // 8332 Section 3 for rsa-sha2-* details. + // + // In practice: + // * OpenSSH always allows "short" signatures: + // https://github.com/openssh/openssh-portable/blob/V_9_8_P1/ssh-rsa.c#L526 + // but always generates padded signatures: + // https://github.com/openssh/openssh-portable/blob/V_9_8_P1/ssh-rsa.c#L439 + // + // * PuTTY versions 0.81 and earlier will generate short + // signatures for all RSA signature variants. Note that + // PuTTY is embedded in other software, such as WinSCP and + // FileZilla. At the time of writing, a patch has been + // applied to PuTTY to generate padded signatures for + // rsa-sha2-*, but not yet released: + // https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=a5bcf3d384e1bf15a51a6923c3724cbbee022d8e + // + // * SSH.NET versions 2024.0.0 and earlier will generate short + // signatures for all RSA signature variants, fixed in 2024.1.0: + // https://github.com/sshnet/SSH.NET/releases/tag/2024.1.0 + // + // As a result, we pad these up to the key size by inserting + // leading 0's. + // + // Note that support for short signatures with rsa-sha2-* may + // be removed in the future due to such signatures not being + // allowed by the spec. + blob := sig.Blob + keySize := (*rsa.PublicKey)(r).Size() + if len(blob) < keySize { + padded := make([]byte, keySize) + copy(padded[keySize-len(blob):], blob) + blob = padded + } + return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), hash, digest, blob) } func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey { @@ -904,6 +946,10 @@ func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error { return errors.New("ssh: signature did not verify") } +func (k *skECDSAPublicKey) CryptoPublicKey() crypto.PublicKey { + return &k.PublicKey +} + type skEd25519PublicKey struct { // application is a URL-like string, typically "ssh:" for SSH. // see openssh/PROTOCOL.u2f for details. @@ -1000,6 +1046,10 @@ func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error { return nil } +func (k *skEd25519PublicKey) CryptoPublicKey() crypto.PublicKey { + return k.PublicKey +} + // NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey, // *ecdsa.PrivateKey or any other crypto.Signer and returns a // corresponding Signer instance. ECDSA keys must use P-256, P-384 or diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index e2ae4f891b..3ca9e89e22 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -462,6 +462,24 @@ func (p *PartialSuccessError) Error() string { // It is returned in ServerAuthError.Errors from NewServerConn. var ErrNoAuth = errors.New("ssh: no auth passed yet") +// BannerError is an error that can be returned by authentication handlers in +// ServerConfig to send a banner message to the client. +type BannerError struct { + Err error + Message string +} + +func (b *BannerError) Unwrap() error { + return b.Err +} + +func (b *BannerError) Error() string { + if b.Err == nil { + return b.Message + } + return b.Err.Error() +} + func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) { sessionID := s.transport.getSessionID() var cache pubKeyCache @@ -734,6 +752,18 @@ userAuthLoop: config.AuthLogCallback(s, userAuthReq.Method, authErr) } + var bannerErr *BannerError + if errors.As(authErr, &bannerErr) { + if bannerErr.Message != "" { + bannerMsg := &userAuthBannerMsg{ + Message: bannerErr.Message, + } + if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil { + return nil, err + } + } + } + if authErr == nil { break userAuthLoop } diff --git a/vendor/golang.org/x/mod/LICENSE b/vendor/golang.org/x/mod/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/mod/LICENSE +++ b/vendor/golang.org/x/mod/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/net/LICENSE b/vendor/golang.org/x/net/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/net/LICENSE +++ b/vendor/golang.org/x/net/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index 6f2df28187..003e649f30 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -17,6 +17,7 @@ package http2 // import "golang.org/x/net/http2" import ( "bufio" + "context" "crypto/tls" "fmt" "io" @@ -26,6 +27,7 @@ import ( "strconv" "strings" "sync" + "time" "golang.org/x/net/http/httpguts" ) @@ -210,12 +212,6 @@ type stringWriter interface { WriteString(s string) (n int, err error) } -// A gate lets two goroutines coordinate their activities. -type gate chan struct{} - -func (g gate) Done() { g <- struct{}{} } -func (g gate) Wait() { <-g } - // A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed). type closeWaiter chan struct{} @@ -383,3 +379,14 @@ func validPseudoPath(v string) bool { // makes that struct also non-comparable, and generally doesn't add // any size (as long as it's first). type incomparable [0]func() + +// synctestGroupInterface is the methods of synctestGroup used by Server and Transport. +// It's defined as an interface here to let us keep synctestGroup entirely test-only +// and not a part of non-test builds. +type synctestGroupInterface interface { + Join() + Now() time.Time + NewTimer(d time.Duration) timer + AfterFunc(d time.Duration, f func()) timer + ContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) +} diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index c5d0810813..6c349f3ec6 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -154,6 +154,39 @@ type Server struct { // so that we don't embed a Mutex in this struct, which will make the // struct non-copyable, which might break some callers. state *serverInternalState + + // Synchronization group used for testing. + // Outside of tests, this is nil. + group synctestGroupInterface +} + +func (s *Server) markNewGoroutine() { + if s.group != nil { + s.group.Join() + } +} + +func (s *Server) now() time.Time { + if s.group != nil { + return s.group.Now() + } + return time.Now() +} + +// newTimer creates a new time.Timer, or a synthetic timer in tests. +func (s *Server) newTimer(d time.Duration) timer { + if s.group != nil { + return s.group.NewTimer(d) + } + return timeTimer{time.NewTimer(d)} +} + +// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. +func (s *Server) afterFunc(d time.Duration, f func()) timer { + if s.group != nil { + return s.group.AfterFunc(d, f) + } + return timeTimer{time.AfterFunc(d, f)} } func (s *Server) initialConnRecvWindowSize() int32 { @@ -400,6 +433,10 @@ func (o *ServeConnOpts) handler() http.Handler { // // The opts parameter is optional. If nil, default values are used. func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { + s.serveConn(c, opts, nil) +} + +func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverConn)) { baseCtx, cancel := serverConnBaseContext(c, opts) defer cancel() @@ -426,6 +463,9 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { pushEnabled: true, sawClientPreface: opts.SawClientPreface, } + if newf != nil { + newf(sc) + } s.state.registerConn(sc) defer s.state.unregisterConn(sc) @@ -599,8 +639,8 @@ type serverConn struct { inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop needToSendGoAway bool // we need to schedule a GOAWAY frame write goAwayCode ErrCode - shutdownTimer *time.Timer // nil until used - idleTimer *time.Timer // nil if unused + shutdownTimer timer // nil until used + idleTimer timer // nil if unused // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer @@ -649,12 +689,12 @@ type stream struct { flow outflow // limits writing from Handler to client inflow inflow // what the client is allowed to POST/etc to us state streamState - resetQueued bool // RST_STREAM queued for write; set by sc.resetStream - gotTrailerHeader bool // HEADER frame for trailers was seen - wroteHeaders bool // whether we wrote headers (not status 100) - readDeadline *time.Timer // nil if unused - writeDeadline *time.Timer // nil if unused - closeErr error // set before cw is closed + resetQueued bool // RST_STREAM queued for write; set by sc.resetStream + gotTrailerHeader bool // HEADER frame for trailers was seen + wroteHeaders bool // whether we wrote headers (not status 100) + readDeadline timer // nil if unused + writeDeadline timer // nil if unused + closeErr error // set before cw is closed trailer http.Header // accumulated trailers reqTrailer http.Header // handler's Request.Trailer @@ -811,8 +851,9 @@ type readFrameResult struct { // consumer is done with the frame. // It's run on its own goroutine. func (sc *serverConn) readFrames() { - gate := make(gate) - gateDone := gate.Done + sc.srv.markNewGoroutine() + gate := make(chan struct{}) + gateDone := func() { gate <- struct{}{} } for { f, err := sc.framer.ReadFrame() select { @@ -843,6 +884,7 @@ type frameWriteResult struct { // At most one goroutine can be running writeFrameAsync at a time per // serverConn. func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) { + sc.srv.markNewGoroutine() var err error if wd == nil { err = wr.write.writeFrame(sc) @@ -922,13 +964,13 @@ func (sc *serverConn) serve() { sc.setConnState(http.StateIdle) if sc.srv.IdleTimeout > 0 { - sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) + sc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() } go sc.readFrames() // closed by defer sc.conn.Close above - settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer) + settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer) defer settingsTimer.Stop() loopNum := 0 @@ -1057,10 +1099,10 @@ func (sc *serverConn) readPreface() error { errc <- nil } }() - timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server? + timer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server? defer timer.Stop() select { - case <-timer.C: + case <-timer.C(): return errPrefaceTimeout case err := <-errc: if err == nil { @@ -1425,7 +1467,7 @@ func (sc *serverConn) goAway(code ErrCode) { func (sc *serverConn) shutDownIn(d time.Duration) { sc.serveG.check() - sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer) + sc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer) } func (sc *serverConn) resetStream(se StreamError) { @@ -1639,7 +1681,7 @@ func (sc *serverConn) closeStream(st *stream, err error) { delete(sc.streams, st.id) if len(sc.streams) == 0 { sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout > 0 { + if sc.srv.IdleTimeout > 0 && sc.idleTimer != nil { sc.idleTimer.Reset(sc.srv.IdleTimeout) } if h1ServerKeepAlivesDisabled(sc.hs) { @@ -1661,6 +1703,7 @@ func (sc *serverConn) closeStream(st *stream, err error) { } } st.closeErr = err + st.cancelCtx() st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc sc.writeSched.CloseStream(st.id) } @@ -2021,7 +2064,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // (in Go 1.8), though. That's a more sane option anyway. if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) - st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) + st.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout) } return sc.scheduleHandler(id, rw, req, handler) @@ -2119,7 +2162,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream st.flow.add(sc.initialStreamSendWindowSize) st.inflow.init(sc.srv.initialStreamRecvWindowSize()) if sc.hs.WriteTimeout > 0 { - st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) + st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } sc.streams[id] = st @@ -2343,6 +2386,7 @@ func (sc *serverConn) handlerDone() { // Run on its own goroutine. func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { + sc.srv.markNewGoroutine() defer sc.sendServeMsg(handlerDoneMsg) didPanic := true defer func() { @@ -2639,7 +2683,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { var date string if _, ok := rws.snapHeader["Date"]; !ok { // TODO(bradfitz): be faster here, like net/http? measure. - date = time.Now().UTC().Format(http.TimeFormat) + date = rws.conn.srv.now().UTC().Format(http.TimeFormat) } for _, v := range rws.snapHeader["Trailer"] { @@ -2761,7 +2805,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() { func (w *responseWriter) SetReadDeadline(deadline time.Time) error { st := w.rws.stream - if !deadline.IsZero() && deadline.Before(time.Now()) { + if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onReadTimeout() @@ -2777,9 +2821,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { if deadline.IsZero() { st.readDeadline = nil } else if st.readDeadline == nil { - st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout) + st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout) } else { - st.readDeadline.Reset(deadline.Sub(time.Now())) + st.readDeadline.Reset(deadline.Sub(sc.srv.now())) } }) return nil @@ -2787,7 +2831,7 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { st := w.rws.stream - if !deadline.IsZero() && deadline.Before(time.Now()) { + if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onWriteTimeout() @@ -2803,9 +2847,9 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { if deadline.IsZero() { st.writeDeadline = nil } else if st.writeDeadline == nil { - st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout) + st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout) } else { - st.writeDeadline.Reset(deadline.Sub(time.Now())) + st.writeDeadline.Reset(deadline.Sub(sc.srv.now())) } }) return nil diff --git a/vendor/golang.org/x/net/http2/testsync.go b/vendor/golang.org/x/net/http2/testsync.go deleted file mode 100644 index 61075bd16d..0000000000 --- a/vendor/golang.org/x/net/http2/testsync.go +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package http2 - -import ( - "context" - "sync" - "time" -) - -// testSyncHooks coordinates goroutines in tests. -// -// For example, a call to ClientConn.RoundTrip involves several goroutines, including: -// - the goroutine running RoundTrip; -// - the clientStream.doRequest goroutine, which writes the request; and -// - the clientStream.readLoop goroutine, which reads the response. -// -// Using testSyncHooks, a test can start a RoundTrip and identify when all these goroutines -// are blocked waiting for some condition such as reading the Request.Body or waiting for -// flow control to become available. -// -// The testSyncHooks also manage timers and synthetic time in tests. -// This permits us to, for example, start a request and cause it to time out waiting for -// response headers without resorting to time.Sleep calls. -type testSyncHooks struct { - // active/inactive act as a mutex and condition variable. - // - // - neither chan contains a value: testSyncHooks is locked. - // - active contains a value: unlocked, and at least one goroutine is not blocked - // - inactive contains a value: unlocked, and all goroutines are blocked - active chan struct{} - inactive chan struct{} - - // goroutine counts - total int // total goroutines - condwait map[*sync.Cond]int // blocked in sync.Cond.Wait - blocked []*testBlockedGoroutine // otherwise blocked - - // fake time - now time.Time - timers []*fakeTimer - - // Transport testing: Report various events. - newclientconn func(*ClientConn) - newstream func(*clientStream) -} - -// testBlockedGoroutine is a blocked goroutine. -type testBlockedGoroutine struct { - f func() bool // blocked until f returns true - ch chan struct{} // closed when unblocked -} - -func newTestSyncHooks() *testSyncHooks { - h := &testSyncHooks{ - active: make(chan struct{}, 1), - inactive: make(chan struct{}, 1), - condwait: map[*sync.Cond]int{}, - } - h.inactive <- struct{}{} - h.now = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) - return h -} - -// lock acquires the testSyncHooks mutex. -func (h *testSyncHooks) lock() { - select { - case <-h.active: - case <-h.inactive: - } -} - -// waitInactive waits for all goroutines to become inactive. -func (h *testSyncHooks) waitInactive() { - for { - <-h.inactive - if !h.unlock() { - break - } - } -} - -// unlock releases the testSyncHooks mutex. -// It reports whether any goroutines are active. -func (h *testSyncHooks) unlock() (active bool) { - // Look for a blocked goroutine which can be unblocked. - blocked := h.blocked[:0] - unblocked := false - for _, b := range h.blocked { - if !unblocked && b.f() { - unblocked = true - close(b.ch) - } else { - blocked = append(blocked, b) - } - } - h.blocked = blocked - - // Count goroutines blocked on condition variables. - condwait := 0 - for _, count := range h.condwait { - condwait += count - } - - if h.total > condwait+len(blocked) { - h.active <- struct{}{} - return true - } else { - h.inactive <- struct{}{} - return false - } -} - -// goRun starts a new goroutine. -func (h *testSyncHooks) goRun(f func()) { - h.lock() - h.total++ - h.unlock() - go func() { - defer func() { - h.lock() - h.total-- - h.unlock() - }() - f() - }() -} - -// blockUntil indicates that a goroutine is blocked waiting for some condition to become true. -// It waits until f returns true before proceeding. -// -// Example usage: -// -// h.blockUntil(func() bool { -// // Is the context done yet? -// select { -// case <-ctx.Done(): -// default: -// return false -// } -// return true -// }) -// // Wait for the context to become done. -// <-ctx.Done() -// -// The function f passed to blockUntil must be non-blocking and idempotent. -func (h *testSyncHooks) blockUntil(f func() bool) { - if f() { - return - } - ch := make(chan struct{}) - h.lock() - h.blocked = append(h.blocked, &testBlockedGoroutine{ - f: f, - ch: ch, - }) - h.unlock() - <-ch -} - -// broadcast is sync.Cond.Broadcast. -func (h *testSyncHooks) condBroadcast(cond *sync.Cond) { - h.lock() - delete(h.condwait, cond) - h.unlock() - cond.Broadcast() -} - -// broadcast is sync.Cond.Wait. -func (h *testSyncHooks) condWait(cond *sync.Cond) { - h.lock() - h.condwait[cond]++ - h.unlock() -} - -// newTimer creates a new fake timer. -func (h *testSyncHooks) newTimer(d time.Duration) timer { - h.lock() - defer h.unlock() - t := &fakeTimer{ - hooks: h, - when: h.now.Add(d), - c: make(chan time.Time), - } - h.timers = append(h.timers, t) - return t -} - -// afterFunc creates a new fake AfterFunc timer. -func (h *testSyncHooks) afterFunc(d time.Duration, f func()) timer { - h.lock() - defer h.unlock() - t := &fakeTimer{ - hooks: h, - when: h.now.Add(d), - f: f, - } - h.timers = append(h.timers, t) - return t -} - -func (h *testSyncHooks) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { - ctx, cancel := context.WithCancel(ctx) - t := h.afterFunc(d, cancel) - return ctx, func() { - t.Stop() - cancel() - } -} - -func (h *testSyncHooks) timeUntilEvent() time.Duration { - h.lock() - defer h.unlock() - var next time.Time - for _, t := range h.timers { - if next.IsZero() || t.when.Before(next) { - next = t.when - } - } - if d := next.Sub(h.now); d > 0 { - return d - } - return 0 -} - -// advance advances time and causes synthetic timers to fire. -func (h *testSyncHooks) advance(d time.Duration) { - h.lock() - defer h.unlock() - h.now = h.now.Add(d) - timers := h.timers[:0] - for _, t := range h.timers { - t := t // remove after go.mod depends on go1.22 - t.mu.Lock() - switch { - case t.when.After(h.now): - timers = append(timers, t) - case t.when.IsZero(): - // stopped timer - default: - t.when = time.Time{} - if t.c != nil { - close(t.c) - } - if t.f != nil { - h.total++ - go func() { - defer func() { - h.lock() - h.total-- - h.unlock() - }() - t.f() - }() - } - } - t.mu.Unlock() - } - h.timers = timers -} - -// A timer wraps a time.Timer, or a synthetic equivalent in tests. -// Unlike time.Timer, timer is single-use: The timer channel is closed when the timer expires. -type timer interface { - C() <-chan time.Time - Stop() bool - Reset(d time.Duration) bool -} - -// timeTimer implements timer using real time. -type timeTimer struct { - t *time.Timer - c chan time.Time -} - -// newTimeTimer creates a new timer using real time. -func newTimeTimer(d time.Duration) timer { - ch := make(chan time.Time) - t := time.AfterFunc(d, func() { - close(ch) - }) - return &timeTimer{t, ch} -} - -// newTimeAfterFunc creates an AfterFunc timer using real time. -func newTimeAfterFunc(d time.Duration, f func()) timer { - return &timeTimer{ - t: time.AfterFunc(d, f), - } -} - -func (t timeTimer) C() <-chan time.Time { return t.c } -func (t timeTimer) Stop() bool { return t.t.Stop() } -func (t timeTimer) Reset(d time.Duration) bool { return t.t.Reset(d) } - -// fakeTimer implements timer using fake time. -type fakeTimer struct { - hooks *testSyncHooks - - mu sync.Mutex - when time.Time // when the timer will fire - c chan time.Time // closed when the timer fires; mutually exclusive with f - f func() // called when the timer fires; mutually exclusive with c -} - -func (t *fakeTimer) C() <-chan time.Time { return t.c } - -func (t *fakeTimer) Stop() bool { - t.mu.Lock() - defer t.mu.Unlock() - stopped := t.when.IsZero() - t.when = time.Time{} - return stopped -} - -func (t *fakeTimer) Reset(d time.Duration) bool { - if t.c != nil || t.f == nil { - panic("fakeTimer only supports Reset on AfterFunc timers") - } - t.mu.Lock() - defer t.mu.Unlock() - t.hooks.lock() - defer t.hooks.unlock() - active := !t.when.IsZero() - t.when = t.hooks.now.Add(d) - if !active { - t.hooks.timers = append(t.hooks.timers, t) - } - return active -} diff --git a/vendor/golang.org/x/net/http2/timer.go b/vendor/golang.org/x/net/http2/timer.go new file mode 100644 index 0000000000..0b1c17b812 --- /dev/null +++ b/vendor/golang.org/x/net/http2/timer.go @@ -0,0 +1,20 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package http2 + +import "time" + +// A timer is a time.Timer, as an interface which can be replaced in tests. +type timer = interface { + C() <-chan time.Time + Reset(d time.Duration) bool + Stop() bool +} + +// timeTimer adapts a time.Timer to the timer interface. +type timeTimer struct { + *time.Timer +} + +func (t timeTimer) C() <-chan time.Time { return t.Timer.C } diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 2fa49490c9..61f511f97a 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -185,7 +185,45 @@ type Transport struct { connPoolOnce sync.Once connPoolOrDef ClientConnPool // non-nil version of ConnPool - syncHooks *testSyncHooks + *transportTestHooks +} + +// Hook points used for testing. +// Outside of tests, t.transportTestHooks is nil and these all have minimal implementations. +// Inside tests, see the testSyncHooks function docs. + +type transportTestHooks struct { + newclientconn func(*ClientConn) + group synctestGroupInterface +} + +func (t *Transport) markNewGoroutine() { + if t != nil && t.transportTestHooks != nil { + t.transportTestHooks.group.Join() + } +} + +// newTimer creates a new time.Timer, or a synthetic timer in tests. +func (t *Transport) newTimer(d time.Duration) timer { + if t.transportTestHooks != nil { + return t.transportTestHooks.group.NewTimer(d) + } + return timeTimer{time.NewTimer(d)} +} + +// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. +func (t *Transport) afterFunc(d time.Duration, f func()) timer { + if t.transportTestHooks != nil { + return t.transportTestHooks.group.AfterFunc(d, f) + } + return timeTimer{time.AfterFunc(d, f)} +} + +func (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + if t.transportTestHooks != nil { + return t.transportTestHooks.group.ContextWithTimeout(ctx, d) + } + return context.WithTimeout(ctx, d) } func (t *Transport) maxHeaderListSize() uint32 { @@ -352,60 +390,6 @@ type ClientConn struct { werr error // first write error that has occurred hbuf bytes.Buffer // HPACK encoder writes into this henc *hpack.Encoder - - syncHooks *testSyncHooks // can be nil -} - -// Hook points used for testing. -// Outside of tests, cc.syncHooks is nil and these all have minimal implementations. -// Inside tests, see the testSyncHooks function docs. - -// goRun starts a new goroutine. -func (cc *ClientConn) goRun(f func()) { - if cc.syncHooks != nil { - cc.syncHooks.goRun(f) - return - } - go f() -} - -// condBroadcast is cc.cond.Broadcast. -func (cc *ClientConn) condBroadcast() { - if cc.syncHooks != nil { - cc.syncHooks.condBroadcast(cc.cond) - } - cc.cond.Broadcast() -} - -// condWait is cc.cond.Wait. -func (cc *ClientConn) condWait() { - if cc.syncHooks != nil { - cc.syncHooks.condWait(cc.cond) - } - cc.cond.Wait() -} - -// newTimer creates a new time.Timer, or a synthetic timer in tests. -func (cc *ClientConn) newTimer(d time.Duration) timer { - if cc.syncHooks != nil { - return cc.syncHooks.newTimer(d) - } - return newTimeTimer(d) -} - -// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. -func (cc *ClientConn) afterFunc(d time.Duration, f func()) timer { - if cc.syncHooks != nil { - return cc.syncHooks.afterFunc(d, f) - } - return newTimeAfterFunc(d, f) -} - -func (cc *ClientConn) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { - if cc.syncHooks != nil { - return cc.syncHooks.contextWithTimeout(ctx, d) - } - return context.WithTimeout(ctx, d) } // clientStream is the state for a single HTTP/2 stream. One of these @@ -487,7 +471,7 @@ func (cs *clientStream) abortStreamLocked(err error) { // TODO(dneil): Clean up tests where cs.cc.cond is nil. if cs.cc.cond != nil { // Wake up writeRequestBody if it is waiting on flow control. - cs.cc.condBroadcast() + cs.cc.cond.Broadcast() } } @@ -497,7 +481,7 @@ func (cs *clientStream) abortRequestBodyWrite() { defer cc.mu.Unlock() if cs.reqBody != nil && cs.reqBodyClosed == nil { cs.closeReqBodyLocked() - cc.condBroadcast() + cc.cond.Broadcast() } } @@ -507,10 +491,11 @@ func (cs *clientStream) closeReqBodyLocked() { } cs.reqBodyClosed = make(chan struct{}) reqBodyClosed := cs.reqBodyClosed - cs.cc.goRun(func() { + go func() { + cs.cc.t.markNewGoroutine() cs.reqBody.Close() close(reqBodyClosed) - }) + }() } type stickyErrWriter struct { @@ -626,21 +611,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) d := time.Second * time.Duration(backoff) - var tm timer - if t.syncHooks != nil { - tm = t.syncHooks.newTimer(d) - t.syncHooks.blockUntil(func() bool { - select { - case <-tm.C(): - case <-req.Context().Done(): - default: - return false - } - return true - }) - } else { - tm = newTimeTimer(d) - } + tm := t.newTimer(d) select { case <-tm.C(): t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) @@ -725,8 +696,8 @@ func canRetryError(err error) bool { } func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) { - if t.syncHooks != nil { - return t.newClientConn(nil, singleUse, t.syncHooks) + if t.transportTestHooks != nil { + return t.newClientConn(nil, singleUse) } host, _, err := net.SplitHostPort(addr) if err != nil { @@ -736,7 +707,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b if err != nil { return nil, err } - return t.newClientConn(tconn, singleUse, nil) + return t.newClientConn(tconn, singleUse) } func (t *Transport) newTLSConfig(host string) *tls.Config { @@ -802,10 +773,10 @@ func (t *Transport) maxEncoderHeaderTableSize() uint32 { } func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { - return t.newClientConn(c, t.disableKeepAlives(), nil) + return t.newClientConn(c, t.disableKeepAlives()) } -func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHooks) (*ClientConn, error) { +func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { cc := &ClientConn{ t: t, tconn: c, @@ -820,16 +791,12 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo wantSettingsAck: true, pings: make(map[[8]byte]chan struct{}), reqHeaderMu: make(chan struct{}, 1), - syncHooks: hooks, } - if hooks != nil { - hooks.newclientconn(cc) + if t.transportTestHooks != nil { + t.markNewGoroutine() + t.transportTestHooks.newclientconn(cc) c = cc.tconn } - if d := t.idleConnTimeout(); d != 0 { - cc.idleTimeout = d - cc.idleTimer = cc.afterFunc(d, cc.onIdleTimeout) - } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) } @@ -860,10 +827,6 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize()) cc.peerMaxHeaderTableSize = initialHeaderTableSize - if t.AllowHTTP { - cc.nextStreamID = 3 - } - if cs, ok := c.(connectionStater); ok { state := cs.ConnectionState() cc.tlsState = &state @@ -893,7 +856,13 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo return nil, cc.werr } - cc.goRun(cc.readLoop) + // Start the idle timer after the connection is fully initialized. + if d := t.idleConnTimeout(); d != 0 { + cc.idleTimeout = d + cc.idleTimer = t.afterFunc(d, cc.onIdleTimeout) + } + + go cc.readLoop() return cc, nil } @@ -901,7 +870,7 @@ func (cc *ClientConn) healthCheck() { pingTimeout := cc.t.pingTimeout() // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. - ctx, cancel := cc.contextWithTimeout(context.Background(), pingTimeout) + ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout) defer cancel() cc.vlogf("http2: Transport sending health check") err := cc.Ping(ctx) @@ -1144,7 +1113,8 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { // Wait for all in-flight streams to complete or connection to close done := make(chan struct{}) cancelled := false // guarded by cc.mu - cc.goRun(func() { + go func() { + cc.t.markNewGoroutine() cc.mu.Lock() defer cc.mu.Unlock() for { @@ -1156,9 +1126,9 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { if cancelled { break } - cc.condWait() + cc.cond.Wait() } - }) + }() shutdownEnterWaitStateHook() select { case <-done: @@ -1168,7 +1138,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { cc.mu.Lock() // Free the goroutine above cancelled = true - cc.condBroadcast() + cc.cond.Broadcast() cc.mu.Unlock() return ctx.Err() } @@ -1206,7 +1176,7 @@ func (cc *ClientConn) closeForError(err error) { for _, cs := range cc.streams { cs.abortStreamLocked(err) } - cc.condBroadcast() + cc.cond.Broadcast() cc.mu.Unlock() cc.closeConn() } @@ -1321,23 +1291,30 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) respHeaderRecv: make(chan struct{}), donec: make(chan struct{}), } - cc.goRun(func() { - cs.doRequest(req) - }) + + // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? + if !cc.t.disableCompression() && + req.Header.Get("Accept-Encoding") == "" && + req.Header.Get("Range") == "" && + !cs.isHead { + // Request gzip only, not deflate. Deflate is ambiguous and + // not as universally supported anyway. + // See: https://zlib.net/zlib_faq.html#faq39 + // + // Note that we don't request this for HEAD requests, + // due to a bug in nginx: + // http://trac.nginx.org/nginx/ticket/358 + // https://golang.org/issue/5522 + // + // We don't request gzip if the request is for a range, since + // auto-decoding a portion of a gzipped document will just fail + // anyway. See https://golang.org/issue/8923 + cs.requestedGzip = true + } + + go cs.doRequest(req, streamf) waitDone := func() error { - if cc.syncHooks != nil { - cc.syncHooks.blockUntil(func() bool { - select { - case <-cs.donec: - case <-ctx.Done(): - case <-cs.reqCancel: - default: - return false - } - return true - }) - } select { case <-cs.donec: return nil @@ -1398,24 +1375,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) return err } - if streamf != nil { - streamf(cs) - } - for { - if cc.syncHooks != nil { - cc.syncHooks.blockUntil(func() bool { - select { - case <-cs.respHeaderRecv: - case <-cs.abort: - case <-ctx.Done(): - case <-cs.reqCancel: - default: - return false - } - return true - }) - } select { case <-cs.respHeaderRecv: return handleResponseHeaders() @@ -1445,8 +1405,9 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) // doRequest runs for the duration of the request lifetime. // // It sends the request and performs post-request cleanup (closing Request.Body, etc.). -func (cs *clientStream) doRequest(req *http.Request) { - err := cs.writeRequest(req) +func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) { + cs.cc.t.markNewGoroutine() + err := cs.writeRequest(req, streamf) cs.cleanupWriteRequest(err) } @@ -1457,7 +1418,7 @@ func (cs *clientStream) doRequest(req *http.Request) { // // It returns non-nil if the request ends otherwise. // If the returned error is StreamError, the error Code may be used in resetting the stream. -func (cs *clientStream) writeRequest(req *http.Request) (err error) { +func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStream)) (err error) { cc := cs.cc ctx := cs.ctx @@ -1471,21 +1432,6 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { if cc.reqHeaderMu == nil { panic("RoundTrip on uninitialized ClientConn") // for tests } - var newStreamHook func(*clientStream) - if cc.syncHooks != nil { - newStreamHook = cc.syncHooks.newstream - cc.syncHooks.blockUntil(func() bool { - select { - case cc.reqHeaderMu <- struct{}{}: - <-cc.reqHeaderMu - case <-cs.reqCancel: - case <-ctx.Done(): - default: - return false - } - return true - }) - } select { case cc.reqHeaderMu <- struct{}{}: case <-cs.reqCancel: @@ -1510,28 +1456,8 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { } cc.mu.Unlock() - if newStreamHook != nil { - newStreamHook(cs) - } - - // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? - if !cc.t.disableCompression() && - req.Header.Get("Accept-Encoding") == "" && - req.Header.Get("Range") == "" && - !cs.isHead { - // Request gzip only, not deflate. Deflate is ambiguous and - // not as universally supported anyway. - // See: https://zlib.net/zlib_faq.html#faq39 - // - // Note that we don't request this for HEAD requests, - // due to a bug in nginx: - // http://trac.nginx.org/nginx/ticket/358 - // https://golang.org/issue/5522 - // - // We don't request gzip if the request is for a range, since - // auto-decoding a portion of a gzipped document will just fail - // anyway. See https://golang.org/issue/8923 - cs.requestedGzip = true + if streamf != nil { + streamf(cs) } continueTimeout := cc.t.expectContinueTimeout() @@ -1594,7 +1520,7 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { var respHeaderTimer <-chan time.Time var respHeaderRecv chan struct{} if d := cc.responseHeaderTimeout(); d != 0 { - timer := cc.newTimer(d) + timer := cc.t.newTimer(d) defer timer.Stop() respHeaderTimer = timer.C() respHeaderRecv = cs.respHeaderRecv @@ -1603,21 +1529,6 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { // or until the request is aborted (via context, error, or otherwise), // whichever comes first. for { - if cc.syncHooks != nil { - cc.syncHooks.blockUntil(func() bool { - select { - case <-cs.peerClosed: - case <-respHeaderTimer: - case <-respHeaderRecv: - case <-cs.abort: - case <-ctx.Done(): - case <-cs.reqCancel: - default: - return false - } - return true - }) - } select { case <-cs.peerClosed: return nil @@ -1766,7 +1677,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { return nil } cc.pendingRequests++ - cc.condWait() + cc.cond.Wait() cc.pendingRequests-- select { case <-cs.abort: @@ -2028,7 +1939,7 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) cs.flow.take(take) return take, nil } - cc.condWait() + cc.cond.Wait() } } @@ -2311,7 +2222,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) { } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. - cc.condBroadcast() + cc.cond.Broadcast() closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 { @@ -2333,6 +2244,7 @@ type clientConnReadLoop struct { // readLoop runs in its own goroutine and reads and dispatches frames. func (cc *ClientConn) readLoop() { + cc.t.markNewGoroutine() rl := &clientConnReadLoop{cc: cc} defer rl.cleanup() cc.readerErr = rl.run() @@ -2399,7 +2311,7 @@ func (rl *clientConnReadLoop) cleanup() { cs.abortStreamLocked(err) } } - cc.condBroadcast() + cc.cond.Broadcast() cc.mu.Unlock() } @@ -2436,7 +2348,7 @@ func (rl *clientConnReadLoop) run() error { readIdleTimeout := cc.t.ReadIdleTimeout var t timer if readIdleTimeout != 0 { - t = cc.afterFunc(readIdleTimeout, cc.healthCheck) + t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck) } for { f, err := cc.fr.ReadFrame() @@ -3034,7 +2946,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { for _, cs := range cc.streams { cs.flow.add(delta) } - cc.condBroadcast() + cc.cond.Broadcast() cc.initialWindowSize = s.Val case SettingHeaderTableSize: @@ -3089,7 +3001,7 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { return ConnectionError(ErrCodeFlowControl) } - cc.condBroadcast() + cc.cond.Broadcast() return nil } @@ -3133,7 +3045,8 @@ func (cc *ClientConn) Ping(ctx context.Context) error { } var pingError error errc := make(chan struct{}) - cc.goRun(func() { + go func() { + cc.t.markNewGoroutine() cc.wmu.Lock() defer cc.wmu.Unlock() if pingError = cc.fr.WritePing(false, p); pingError != nil { @@ -3144,20 +3057,7 @@ func (cc *ClientConn) Ping(ctx context.Context) error { close(errc) return } - }) - if cc.syncHooks != nil { - cc.syncHooks.blockUntil(func() bool { - select { - case <-c: - case <-errc: - case <-ctx.Done(): - case <-cc.readerDone: - default: - return false - } - return true - }) - } + }() select { case <-c: return nil diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go index 0a242c669e..f6783339d1 100644 --- a/vendor/golang.org/x/net/http2/writesched_priority.go +++ b/vendor/golang.org/x/net/http2/writesched_priority.go @@ -443,8 +443,8 @@ func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, max } func (ws *priorityWriteScheduler) removeNode(n *priorityNode) { - for k := n.kids; k != nil; k = k.next { - k.setParent(n.parent) + for n.kids != nil { + n.kids.setParent(n.parent) } n.setParent(nil) delete(ws.nodes, n.id) diff --git a/vendor/golang.org/x/net/proxy/per_host.go b/vendor/golang.org/x/net/proxy/per_host.go index 573fe79e86..d7d4b8b6e3 100644 --- a/vendor/golang.org/x/net/proxy/per_host.go +++ b/vendor/golang.org/x/net/proxy/per_host.go @@ -137,9 +137,7 @@ func (p *PerHost) AddNetwork(net *net.IPNet) { // AddZone specifies a DNS suffix that will use the bypass proxy. A zone of // "example.com" matches "example.com" and all of its subdomains. func (p *PerHost) AddZone(zone string) { - if strings.HasSuffix(zone, ".") { - zone = zone[:len(zone)-1] - } + zone = strings.TrimSuffix(zone, ".") if !strings.HasPrefix(zone, ".") { zone = "." + zone } @@ -148,8 +146,6 @@ func (p *PerHost) AddZone(zone string) { // AddHost specifies a host name that will use the bypass proxy. func (p *PerHost) AddHost(host string) { - if strings.HasSuffix(host, ".") { - host = host[:len(host)-1] - } + host = strings.TrimSuffix(host, ".") p.bypassHosts = append(p.bypassHosts, host) } diff --git a/vendor/golang.org/x/sync/LICENSE b/vendor/golang.org/x/sync/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/sync/LICENSE +++ b/vendor/golang.org/x/sync/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index b18efb743f..948a3ee63d 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -4,6 +4,9 @@ // Package errgroup provides synchronization, error propagation, and Context // cancelation for groups of goroutines working on subtasks of a common task. +// +// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks +// returning errors. package errgroup import ( diff --git a/vendor/golang.org/x/sync/errgroup/go120.go b/vendor/golang.org/x/sync/errgroup/go120.go index 7d419d3760..f93c740b63 100644 --- a/vendor/golang.org/x/sync/errgroup/go120.go +++ b/vendor/golang.org/x/sync/errgroup/go120.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build go1.20 -// +build go1.20 package errgroup diff --git a/vendor/golang.org/x/sync/errgroup/pre_go120.go b/vendor/golang.org/x/sync/errgroup/pre_go120.go index 1795c18ace..88ce33434e 100644 --- a/vendor/golang.org/x/sync/errgroup/pre_go120.go +++ b/vendor/golang.org/x/sync/errgroup/pre_go120.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build !go1.20 -// +build !go1.20 package errgroup diff --git a/vendor/golang.org/x/sys/LICENSE b/vendor/golang.org/x/sys/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/sys/LICENSE +++ b/vendor/golang.org/x/sys/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go index 8fa707aa4b..02609d5b21 100644 --- a/vendor/golang.org/x/sys/cpu/cpu.go +++ b/vendor/golang.org/x/sys/cpu/cpu.go @@ -105,6 +105,8 @@ var ARM64 struct { HasSVE bool // Scalable Vector Extensions HasSVE2 bool // Scalable Vector Extensions 2 HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32 + HasDIT bool // Data Independent Timing support + HasI8MM bool // Advanced SIMD Int8 matrix multiplication instructions _ CacheLinePad } @@ -199,6 +201,25 @@ var S390X struct { _ CacheLinePad } +// RISCV64 contains the supported CPU features and performance characteristics for riscv64 +// platforms. The booleans in RISCV64, with the exception of HasFastMisaligned, indicate +// the presence of RISC-V extensions. +// +// It is safe to assume that all the RV64G extensions are supported and so they are omitted from +// this structure. As riscv64 Go programs require at least RV64G, the code that populates +// this structure cannot run successfully if some of the RV64G extensions are missing. +// The struct is padded to avoid false sharing. +var RISCV64 struct { + _ CacheLinePad + HasFastMisaligned bool // Fast misaligned accesses + HasC bool // Compressed instruction-set extension + HasV bool // Vector extension compatible with RVV 1.0 + HasZba bool // Address generation instructions extension + HasZbb bool // Basic bit-manipulation extension + HasZbs bool // Single-bit instructions extension + _ CacheLinePad +} + func init() { archInit() initOptions() diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_arm64.go index 0e27a21e1f..af2aa99f9f 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.go @@ -38,6 +38,8 @@ func initOptions() { {Name: "dcpop", Feature: &ARM64.HasDCPOP}, {Name: "asimddp", Feature: &ARM64.HasASIMDDP}, {Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM}, + {Name: "dit", Feature: &ARM64.HasDIT}, + {Name: "i8mm", Feature: &ARM64.HasI8MM}, } } @@ -145,6 +147,11 @@ func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { ARM64.HasLRCPC = true } + switch extractBits(isar1, 52, 55) { + case 1: + ARM64.HasI8MM = true + } + // ID_AA64PFR0_EL1 switch extractBits(pfr0, 16, 19) { case 0: @@ -168,6 +175,11 @@ func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { parseARM64SVERegister(getzfr0()) } + + switch extractBits(pfr0, 48, 51) { + case 1: + ARM64.HasDIT = true + } } func parseARM64SVERegister(zfr0 uint64) { diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go index 3d386d0fc2..08f35ea177 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go @@ -35,8 +35,10 @@ const ( hwcap_SHA512 = 1 << 21 hwcap_SVE = 1 << 22 hwcap_ASIMDFHM = 1 << 23 + hwcap_DIT = 1 << 24 hwcap2_SVE2 = 1 << 1 + hwcap2_I8MM = 1 << 13 ) // linuxKernelCanEmulateCPUID reports whether we're running @@ -106,9 +108,12 @@ func doinit() { ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512) ARM64.HasSVE = isSet(hwCap, hwcap_SVE) ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM) + ARM64.HasDIT = isSet(hwCap, hwcap_DIT) + // HWCAP2 feature bits ARM64.HasSVE2 = isSet(hwCap2, hwcap2_SVE2) + ARM64.HasI8MM = isSet(hwCap2, hwcap2_I8MM) } func isSet(hwc uint, value uint) bool { diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go index cd63e73355..7d902b6847 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build linux && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x +//go:build linux && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x && !riscv64 package cpu diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go new file mode 100644 index 0000000000..cb4a0c5728 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go @@ -0,0 +1,137 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +import ( + "syscall" + "unsafe" +) + +// RISC-V extension discovery code for Linux. The approach here is to first try the riscv_hwprobe +// syscall falling back to HWCAP to check for the C extension if riscv_hwprobe is not available. +// +// A note on detection of the Vector extension using HWCAP. +// +// Support for the Vector extension version 1.0 was added to the Linux kernel in release 6.5. +// Support for the riscv_hwprobe syscall was added in 6.4. It follows that if the riscv_hwprobe +// syscall is not available then neither is the Vector extension (which needs kernel support). +// The riscv_hwprobe syscall should then be all we need to detect the Vector extension. +// However, some RISC-V board manufacturers ship boards with an older kernel on top of which +// they have back-ported various versions of the Vector extension patches but not the riscv_hwprobe +// patches. These kernels advertise support for the Vector extension using HWCAP. Falling +// back to HWCAP to detect the Vector extension, if riscv_hwprobe is not available, or simply not +// bothering with riscv_hwprobe at all and just using HWCAP may then seem like an attractive option. +// +// Unfortunately, simply checking the 'V' bit in AT_HWCAP will not work as this bit is used by +// RISC-V board and cloud instance providers to mean different things. The Lichee Pi 4A board +// and the Scaleway RV1 cloud instances use the 'V' bit to advertise their support for the unratified +// 0.7.1 version of the Vector Specification. The Banana Pi BPI-F3 and the CanMV-K230 board use +// it to advertise support for 1.0 of the Vector extension. Versions 0.7.1 and 1.0 of the Vector +// extension are binary incompatible. HWCAP can then not be used in isolation to populate the +// HasV field as this field indicates that the underlying CPU is compatible with RVV 1.0. +// +// There is a way at runtime to distinguish between versions 0.7.1 and 1.0 of the Vector +// specification by issuing a RVV 1.0 vsetvli instruction and checking the vill bit of the vtype +// register. This check would allow us to safely detect version 1.0 of the Vector extension +// with HWCAP, if riscv_hwprobe were not available. However, the check cannot +// be added until the assembler supports the Vector instructions. +// +// Note the riscv_hwprobe syscall does not suffer from these ambiguities by design as all of the +// extensions it advertises support for are explicitly versioned. It's also worth noting that +// the riscv_hwprobe syscall is the only way to detect multi-letter RISC-V extensions, e.g., Zba. +// These cannot be detected using HWCAP and so riscv_hwprobe must be used to detect the majority +// of RISC-V extensions. +// +// Please see https://docs.kernel.org/arch/riscv/hwprobe.html for more information. + +// golang.org/x/sys/cpu is not allowed to depend on golang.org/x/sys/unix so we must +// reproduce the constants, types and functions needed to make the riscv_hwprobe syscall +// here. + +const ( + // Copied from golang.org/x/sys/unix/ztypes_linux_riscv64.go. + riscv_HWPROBE_KEY_IMA_EXT_0 = 0x4 + riscv_HWPROBE_IMA_C = 0x2 + riscv_HWPROBE_IMA_V = 0x4 + riscv_HWPROBE_EXT_ZBA = 0x8 + riscv_HWPROBE_EXT_ZBB = 0x10 + riscv_HWPROBE_EXT_ZBS = 0x20 + riscv_HWPROBE_KEY_CPUPERF_0 = 0x5 + riscv_HWPROBE_MISALIGNED_FAST = 0x3 + riscv_HWPROBE_MISALIGNED_MASK = 0x7 +) + +const ( + // sys_RISCV_HWPROBE is copied from golang.org/x/sys/unix/zsysnum_linux_riscv64.go. + sys_RISCV_HWPROBE = 258 +) + +// riscvHWProbePairs is copied from golang.org/x/sys/unix/ztypes_linux_riscv64.go. +type riscvHWProbePairs struct { + key int64 + value uint64 +} + +const ( + // CPU features + hwcap_RISCV_ISA_C = 1 << ('C' - 'A') +) + +func doinit() { + // A slice of key/value pair structures is passed to the RISCVHWProbe syscall. The key + // field should be initialised with one of the key constants defined above, e.g., + // RISCV_HWPROBE_KEY_IMA_EXT_0. The syscall will set the value field to the appropriate value. + // If the kernel does not recognise a key it will set the key field to -1 and the value field to 0. + + pairs := []riscvHWProbePairs{ + {riscv_HWPROBE_KEY_IMA_EXT_0, 0}, + {riscv_HWPROBE_KEY_CPUPERF_0, 0}, + } + + // This call only indicates that extensions are supported if they are implemented on all cores. + if riscvHWProbe(pairs, 0) { + if pairs[0].key != -1 { + v := uint(pairs[0].value) + RISCV64.HasC = isSet(v, riscv_HWPROBE_IMA_C) + RISCV64.HasV = isSet(v, riscv_HWPROBE_IMA_V) + RISCV64.HasZba = isSet(v, riscv_HWPROBE_EXT_ZBA) + RISCV64.HasZbb = isSet(v, riscv_HWPROBE_EXT_ZBB) + RISCV64.HasZbs = isSet(v, riscv_HWPROBE_EXT_ZBS) + } + if pairs[1].key != -1 { + v := pairs[1].value & riscv_HWPROBE_MISALIGNED_MASK + RISCV64.HasFastMisaligned = v == riscv_HWPROBE_MISALIGNED_FAST + } + } + + // Let's double check with HWCAP if the C extension does not appear to be supported. + // This may happen if we're running on a kernel older than 6.4. + + if !RISCV64.HasC { + RISCV64.HasC = isSet(hwCap, hwcap_RISCV_ISA_C) + } +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} + +// riscvHWProbe is a simplified version of the generated wrapper function found in +// golang.org/x/sys/unix/zsyscall_linux_riscv64.go. We simplify it by removing the +// cpuCount and cpus parameters which we do not need. We always want to pass 0 for +// these parameters here so the kernel only reports the extensions that are present +// on all cores. +func riscvHWProbe(pairs []riscvHWProbePairs, flags uint) bool { + var _zero uintptr + var p0 unsafe.Pointer + if len(pairs) > 0 { + p0 = unsafe.Pointer(&pairs[0]) + } else { + p0 = unsafe.Pointer(&_zero) + } + + _, _, e1 := syscall.Syscall6(sys_RISCV_HWPROBE, uintptr(p0), uintptr(len(pairs)), uintptr(0), uintptr(0), uintptr(flags), 0) + return e1 == 0 +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go index 7f0c79c004..aca3199c91 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go @@ -8,4 +8,13 @@ package cpu const cacheLineSize = 64 -func initOptions() {} +func initOptions() { + options = []option{ + {Name: "fastmisaligned", Feature: &RISCV64.HasFastMisaligned}, + {Name: "c", Feature: &RISCV64.HasC}, + {Name: "v", Feature: &RISCV64.HasV}, + {Name: "zba", Feature: &RISCV64.HasZba}, + {Name: "zbb", Feature: &RISCV64.HasZbb}, + {Name: "zbs", Feature: &RISCV64.HasZbs}, + } +} diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index fdcaa974d2..e14b766a32 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -58,6 +58,7 @@ includes_Darwin=' #define _DARWIN_USE_64_BIT_INODE #define __APPLE_USE_RFC_3542 #include +#include #include #include #include @@ -263,6 +264,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -549,6 +551,8 @@ ccflags="$@" $2 !~ "NLA_TYPE_MASK" && $2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ && $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ || + $2 ~ /^SOCK_|SK_DIAG_|SKNLGRP_$/ || + $2 ~ /^(CONNECT|SAE)_/ || $2 ~ /^FIORDCHK$/ || $2 ~ /^SIOC/ || $2 ~ /^TIOC/ || diff --git a/vendor/golang.org/x/sys/unix/mremap.go b/vendor/golang.org/x/sys/unix/mremap.go index fd45fe529d..3a5e776f89 100644 --- a/vendor/golang.org/x/sys/unix/mremap.go +++ b/vendor/golang.org/x/sys/unix/mremap.go @@ -50,3 +50,8 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [ func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { return mapper.Mremap(oldData, newLength, flags) } + +func MremapPtr(oldAddr unsafe.Pointer, oldSize uintptr, newAddr unsafe.Pointer, newSize uintptr, flags int) (ret unsafe.Pointer, err error) { + xaddr, err := mapper.mremap(uintptr(oldAddr), oldSize, newSize, flags, uintptr(newAddr)) + return unsafe.Pointer(xaddr), err +} diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 59542a897d..099867deed 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -402,6 +402,18 @@ func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error { return ioctlPtr(fd, SIOCSIFMTU, unsafe.Pointer(ifreq)) } +//sys renamexNp(from string, to string, flag uint32) (err error) + +func RenamexNp(from string, to string, flag uint32) (err error) { + return renamexNp(from, to, flag) +} + +//sys renameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) + +func RenameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) { + return renameatxNp(fromfd, from, tofd, to, flag) +} + //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL func Uname(uname *Utsname) error { @@ -542,6 +554,55 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { } } +//sys pthread_chdir_np(path string) (err error) + +func PthreadChdir(path string) (err error) { + return pthread_chdir_np(path) +} + +//sys pthread_fchdir_np(fd int) (err error) + +func PthreadFchdir(fd int) (err error) { + return pthread_fchdir_np(fd) +} + +// Connectx calls connectx(2) to initiate a connection on a socket. +// +// srcIf, srcAddr, and dstAddr are filled into a [SaEndpoints] struct and passed as the endpoints argument. +// +// - srcIf is the optional source interface index. 0 means unspecified. +// - srcAddr is the optional source address. nil means unspecified. +// - dstAddr is the destination address. +// +// On success, Connectx returns the number of bytes enqueued for transmission. +func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocID, flags uint32, iov []Iovec, connid *SaeConnID) (n uintptr, err error) { + endpoints := SaEndpoints{ + Srcif: srcIf, + } + + if srcAddr != nil { + addrp, addrlen, err := srcAddr.sockaddr() + if err != nil { + return 0, err + } + endpoints.Srcaddr = (*RawSockaddr)(addrp) + endpoints.Srcaddrlen = uint32(addrlen) + } + + if dstAddr != nil { + addrp, addrlen, err := dstAddr.sockaddr() + if err != nil { + return 0, err + } + endpoints.Dstaddr = (*RawSockaddr)(addrp) + endpoints.Dstaddrlen = uint32(addrlen) + } + + err = connectx(fd, &endpoints, associd, flags, iov, &n, connid) + return +} + +//sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_hurd.go b/vendor/golang.org/x/sys/unix/syscall_hurd.go index ba46651f8e..a6a2d2fc2b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_hurd.go +++ b/vendor/golang.org/x/sys/unix/syscall_hurd.go @@ -11,6 +11,7 @@ package unix int ioctl(int, unsigned long int, uintptr_t); */ import "C" +import "unsafe" func ioctl(fd int, req uint, arg uintptr) (err error) { r0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(arg)) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 5682e2628a..3f1d3d4cb2 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -2592,3 +2592,4 @@ func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { } //sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) +//sys Mseal(b []byte, flags uint) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go index b25343c71a..b86ded549c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go @@ -293,6 +293,7 @@ func Uname(uname *Utsname) error { //sys Mkfifoat(dirfd int, path string, mode uint32) (err error) //sys Mknod(path string, mode uint32, dev int) (err error) //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) +//sys Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 77081de8c7..4e92e5aa40 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -154,6 +154,15 @@ func Munmap(b []byte) (err error) { return mapper.Munmap(b) } +func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) { + xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset) + return unsafe.Pointer(xaddr), err +} + +func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) { + return mapper.munmap(uintptr(addr), length) +} + func Read(fd int, p []byte) (n int, err error) { n, err = read(fd, p) if raceenabled { diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index e40fa85245..d73c4652e6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -237,6 +237,9 @@ const ( CLOCK_UPTIME_RAW_APPROX = 0x9 CLONE_NOFOLLOW = 0x1 CLONE_NOOWNERCOPY = 0x2 + CONNECT_DATA_AUTHENTICATED = 0x4 + CONNECT_DATA_IDEMPOTENT = 0x2 + CONNECT_RESUME_ON_READ_WRITE = 0x1 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -1169,6 +1172,11 @@ const ( PT_WRITE_D = 0x5 PT_WRITE_I = 0x4 PT_WRITE_U = 0x6 + RENAME_EXCL = 0x4 + RENAME_NOFOLLOW_ANY = 0x10 + RENAME_RESERVED1 = 0x8 + RENAME_SECLUDE = 0x1 + RENAME_SWAP = 0x2 RLIMIT_AS = 0x5 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1260,6 +1268,10 @@ const ( RTV_SSTHRESH = 0x20 RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 + SAE_ASSOCID_ALL = 0xffffffff + SAE_ASSOCID_ANY = 0x0 + SAE_CONNID_ALL = 0xffffffff + SAE_CONNID_ANY = 0x0 SCM_CREDS = 0x3 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index bb02aa6c05..4a55a40058 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -237,6 +237,9 @@ const ( CLOCK_UPTIME_RAW_APPROX = 0x9 CLONE_NOFOLLOW = 0x1 CLONE_NOOWNERCOPY = 0x2 + CONNECT_DATA_AUTHENTICATED = 0x4 + CONNECT_DATA_IDEMPOTENT = 0x2 + CONNECT_RESUME_ON_READ_WRITE = 0x1 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -1169,6 +1172,11 @@ const ( PT_WRITE_D = 0x5 PT_WRITE_I = 0x4 PT_WRITE_U = 0x6 + RENAME_EXCL = 0x4 + RENAME_NOFOLLOW_ANY = 0x10 + RENAME_RESERVED1 = 0x8 + RENAME_SECLUDE = 0x1 + RENAME_SWAP = 0x2 RLIMIT_AS = 0x5 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1260,6 +1268,10 @@ const ( RTV_SSTHRESH = 0x20 RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 + SAE_ASSOCID_ALL = 0xffffffff + SAE_ASSOCID_ANY = 0x0 + SAE_CONNID_ALL = 0xffffffff + SAE_CONNID_ANY = 0x0 SCM_CREDS = 0x3 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 93a38a97d9..01a70b2463 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -457,6 +457,7 @@ const ( B600 = 0x8 B75 = 0x2 B9600 = 0xd + BCACHEFS_SUPER_MAGIC = 0xca451a4e BDEVFS_MAGIC = 0x62646576 BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d @@ -502,6 +503,7 @@ const ( BPF_IMM = 0x0 BPF_IND = 0x40 BPF_JA = 0x0 + BPF_JCOND = 0xe0 BPF_JEQ = 0x10 BPF_JGE = 0x30 BPF_JGT = 0x20 @@ -657,6 +659,9 @@ const ( CAN_NPROTO = 0x8 CAN_RAW = 0x1 CAN_RAW_FILTER_MAX = 0x200 + CAN_RAW_XL_VCID_RX_FILTER = 0x4 + CAN_RAW_XL_VCID_TX_PASS = 0x2 + CAN_RAW_XL_VCID_TX_SET = 0x1 CAN_RTR_FLAG = 0x40000000 CAN_SFF_ID_BITS = 0xb CAN_SFF_MASK = 0x7ff @@ -924,6 +929,7 @@ const ( EPOLL_CTL_ADD = 0x1 EPOLL_CTL_DEL = 0x2 EPOLL_CTL_MOD = 0x3 + EPOLL_IOC_TYPE = 0x8a EROFS_SUPER_MAGIC_V1 = 0xe0f5e1e2 ESP_V4_FLOW = 0xa ESP_V6_FLOW = 0xc @@ -937,9 +943,6 @@ const ( ETHTOOL_FEC_OFF = 0x4 ETHTOOL_FEC_RS = 0x8 ETHTOOL_FLAG_ALL = 0x7 - ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 - ETHTOOL_FLAG_OMIT_REPLY = 0x2 - ETHTOOL_FLAG_STATS = 0x4 ETHTOOL_FLASHDEV = 0x33 ETHTOOL_FLASH_MAX_FILENAME = 0x80 ETHTOOL_FWVERS_LEN = 0x20 @@ -1339,6 +1342,7 @@ const ( F_OFD_SETLK = 0x25 F_OFD_SETLKW = 0x26 F_OK = 0x0 + F_SEAL_EXEC = 0x20 F_SEAL_FUTURE_WRITE = 0x10 F_SEAL_GROW = 0x4 F_SEAL_SEAL = 0x1 @@ -1627,6 +1631,7 @@ const ( IP_FREEBIND = 0xf IP_HDRINCL = 0x3 IP_IPSEC_POLICY = 0x10 + IP_LOCAL_PORT_RANGE = 0x33 IP_MAXPACKET = 0xffff IP_MAX_MEMBERSHIPS = 0x14 IP_MF = 0x2000 @@ -1653,6 +1658,7 @@ const ( IP_PMTUDISC_OMIT = 0x5 IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 + IP_PROTOCOL = 0x34 IP_RECVERR = 0xb IP_RECVERR_RFC4884 = 0x1a IP_RECVFRAGSIZE = 0x19 @@ -1698,6 +1704,7 @@ const ( KEXEC_ARCH_S390 = 0x160000 KEXEC_ARCH_SH = 0x2a0000 KEXEC_ARCH_X86_64 = 0x3e0000 + KEXEC_CRASH_HOTPLUG_SUPPORT = 0x8 KEXEC_FILE_DEBUG = 0x8 KEXEC_FILE_NO_INITRAMFS = 0x4 KEXEC_FILE_ON_CRASH = 0x2 @@ -1773,6 +1780,7 @@ const ( KEY_SPEC_USER_KEYRING = -0x4 KEY_SPEC_USER_SESSION_KEYRING = -0x5 LANDLOCK_ACCESS_FS_EXECUTE = 0x1 + LANDLOCK_ACCESS_FS_IOCTL_DEV = 0x8000 LANDLOCK_ACCESS_FS_MAKE_BLOCK = 0x800 LANDLOCK_ACCESS_FS_MAKE_CHAR = 0x40 LANDLOCK_ACCESS_FS_MAKE_DIR = 0x80 @@ -1854,6 +1862,19 @@ const ( MAP_FILE = 0x0 MAP_FIXED = 0x10 MAP_FIXED_NOREPLACE = 0x100000 + MAP_HUGE_16GB = 0x88000000 + MAP_HUGE_16KB = 0x38000000 + MAP_HUGE_16MB = 0x60000000 + MAP_HUGE_1GB = 0x78000000 + MAP_HUGE_1MB = 0x50000000 + MAP_HUGE_256MB = 0x70000000 + MAP_HUGE_2GB = 0x7c000000 + MAP_HUGE_2MB = 0x54000000 + MAP_HUGE_32MB = 0x64000000 + MAP_HUGE_512KB = 0x4c000000 + MAP_HUGE_512MB = 0x74000000 + MAP_HUGE_64KB = 0x40000000 + MAP_HUGE_8MB = 0x5c000000 MAP_HUGE_MASK = 0x3f MAP_HUGE_SHIFT = 0x1a MAP_PRIVATE = 0x2 @@ -2169,7 +2190,7 @@ const ( NFT_SECMARK_CTX_MAXLEN = 0x100 NFT_SET_MAXNAMELEN = 0x100 NFT_SOCKET_MAX = 0x3 - NFT_TABLE_F_MASK = 0x3 + NFT_TABLE_F_MASK = 0x7 NFT_TABLE_MAXNAMELEN = 0x100 NFT_TRACETYPE_MAX = 0x3 NFT_TUNNEL_F_MASK = 0x7 @@ -2403,6 +2424,7 @@ const ( PERF_RECORD_MISC_USER = 0x2 PERF_SAMPLE_BRANCH_PLM_ALL = 0x7 PERF_SAMPLE_WEIGHT_TYPE = 0x1004000 + PID_FS_MAGIC = 0x50494446 PIPEFS_MAGIC = 0x50495045 PPPIOCGNPMODE = 0xc008744c PPPIOCNEWUNIT = 0xc004743e @@ -2490,6 +2512,23 @@ const ( PR_PAC_GET_ENABLED_KEYS = 0x3d PR_PAC_RESET_KEYS = 0x36 PR_PAC_SET_ENABLED_KEYS = 0x3c + PR_PPC_DEXCR_CTRL_CLEAR = 0x4 + PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10 + PR_PPC_DEXCR_CTRL_EDITABLE = 0x1 + PR_PPC_DEXCR_CTRL_MASK = 0x1f + PR_PPC_DEXCR_CTRL_SET = 0x2 + PR_PPC_DEXCR_CTRL_SET_ONEXEC = 0x8 + PR_PPC_DEXCR_IBRTPD = 0x1 + PR_PPC_DEXCR_NPHIE = 0x3 + PR_PPC_DEXCR_SBHE = 0x0 + PR_PPC_DEXCR_SRAPD = 0x2 + PR_PPC_GET_DEXCR = 0x48 + PR_PPC_SET_DEXCR = 0x49 + PR_RISCV_CTX_SW_FENCEI_OFF = 0x1 + PR_RISCV_CTX_SW_FENCEI_ON = 0x0 + PR_RISCV_SCOPE_PER_PROCESS = 0x0 + PR_RISCV_SCOPE_PER_THREAD = 0x1 + PR_RISCV_SET_ICACHE_FLUSH_CTX = 0x47 PR_RISCV_V_GET_CONTROL = 0x46 PR_RISCV_V_SET_CONTROL = 0x45 PR_RISCV_V_VSTATE_CTRL_CUR_MASK = 0x3 @@ -2896,8 +2935,9 @@ const ( RWF_APPEND = 0x10 RWF_DSYNC = 0x2 RWF_HIPRI = 0x1 + RWF_NOAPPEND = 0x20 RWF_NOWAIT = 0x8 - RWF_SUPPORTED = 0x1f + RWF_SUPPORTED = 0x3f RWF_SYNC = 0x4 RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 @@ -2918,7 +2958,9 @@ const ( SCHED_RESET_ON_FORK = 0x40000000 SCHED_RR = 0x2 SCM_CREDENTIALS = 0x2 + SCM_PIDFD = 0x4 SCM_RIGHTS = 0x1 + SCM_SECURITY = 0x3 SCM_TIMESTAMP = 0x1d SC_LOG_FLUSH = 0x100000 SECCOMP_ADDFD_FLAG_SEND = 0x2 @@ -3051,6 +3093,8 @@ const ( SIOCSMIIREG = 0x8949 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SK_DIAG_BPF_STORAGE_MAX = 0x3 + SK_DIAG_BPF_STORAGE_REQ_MAX = 0x1 SMACK_MAGIC = 0x43415d53 SMART_AUTOSAVE = 0xd2 SMART_AUTO_OFFLINE = 0xdb @@ -3071,6 +3115,8 @@ const ( SOCKFS_MAGIC = 0x534f434b SOCK_BUF_LOCK_MASK = 0x3 SOCK_DCCP = 0x6 + SOCK_DESTROY = 0x15 + SOCK_DIAG_BY_FAMILY = 0x14 SOCK_IOC_TYPE = 0x89 SOCK_PACKET = 0xa SOCK_RAW = 0x3 @@ -3177,6 +3223,7 @@ const ( STATX_MTIME = 0x40 STATX_NLINK = 0x4 STATX_SIZE = 0x200 + STATX_SUBVOL = 0x8000 STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 @@ -3260,6 +3307,7 @@ const ( TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_IFINDEX = 0x2 TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 42ff8c3c1b..684a5168da 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -118,6 +120,7 @@ const ( IXOFF = 0x1000 IXON = 0x400 MAP_32BIT = 0x40 + MAP_ABOVE4G = 0x80 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index dca436004f..61d74b592d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -118,6 +120,7 @@ const ( IXOFF = 0x1000 IXON = 0x400 MAP_32BIT = 0x40 + MAP_ABOVE4G = 0x80 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 5cca668ac3..a28c9e3e89 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index d8cae6d153..ab5d1fe8ea 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 ESR_MAGIC = 0x45535201 EXTPROC = 0x10000 @@ -87,6 +89,7 @@ const ( FICLONE = 0x40049409 FICLONERANGE = 0x4020940d FLUSHO = 0x1000 + FPMR_MAGIC = 0x46504d52 FPSIMD_MAGIC = 0x46508001 FS_IOC_ENABLE_VERITY = 0x40806685 FS_IOC_GETFLAGS = 0x80086601 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 28e39afdcb..c523090e7c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index cd66e92cb4..01e6ea7804 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index c1595eba78..7aa610b1e7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index ee9456b0da..92af771b44 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 8cfca81e1b..b27ef5e6f1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index 60b0deb3af..237a2cefb3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x20 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000000 FF1 = 0x4000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index f90aa7281b..4a5c555a36 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x20 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000000 FF1 = 0x4000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index ba9e015033..a02fb49a5f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x20 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000000 FF1 = 0x4000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 07cdfd6e9f..e26a7c61b2 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 2f1dd214a7..c48f7c2103 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index f40519d901..ad4b9aace7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -82,6 +82,8 @@ const ( EFD_CLOEXEC = 0x400000 EFD_NONBLOCK = 0x4000 EMT_TAGOVF = 0x1 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x400000 EXTPROC = 0x10000 FF1 = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go index da08b2ab3d..1ec2b1407b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go @@ -581,6 +581,8 @@ const ( AT_EMPTY_PATH = 0x1000 AT_REMOVEDIR = 0x200 RENAME_NOREPLACE = 1 << 0 + ST_RDONLY = 1 + ST_NOSUID = 2 ) const ( diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index ccb02f240a..24b346e1a3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -740,6 +740,54 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func renamexNp(from string, to string, flag uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_renamex_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renamex_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renamex_np renamex_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func renameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_renameatx_np_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), uintptr(flag), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renameatx_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renameatx_np renameatx_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -760,6 +808,59 @@ var libc_sysctl_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func pthread_chdir_np(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pthread_chdir_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pthread_fchdir_np(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pthread_fchdir_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) { + var _p0 unsafe.Pointer + if len(iov) > 0 { + _p0 = unsafe.Pointer(&iov[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall9(libc_connectx_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(endpoints)), uintptr(associd), uintptr(flags), uintptr(_p0), uintptr(len(iov)), uintptr(unsafe.Pointer(n)), uintptr(unsafe.Pointer(connid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_connectx_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_connectx connectx "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index 8b8bb28402..ebd213100b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -223,11 +223,36 @@ TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) +TEXT libc_renamex_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renamex_np(SB) +GLOBL ·libc_renamex_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renamex_np_trampoline_addr(SB)/8, $libc_renamex_np_trampoline<>(SB) + +TEXT libc_renameatx_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renameatx_np(SB) +GLOBL ·libc_renameatx_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renameatx_np_trampoline_addr(SB)/8, $libc_renameatx_np_trampoline<>(SB) + TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) +TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pthread_chdir_np(SB) +GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB) + +TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pthread_fchdir_np(SB) +GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB) + +TEXT libc_connectx_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_connectx(SB) +GLOBL ·libc_connectx_trampoline_addr(SB), RODATA, $8 +DATA ·libc_connectx_trampoline_addr(SB)/8, $libc_connectx_trampoline<>(SB) + TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendfile(SB) GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 1b40b997b5..824b9c2d5e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -740,6 +740,54 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func renamexNp(from string, to string, flag uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_renamex_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renamex_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renamex_np renamex_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func renameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_renameatx_np_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), uintptr(flag), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renameatx_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renameatx_np renameatx_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -760,6 +808,59 @@ var libc_sysctl_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func pthread_chdir_np(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pthread_chdir_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pthread_fchdir_np(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pthread_fchdir_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) { + var _p0 unsafe.Pointer + if len(iov) > 0 { + _p0 = unsafe.Pointer(&iov[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall9(libc_connectx_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(endpoints)), uintptr(associd), uintptr(flags), uintptr(_p0), uintptr(len(iov)), uintptr(unsafe.Pointer(n)), uintptr(unsafe.Pointer(connid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_connectx_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_connectx connectx "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index 08362c1ab7..4f178a2293 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -223,11 +223,36 @@ TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) +TEXT libc_renamex_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renamex_np(SB) +GLOBL ·libc_renamex_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renamex_np_trampoline_addr(SB)/8, $libc_renamex_np_trampoline<>(SB) + +TEXT libc_renameatx_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renameatx_np(SB) +GLOBL ·libc_renameatx_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renameatx_np_trampoline_addr(SB)/8, $libc_renameatx_np_trampoline<>(SB) + TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) +TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pthread_chdir_np(SB) +GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB) + +TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pthread_fchdir_np(SB) +GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB) + +TEXT libc_connectx_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_connectx(SB) +GLOBL ·libc_connectx_trampoline_addr(SB), RODATA, $8 +DATA ·libc_connectx_trampoline_addr(SB)/8, $libc_connectx_trampoline<>(SB) + TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendfile(SB) GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 87d8612a1d..1bc1a5adb2 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -2229,3 +2229,19 @@ func Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mseal(b []byte, flags uint) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSEAL, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index 9dc42410b7..1851df14e8 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s index 41b5617316..0b43c69365 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mknodat_trampoline_addr(SB)/4, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $4 +DATA ·libc_mount_trampoline_addr(SB)/4, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $4 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 0d3a0751cd..e1ec0dbe4e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s index 4019a656f6..880c6d6e31 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index c39f7776db..7c8452a63e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s index ac4af24f90..b8ef95b0fa 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mknodat_trampoline_addr(SB)/4, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $4 +DATA ·libc_mount_trampoline_addr(SB)/4, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $4 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 57571d072f..2ffdf861f7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s index f77d532121..2af3b5c762 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index e62963e67e..1da08d5267 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s index fae140b62c..b7a251353b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go index 00831354c8..6e85b0aac9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s index 9d1e0ff06d..f15dadf055 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s @@ -555,6 +555,12 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mount(SB) + RET +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 CALL libc_nanosleep(SB) RET diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go index 79029ed584..28b487df25 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s index da115f9a4b..1e7f321e43 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index 53aef5dc58..524b0820cb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -457,4 +457,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index 71d524763d..d3e38f681a 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -379,4 +379,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index c747706131..70b35bf3b0 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -421,4 +421,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index f96e214f6d..6c778c2327 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -324,4 +324,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 28425346cf..37281cf51a 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -318,4 +318,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index d0953018da..7e567f1eff 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -441,4 +441,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 4459 SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 + SYS_MSEAL = 4462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 295c7f4b81..38ae55e5ef 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -371,4 +371,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 5459 SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 + SYS_MSEAL = 5462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index d1a9eaca7a..55e92e60a8 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -371,4 +371,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 5459 SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 + SYS_MSEAL = 5462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index bec157c39f..60658d6a02 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -441,4 +441,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 4459 SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 + SYS_MSEAL = 4462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index 7ee7bdc435..e203e8a7ed 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -448,4 +448,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index fad1f25b44..5944b97d54 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -420,4 +420,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index 7d3e16357d..c66d416dad 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -420,4 +420,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 0ed53ad9f7..9889f6a559 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -325,4 +325,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index 2fba04ad50..01d86825bb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -386,4 +386,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 621d00d741..7b703e77cd 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -399,4 +399,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 091d107f3a..d003c3d437 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -306,6 +306,19 @@ type XVSockPgen struct { type _Socklen uint32 +type SaeAssocID uint32 + +type SaeConnID uint32 + +type SaEndpoints struct { + Srcif uint32 + Srcaddr *RawSockaddr + Srcaddrlen uint32 + Dstaddr *RawSockaddr + Dstaddrlen uint32 + _ [4]byte +} + type Xucred struct { Version uint32 Uid uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 28ff4ef74d..0d45a941aa 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -306,6 +306,19 @@ type XVSockPgen struct { type _Socklen uint32 +type SaeAssocID uint32 + +type SaeConnID uint32 + +type SaEndpoints struct { + Srcif uint32 + Srcaddr *RawSockaddr + Srcaddrlen uint32 + Dstaddr *RawSockaddr + Dstaddrlen uint32 + _ [4]byte +} + type Xucred struct { Version uint32 Uid uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go index 6cbd094a3a..51e13eb055 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go @@ -625,6 +625,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go index 7c03b6ee77..d002d8ef3c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go @@ -630,6 +630,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go index 422107ee8b..3f863d898d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go @@ -616,6 +616,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go index 505a12acfd..61c7293106 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go @@ -610,6 +610,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go index cc986c7900..b5d17414f0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go @@ -612,6 +612,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 0036746ea1..9f2550dc31 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -110,7 +110,8 @@ type Statx_t struct { Mnt_id uint64 Dio_mem_align uint32 Dio_offset_align uint32 - _ [12]uint64 + Subvol uint64 + _ [11]uint64 } type Fsid struct { @@ -2485,7 +2486,7 @@ type XDPMmapOffsets struct { type XDPUmemReg struct { Addr uint64 Len uint64 - Chunk_size uint32 + Size uint32 Headroom uint32 Flags uint32 Tx_metadata_len uint32 @@ -3473,7 +3474,7 @@ const ( DEVLINK_PORT_FN_ATTR_STATE = 0x2 DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3 DEVLINK_PORT_FN_ATTR_CAPS = 0x4 - DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x5 + DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x6 ) type FsverityDigest struct { @@ -3806,6 +3807,9 @@ const ( ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 ETHTOOL_MSG_KERNEL_MAX = 0x2b + ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 + ETHTOOL_FLAG_OMIT_REPLY = 0x2 + ETHTOOL_FLAG_STATS = 0x4 ETHTOOL_A_HEADER_UNSPEC = 0x0 ETHTOOL_A_HEADER_DEV_INDEX = 0x1 ETHTOOL_A_HEADER_DEV_NAME = 0x2 @@ -3975,7 +3979,7 @@ const ( ETHTOOL_A_TSINFO_TX_TYPES = 0x3 ETHTOOL_A_TSINFO_RX_FILTERS = 0x4 ETHTOOL_A_TSINFO_PHC_INDEX = 0x5 - ETHTOOL_A_TSINFO_MAX = 0x5 + ETHTOOL_A_TSINFO_MAX = 0x6 ETHTOOL_A_CABLE_TEST_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_HEADER = 0x1 ETHTOOL_A_CABLE_TEST_MAX = 0x1 @@ -4605,7 +4609,7 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x149 + NL80211_ATTR_MAX = 0x14a NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 @@ -5209,7 +5213,7 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x1f + NL80211_FREQUENCY_ATTR_MAX = 0x20 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc @@ -5703,7 +5707,7 @@ const ( NL80211_STA_FLAG_ASSOCIATED = 0x7 NL80211_STA_FLAG_AUTHENTICATED = 0x5 NL80211_STA_FLAG_AUTHORIZED = 0x1 - NL80211_STA_FLAG_MAX = 0x7 + NL80211_STA_FLAG_MAX = 0x8 NL80211_STA_FLAG_MAX_OLD_API = 0x6 NL80211_STA_FLAG_MFP = 0x4 NL80211_STA_FLAG_SHORT_PREAMBLE = 0x2 @@ -6001,3 +6005,34 @@ type CachestatRange struct { Off uint64 Len uint64 } + +const ( + SK_MEMINFO_RMEM_ALLOC = 0x0 + SK_MEMINFO_RCVBUF = 0x1 + SK_MEMINFO_WMEM_ALLOC = 0x2 + SK_MEMINFO_SNDBUF = 0x3 + SK_MEMINFO_FWD_ALLOC = 0x4 + SK_MEMINFO_WMEM_QUEUED = 0x5 + SK_MEMINFO_OPTMEM = 0x6 + SK_MEMINFO_BACKLOG = 0x7 + SK_MEMINFO_DROPS = 0x8 + SK_MEMINFO_VARS = 0x9 + SKNLGRP_NONE = 0x0 + SKNLGRP_INET_TCP_DESTROY = 0x1 + SKNLGRP_INET_UDP_DESTROY = 0x2 + SKNLGRP_INET6_TCP_DESTROY = 0x3 + SKNLGRP_INET6_UDP_DESTROY = 0x4 + SK_DIAG_BPF_STORAGE_REQ_NONE = 0x0 + SK_DIAG_BPF_STORAGE_REQ_MAP_FD = 0x1 + SK_DIAG_BPF_STORAGE_REP_NONE = 0x0 + SK_DIAG_BPF_STORAGE = 0x1 + SK_DIAG_BPF_STORAGE_NONE = 0x0 + SK_DIAG_BPF_STORAGE_PAD = 0x1 + SK_DIAG_BPF_STORAGE_MAP_ID = 0x2 + SK_DIAG_BPF_STORAGE_MAP_VALUE = 0x3 +) + +type SockDiagReq struct { + Family uint8 + Protocol uint8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 15adc04142..ad05b51a60 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -727,6 +727,37 @@ const ( RISCV_HWPROBE_EXT_ZBA = 0x8 RISCV_HWPROBE_EXT_ZBB = 0x10 RISCV_HWPROBE_EXT_ZBS = 0x20 + RISCV_HWPROBE_EXT_ZICBOZ = 0x40 + RISCV_HWPROBE_EXT_ZBC = 0x80 + RISCV_HWPROBE_EXT_ZBKB = 0x100 + RISCV_HWPROBE_EXT_ZBKC = 0x200 + RISCV_HWPROBE_EXT_ZBKX = 0x400 + RISCV_HWPROBE_EXT_ZKND = 0x800 + RISCV_HWPROBE_EXT_ZKNE = 0x1000 + RISCV_HWPROBE_EXT_ZKNH = 0x2000 + RISCV_HWPROBE_EXT_ZKSED = 0x4000 + RISCV_HWPROBE_EXT_ZKSH = 0x8000 + RISCV_HWPROBE_EXT_ZKT = 0x10000 + RISCV_HWPROBE_EXT_ZVBB = 0x20000 + RISCV_HWPROBE_EXT_ZVBC = 0x40000 + RISCV_HWPROBE_EXT_ZVKB = 0x80000 + RISCV_HWPROBE_EXT_ZVKG = 0x100000 + RISCV_HWPROBE_EXT_ZVKNED = 0x200000 + RISCV_HWPROBE_EXT_ZVKNHA = 0x400000 + RISCV_HWPROBE_EXT_ZVKNHB = 0x800000 + RISCV_HWPROBE_EXT_ZVKSED = 0x1000000 + RISCV_HWPROBE_EXT_ZVKSH = 0x2000000 + RISCV_HWPROBE_EXT_ZVKT = 0x4000000 + RISCV_HWPROBE_EXT_ZFH = 0x8000000 + RISCV_HWPROBE_EXT_ZFHMIN = 0x10000000 + RISCV_HWPROBE_EXT_ZIHINTNTL = 0x20000000 + RISCV_HWPROBE_EXT_ZVFH = 0x40000000 + RISCV_HWPROBE_EXT_ZVFHMIN = 0x80000000 + RISCV_HWPROBE_EXT_ZFA = 0x100000000 + RISCV_HWPROBE_EXT_ZTSO = 0x200000000 + RISCV_HWPROBE_EXT_ZACAS = 0x400000000 + RISCV_HWPROBE_EXT_ZICOND = 0x800000000 + RISCV_HWPROBE_EXT_ZIHINTPAUSE = 0x1000000000 RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5 RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0 RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1 @@ -734,4 +765,6 @@ const ( RISCV_HWPROBE_MISALIGNED_FAST = 0x3 RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4 RISCV_HWPROBE_MISALIGNED_MASK = 0x7 + RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE = 0x6 + RISCV_HWPROBE_WHICH_CPUS = 0x1 ) diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go index 26be94a8a7..b6e1ab76f8 100644 --- a/vendor/golang.org/x/sys/windows/security_windows.go +++ b/vendor/golang.org/x/sys/windows/security_windows.go @@ -68,6 +68,7 @@ type UserInfo10 struct { //sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo //sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation //sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree +//sys NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) = netapi32.NetUserEnum const ( // do not reorder @@ -893,7 +894,7 @@ type ACL struct { aclRevision byte sbz1 byte aclSize uint16 - aceCount uint16 + AceCount uint16 sbz2 uint16 } @@ -1086,6 +1087,27 @@ type EXPLICIT_ACCESS struct { Trustee TRUSTEE } +// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header +type ACE_HEADER struct { + AceType uint8 + AceFlags uint8 + AceSize uint16 +} + +// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace +type ACCESS_ALLOWED_ACE struct { + Header ACE_HEADER + Mask ACCESS_MASK + SidStart uint32 +} + +const ( + // Constants for AceType + // https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header + ACCESS_ALLOWED_ACE_TYPE = 0 + ACCESS_DENIED_ACE_TYPE = 1 +) + // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions. type TrusteeValue uintptr @@ -1157,6 +1179,7 @@ type OBJECTS_AND_NAME struct { //sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD //sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW +//sys GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) = advapi32.GetAce // Control returns the security descriptor control bits. func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) { diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 6525c62f3c..5cee9a3143 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -17,8 +17,10 @@ import ( "unsafe" ) -type Handle uintptr -type HWND uintptr +type ( + Handle uintptr + HWND uintptr +) const ( InvalidHandle = ^Handle(0) @@ -211,6 +213,10 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error) //sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW //sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId +//sys LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) [failretval==0] = user32.LoadKeyboardLayoutW +//sys UnloadKeyboardLayout(hkl Handle) (err error) = user32.UnloadKeyboardLayout +//sys GetKeyboardLayout(tid uint32) (hkl Handle) = user32.GetKeyboardLayout +//sys ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) = user32.ToUnicodeEx //sys GetShellWindow() (shellWindow HWND) = user32.GetShellWindow //sys MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW //sys ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx @@ -307,6 +313,10 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode //sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo //sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition +//sys GetConsoleCP() (cp uint32, err error) = kernel32.GetConsoleCP +//sys GetConsoleOutputCP() (cp uint32, err error) = kernel32.GetConsoleOutputCP +//sys SetConsoleCP(cp uint32) (err error) = kernel32.SetConsoleCP +//sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW //sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole @@ -1368,9 +1378,11 @@ func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) } + func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) { return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) } + func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { return syscall.EWINDOWS } diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index d8cb71db0a..7b97a154c9 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -1060,6 +1060,7 @@ const ( SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6 SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4 SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 + SIO_UDP_NETRESET = IOC_IN | IOC_VENDOR | 15 // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 @@ -2003,7 +2004,21 @@ const ( MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 ) -const GAA_FLAG_INCLUDE_PREFIX = 0x00000010 +// Flags for GetAdaptersAddresses, see +// https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses. +const ( + GAA_FLAG_SKIP_UNICAST = 0x1 + GAA_FLAG_SKIP_ANYCAST = 0x2 + GAA_FLAG_SKIP_MULTICAST = 0x4 + GAA_FLAG_SKIP_DNS_SERVER = 0x8 + GAA_FLAG_INCLUDE_PREFIX = 0x10 + GAA_FLAG_SKIP_FRIENDLY_NAME = 0x20 + GAA_FLAG_INCLUDE_WINS_INFO = 0x40 + GAA_FLAG_INCLUDE_GATEWAYS = 0x80 + GAA_FLAG_INCLUDE_ALL_INTERFACES = 0x100 + GAA_FLAG_INCLUDE_ALL_COMPARTMENTS = 0x200 + GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER = 0x400 +) const ( IF_TYPE_OTHER = 1 @@ -2017,6 +2032,50 @@ const ( IF_TYPE_IEEE1394 = 144 ) +// Enum NL_PREFIX_ORIGIN for [IpAdapterUnicastAddress], see +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_prefix_origin +const ( + IpPrefixOriginOther = 0 + IpPrefixOriginManual = 1 + IpPrefixOriginWellKnown = 2 + IpPrefixOriginDhcp = 3 + IpPrefixOriginRouterAdvertisement = 4 + IpPrefixOriginUnchanged = 1 << 4 +) + +// Enum NL_SUFFIX_ORIGIN for [IpAdapterUnicastAddress], see +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_suffix_origin +const ( + NlsoOther = 0 + NlsoManual = 1 + NlsoWellKnown = 2 + NlsoDhcp = 3 + NlsoLinkLayerAddress = 4 + NlsoRandom = 5 + IpSuffixOriginOther = 0 + IpSuffixOriginManual = 1 + IpSuffixOriginWellKnown = 2 + IpSuffixOriginDhcp = 3 + IpSuffixOriginLinkLayerAddress = 4 + IpSuffixOriginRandom = 5 + IpSuffixOriginUnchanged = 1 << 4 +) + +// Enum NL_DAD_STATE for [IpAdapterUnicastAddress], see +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_dad_state +const ( + NldsInvalid = 0 + NldsTentative = 1 + NldsDuplicate = 2 + NldsDeprecated = 3 + NldsPreferred = 4 + IpDadStateInvalid = 0 + IpDadStateTentative = 1 + IpDadStateDuplicate = 2 + IpDadStateDeprecated = 3 + IpDadStatePreferred = 4 +) + type SocketAddress struct { Sockaddr *syscall.RawSockaddrAny SockaddrLength int32 @@ -3404,3 +3463,14 @@ type DCB struct { EvtChar byte wReserved1 uint16 } + +// Keyboard Layout Flags. +// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadkeyboardlayoutw +const ( + KLF_ACTIVATE = 0x00000001 + KLF_SUBSTITUTE_OK = 0x00000002 + KLF_REORDER = 0x00000008 + KLF_REPLACELANG = 0x00000010 + KLF_NOTELLSHELL = 0x00000080 + KLF_SETFORPROCESS = 0x00000100 +) diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 5c6035ddfa..4c2e1bdc01 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -91,6 +91,7 @@ var ( procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") procEqualSid = modadvapi32.NewProc("EqualSid") procFreeSid = modadvapi32.NewProc("FreeSid") + procGetAce = modadvapi32.NewProc("GetAce") procGetLengthSid = modadvapi32.NewProc("GetLengthSid") procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW") procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl") @@ -246,7 +247,9 @@ var ( procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") + procGetConsoleCP = modkernel32.NewProc("GetConsoleCP") procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") + procGetConsoleOutputCP = modkernel32.NewProc("GetConsoleOutputCP") procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") @@ -346,8 +349,10 @@ var ( procSetCommMask = modkernel32.NewProc("SetCommMask") procSetCommState = modkernel32.NewProc("SetCommState") procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") + procSetConsoleCP = modkernel32.NewProc("SetConsoleCP") procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition") procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") + procSetConsoleOutputCP = modkernel32.NewProc("SetConsoleOutputCP") procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") @@ -401,6 +406,7 @@ var ( procTransmitFile = modmswsock.NewProc("TransmitFile") procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree") procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation") + procNetUserEnum = modnetapi32.NewProc("NetUserEnum") procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") procNtCreateFile = modntdll.NewProc("NtCreateFile") procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile") @@ -476,12 +482,16 @@ var ( procGetDesktopWindow = moduser32.NewProc("GetDesktopWindow") procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow") procGetGUIThreadInfo = moduser32.NewProc("GetGUIThreadInfo") + procGetKeyboardLayout = moduser32.NewProc("GetKeyboardLayout") procGetShellWindow = moduser32.NewProc("GetShellWindow") procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId") procIsWindow = moduser32.NewProc("IsWindow") procIsWindowUnicode = moduser32.NewProc("IsWindowUnicode") procIsWindowVisible = moduser32.NewProc("IsWindowVisible") + procLoadKeyboardLayoutW = moduser32.NewProc("LoadKeyboardLayoutW") procMessageBoxW = moduser32.NewProc("MessageBoxW") + procToUnicodeEx = moduser32.NewProc("ToUnicodeEx") + procUnloadKeyboardLayout = moduser32.NewProc("UnloadKeyboardLayout") procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") @@ -787,6 +797,14 @@ func FreeSid(sid *SID) (err error) { return } +func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) { + r1, _, e1 := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetLengthSid(sid *SID) (len uint32) { r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) len = uint32(r0) @@ -2148,6 +2166,15 @@ func GetComputerName(buf *uint16, n *uint32) (err error) { return } +func GetConsoleCP() (cp uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0) + cp = uint32(r0) + if cp == 0 { + err = errnoErr(e1) + } + return +} + func GetConsoleMode(console Handle, mode *uint32) (err error) { r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) if r1 == 0 { @@ -2156,6 +2183,15 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) { return } +func GetConsoleOutputCP() (cp uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetConsoleOutputCP.Addr(), 0, 0, 0, 0) + cp = uint32(r0) + if cp == 0 { + err = errnoErr(e1) + } + return +} + func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) if r1 == 0 { @@ -3024,6 +3060,14 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { return } +func SetConsoleCP(cp uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleCP.Addr(), 1, uintptr(cp), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func setConsoleCursorPosition(console Handle, position uint32) (err error) { r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0) if r1 == 0 { @@ -3040,6 +3084,14 @@ func SetConsoleMode(console Handle, mode uint32) (err error) { return } +func SetConsoleOutputCP(cp uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleOutputCP.Addr(), 1, uintptr(cp), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetCurrentDirectory(path *uint16) (err error) { r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) if r1 == 0 { @@ -3486,6 +3538,14 @@ func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (nete return } +func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) { + r0, _, _ := syscall.Syscall9(procNetUserEnum.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle)), 0) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) { r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0) if r0 != 0 { @@ -4064,6 +4124,12 @@ func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) { return } +func GetKeyboardLayout(tid uint32) (hkl Handle) { + r0, _, _ := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(tid), 0, 0) + hkl = Handle(r0) + return +} + func GetShellWindow() (shellWindow HWND) { r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0) shellWindow = HWND(r0) @@ -4097,6 +4163,15 @@ func IsWindowVisible(hwnd HWND) (isVisible bool) { return } +func LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) { + r0, _, e1 := syscall.Syscall(procLoadKeyboardLayoutW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(flags), 0) + hkl = Handle(r0) + if hkl == 0 { + err = errnoErr(e1) + } + return +} + func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) ret = int32(r0) @@ -4106,6 +4181,20 @@ func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret i return } +func ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) { + r0, _, _ := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl), 0, 0) + ret = int32(r0) + return +} + +func UnloadKeyboardLayout(hkl Handle) (err error) { + r1, _, e1 := syscall.Syscall(procUnloadKeyboardLayout.Addr(), 1, uintptr(hkl), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) { var _p0 uint32 if inheritExisting { diff --git a/vendor/golang.org/x/term/LICENSE b/vendor/golang.org/x/term/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/term/LICENSE +++ b/vendor/golang.org/x/term/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/term/term_windows.go b/vendor/golang.org/x/term/term_windows.go index 465f560604..df6bf948e1 100644 --- a/vendor/golang.org/x/term/term_windows.go +++ b/vendor/golang.org/x/term/term_windows.go @@ -26,6 +26,7 @@ func makeRaw(fd int) (*State, error) { return nil, err } raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + raw |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { return nil, err } diff --git a/vendor/golang.org/x/text/LICENSE b/vendor/golang.org/x/text/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/text/LICENSE +++ b/vendor/golang.org/x/text/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/tools/LICENSE +++ b/vendor/golang.org/x/tools/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/tools/cmd/stringer/stringer.go b/vendor/golang.org/x/tools/cmd/stringer/stringer.go index 998d1a51bf..2b19c93e8e 100644 --- a/vendor/golang.org/x/tools/cmd/stringer/stringer.go +++ b/vendor/golang.org/x/tools/cmd/stringer/stringer.go @@ -188,6 +188,8 @@ type Generator struct { trimPrefix string lineComment bool + + logf func(format string, args ...interface{}) // test logging hook; nil when not testing } func (g *Generator) Printf(format string, args ...interface{}) { @@ -221,13 +223,14 @@ func (g *Generator) parsePackage(patterns []string, tags []string) { // in a separate pass? For later. Tests: false, BuildFlags: []string{fmt.Sprintf("-tags=%s", strings.Join(tags, " "))}, + Logf: g.logf, } pkgs, err := packages.Load(cfg, patterns...) if err != nil { log.Fatal(err) } if len(pkgs) != 1 { - log.Fatalf("error: %d packages found", len(pkgs)) + log.Fatalf("error: %d packages matching %v", len(pkgs), strings.Join(patterns, " ")) } g.addPackage(pkgs[0]) } diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go index 03543bd4bb..137cc8df1d 100644 --- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -47,7 +47,7 @@ import ( func Find(importPath, srcDir string) (filename, path string) { cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) cmd.Dir = srcDir - out, err := cmd.CombinedOutput() + out, err := cmd.Output() if err != nil { return "", "" } diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go deleted file mode 100644 index 0454cdd78e..0000000000 --- a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package packagesdriver fetches type sizes for go/packages and go/analysis. -package packagesdriver - -import ( - "context" - "fmt" - "strings" - - "golang.org/x/tools/internal/gocommand" -) - -var debug = false - -func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) { - inv.Verb = "list" - inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"} - stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) - var goarch, compiler string - if rawErr != nil { - if rawErrMsg := rawErr.Error(); strings.Contains(rawErrMsg, "cannot find main module") || strings.Contains(rawErrMsg, "go.mod file not found") { - // User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc. - // TODO(matloob): Is this a problem in practice? - inv.Verb = "env" - inv.Args = []string{"GOARCH"} - envout, enverr := gocmdRunner.Run(ctx, inv) - if enverr != nil { - return "", "", enverr - } - goarch = strings.TrimSpace(envout.String()) - compiler = "gc" - } else { - return "", "", friendlyErr - } - } else { - fields := strings.Fields(stdout.String()) - if len(fields) < 2 { - return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", - stdout.String(), stderr.String()) - } - goarch = fields[0] - compiler = fields[1] - } - return compiler, goarch, nil -} diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go index da4ab89fe6..3531ac8f5f 100644 --- a/vendor/golang.org/x/tools/go/packages/doc.go +++ b/vendor/golang.org/x/tools/go/packages/doc.go @@ -5,12 +5,20 @@ /* Package packages loads Go packages for inspection and analysis. -The Load function takes as input a list of patterns and return a list of Package -structs describing individual packages matched by those patterns. -The LoadMode controls the amount of detail in the loaded packages. - -Load passes most patterns directly to the underlying build tool, -but all patterns with the prefix "query=", where query is a +The [Load] function takes as input a list of patterns and returns a +list of [Package] values describing individual packages matched by those +patterns. +A [Config] specifies configuration options, the most important of which is +the [LoadMode], which controls the amount of detail in the loaded packages. + +Load passes most patterns directly to the underlying build tool. +The default build tool is the go command. +Its supported patterns are described at +https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns. +Other build systems may be supported by providing a "driver"; +see [The driver protocol]. + +All patterns with the prefix "query=", where query is a non-empty string of letters from [a-z], are reserved and may be interpreted as query operators. @@ -35,7 +43,7 @@ The Package struct provides basic information about the package, including - Imports, a map from source import strings to the Packages they name; - Types, the type information for the package's exported symbols; - Syntax, the parsed syntax trees for the package's source code; and - - TypeInfo, the result of a complete type-check of the package syntax trees. + - TypesInfo, the result of a complete type-check of the package syntax trees. (See the documentation for type Package for the complete list of fields and more detailed descriptions.) @@ -64,9 +72,31 @@ reported about the loaded packages. See the documentation for type LoadMode for details. Most tools should pass their command-line arguments (after any flags) -uninterpreted to the loader, so that the loader can interpret them +uninterpreted to [Load], so that it can interpret them according to the conventions of the underlying build system. + See the Example function for typical usage. + +# The driver protocol + +[Load] may be used to load Go packages even in Go projects that use +alternative build systems, by installing an appropriate "driver" +program for the build system and specifying its location in the +GOPACKAGESDRIVER environment variable. +For example, +https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration +explains how to use the driver for Bazel. + +The driver program is responsible for interpreting patterns in its +preferred notation and reporting information about the packages that +those patterns identify. Drivers must also support the special "file=" +and "pattern=" patterns described above. + +The patterns are provided as positional command-line arguments. A +JSON-encoded [DriverRequest] message providing additional information +is written to the driver's standard input. The driver must write a +JSON-encoded [DriverResponse] message to its standard output. (This +message differs from the JSON schema produced by 'go list'.) */ package packages // import "golang.org/x/tools/go/packages" @@ -168,14 +198,6 @@ Instead, ssadump no longer requests the runtime package, but seeks it among the dependencies of the user-specified packages, and emits an error if it is not found. -Overlays: The Overlay field in the Config allows providing alternate contents -for Go source files, by providing a mapping from file path to contents. -go/packages will pull in new imports added in overlay files when go/packages -is run in LoadImports mode or greater. -Overlay support for the go list driver isn't complete yet: if the file doesn't -exist on disk, it will only be recognized in an overlay if it is a non-test file -and the package would be reported even without the overlay. - Questions & Tasks - Add GOARCH/GOOS? diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go index 7242a0a7d2..8f7afcb5df 100644 --- a/vendor/golang.org/x/tools/go/packages/external.go +++ b/vendor/golang.org/x/tools/go/packages/external.go @@ -2,48 +2,87 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// This file enables an external tool to intercept package requests. -// If the tool is present then its results are used in preference to -// the go list command. - package packages +// This file defines the protocol that enables an external "driver" +// tool to supply package metadata in place of 'go list'. + import ( "bytes" "encoding/json" "fmt" - exec "golang.org/x/sys/execabs" "os" + "os/exec" "strings" ) -// The Driver Protocol +// DriverRequest defines the schema of a request for package metadata +// from an external driver program. The JSON-encoded DriverRequest +// message is provided to the driver program's standard input. The +// query patterns are provided as command-line arguments. // -// The driver, given the inputs to a call to Load, returns metadata about the packages specified. -// This allows for different build systems to support go/packages by telling go/packages how the -// packages' source is organized. -// The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in -// the path as gopackagesdriver. It's given the inputs to load in its argv. See the package -// documentation in doc.go for the full description of the patterns that need to be supported. -// A driver receives as a JSON-serialized driverRequest struct in standard input and will -// produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output. - -// driverRequest is used to provide the portion of Load's Config that is needed by a driver. -type driverRequest struct { +// See the package documentation for an overview. +type DriverRequest struct { Mode LoadMode `json:"mode"` + // Env specifies the environment the underlying build system should be run in. Env []string `json:"env"` + // BuildFlags are flags that should be passed to the underlying build system. BuildFlags []string `json:"build_flags"` + // Tests specifies whether the patterns should also return test packages. Tests bool `json:"tests"` - // Overlay maps file paths (relative to the driver's working directory) to the byte contents - // of overlay files. + + // Overlay maps file paths (relative to the driver's working directory) + // to the contents of overlay files (see Config.Overlay). Overlay map[string][]byte `json:"overlay"` } +// DriverResponse defines the schema of a response from an external +// driver program, providing the results of a query for package +// metadata. The driver program must write a JSON-encoded +// DriverResponse message to its standard output. +// +// See the package documentation for an overview. +type DriverResponse struct { + // NotHandled is returned if the request can't be handled by the current + // driver. If an external driver returns a response with NotHandled, the + // rest of the DriverResponse is ignored, and go/packages will fallback + // to the next driver. If go/packages is extended in the future to support + // lists of multiple drivers, go/packages will fall back to the next driver. + NotHandled bool + + // Compiler and Arch are the arguments pass of types.SizesFor + // to get a types.Sizes to use when type checking. + Compiler string + Arch string + + // Roots is the set of package IDs that make up the root packages. + // We have to encode this separately because when we encode a single package + // we cannot know if it is one of the roots as that requires knowledge of the + // graph it is part of. + Roots []string `json:",omitempty"` + + // Packages is the full set of packages in the graph. + // The packages are not connected into a graph. + // The Imports if populated will be stubs that only have their ID set. + // Imports will be connected and then type and syntax information added in a + // later pass (see refine). + Packages []*Package + + // GoVersion is the minor version number used by the driver + // (e.g. the go command on the PATH) when selecting .go files. + // Zero means unknown. + GoVersion int +} + +// driver is the type for functions that query the build system for the +// packages named by the patterns. +type driver func(cfg *Config, patterns ...string) (*DriverResponse, error) + // findExternalDriver returns the file path of a tool that supplies -// the build system package structure, or "" if not found." +// the build system package structure, or "" if not found. // If GOPACKAGESDRIVER is set in the environment findExternalTool returns its // value, otherwise it searches for a binary named gopackagesdriver on the PATH. func findExternalDriver(cfg *Config) driver { @@ -64,8 +103,8 @@ func findExternalDriver(cfg *Config) driver { return nil } } - return func(cfg *Config, words ...string) (*driverResponse, error) { - req, err := json.Marshal(driverRequest{ + return func(cfg *Config, words ...string) (*DriverResponse, error) { + req, err := json.Marshal(DriverRequest{ Mode: cfg.Mode, Env: cfg.Env, BuildFlags: cfg.BuildFlags, @@ -80,7 +119,19 @@ func findExternalDriver(cfg *Config) driver { stderr := new(bytes.Buffer) cmd := exec.CommandContext(cfg.Context, tool, words...) cmd.Dir = cfg.Dir - cmd.Env = cfg.Env + // The cwd gets resolved to the real path. On Darwin, where + // /tmp is a symlink, this breaks anything that expects the + // working directory to keep the original path, including the + // go command when dealing with modules. + // + // os.Getwd stdlib has a special feature where if the + // cwd and the PWD are the same node then it trusts + // the PWD, so by setting it in the env for the child + // process we fix up all the paths returned by the go + // command. + // + // (See similar trick in Invocation.run in ../../internal/gocommand/invoke.go) + cmd.Env = append(slicesClip(cfg.Env), "PWD="+cfg.Dir) cmd.Stdin = bytes.NewReader(req) cmd.Stdout = buf cmd.Stderr = stderr @@ -92,10 +143,14 @@ func findExternalDriver(cfg *Config) driver { fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr) } - var response driverResponse + var response DriverResponse if err := json.Unmarshal(buf.Bytes(), &response); err != nil { return nil, err } return &response, nil } } + +// slicesClip removes unused capacity from the slice, returning s[:len(s):len(s)]. +// TODO(adonovan): use go1.21 slices.Clip. +func slicesClip[S ~[]E, E any](s S) S { return s[:len(s):len(s)] } diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go index b5de9cf9f2..1a3a5b44f5 100644 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -9,9 +9,9 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" "log" "os" + "os/exec" "path" "path/filepath" "reflect" @@ -21,8 +21,6 @@ import ( "sync" "unicode" - exec "golang.org/x/sys/execabs" - "golang.org/x/tools/go/internal/packagesdriver" "golang.org/x/tools/internal/gocommand" "golang.org/x/tools/internal/packagesinternal" ) @@ -36,23 +34,23 @@ type goTooOldError struct { error } -// responseDeduper wraps a driverResponse, deduplicating its contents. +// responseDeduper wraps a DriverResponse, deduplicating its contents. type responseDeduper struct { seenRoots map[string]bool seenPackages map[string]*Package - dr *driverResponse + dr *DriverResponse } func newDeduper() *responseDeduper { return &responseDeduper{ - dr: &driverResponse{}, + dr: &DriverResponse{}, seenRoots: map[string]bool{}, seenPackages: map[string]*Package{}, } } -// addAll fills in r with a driverResponse. -func (r *responseDeduper) addAll(dr *driverResponse) { +// addAll fills in r with a DriverResponse. +func (r *responseDeduper) addAll(dr *DriverResponse) { for _, pkg := range dr.Packages { r.addPackage(pkg) } @@ -129,7 +127,7 @@ func (state *golistState) mustGetEnv() map[string]string { // goListDriver uses the go list command to interpret the patterns and produce // the build system package structure. // See driver for more details. -func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) { +func goListDriver(cfg *Config, patterns ...string) (_ *DriverResponse, err error) { // Make sure that any asynchronous go commands are killed when we return. parentCtx := cfg.Context if parentCtx == nil { @@ -147,16 +145,18 @@ func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) { } // Fill in response.Sizes asynchronously if necessary. - var sizeserr error - var sizeswg sync.WaitGroup if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 { - sizeswg.Add(1) + errCh := make(chan error) go func() { - compiler, arch, err := packagesdriver.GetSizesForArgsGolist(ctx, state.cfgInvocation(), cfg.gocmdRunner) - sizeserr = err + compiler, arch, err := getSizesForArgs(ctx, state.cfgInvocation(), cfg.gocmdRunner) response.dr.Compiler = compiler response.dr.Arch = arch - sizeswg.Done() + errCh <- err + }() + defer func() { + if sizesErr := <-errCh; sizesErr != nil { + err = sizesErr + } }() } @@ -209,87 +209,10 @@ extractQueries: } } - // Only use go/packages' overlay processing if we're using a Go version - // below 1.16. Otherwise, go list handles it. - if goVersion, err := state.getGoVersion(); err == nil && goVersion < 16 { - modifiedPkgs, needPkgs, err := state.processGolistOverlay(response) - if err != nil { - return nil, err - } - - var containsCandidates []string - if len(containFiles) > 0 { - containsCandidates = append(containsCandidates, modifiedPkgs...) - containsCandidates = append(containsCandidates, needPkgs...) - } - if err := state.addNeededOverlayPackages(response, needPkgs); err != nil { - return nil, err - } - // Check candidate packages for containFiles. - if len(containFiles) > 0 { - for _, id := range containsCandidates { - pkg, ok := response.seenPackages[id] - if !ok { - response.addPackage(&Package{ - ID: id, - Errors: []Error{{ - Kind: ListError, - Msg: fmt.Sprintf("package %s expected but not seen", id), - }}, - }) - continue - } - for _, f := range containFiles { - for _, g := range pkg.GoFiles { - if sameFile(f, g) { - response.addRoot(id) - } - } - } - } - } - // Add root for any package that matches a pattern. This applies only to - // packages that are modified by overlays, since they are not added as - // roots automatically. - for _, pattern := range restPatterns { - match := matchPattern(pattern) - for _, pkgID := range modifiedPkgs { - pkg, ok := response.seenPackages[pkgID] - if !ok { - continue - } - if match(pkg.PkgPath) { - response.addRoot(pkg.ID) - } - } - } - } - - sizeswg.Wait() - if sizeserr != nil { - return nil, sizeserr - } + // (We may yet return an error due to defer.) return response.dr, nil } -func (state *golistState) addNeededOverlayPackages(response *responseDeduper, pkgs []string) error { - if len(pkgs) == 0 { - return nil - } - dr, err := state.createDriverResponse(pkgs...) - if err != nil { - return err - } - for _, pkg := range dr.Packages { - response.addPackage(pkg) - } - _, needPkgs, err := state.processGolistOverlay(response) - if err != nil { - return err - } - return state.addNeededOverlayPackages(response, needPkgs) -} - func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error { for _, query := range queries { // TODO(matloob): Do only one query per directory. @@ -341,7 +264,7 @@ func (state *golistState) runContainsQueries(response *responseDeduper, queries // adhocPackage attempts to load or construct an ad-hoc package for a given // query, if the original call to the driver produced inadequate results. -func (state *golistState) adhocPackage(pattern, query string) (*driverResponse, error) { +func (state *golistState) adhocPackage(pattern, query string) (*DriverResponse, error) { response, err := state.createDriverResponse(query) if err != nil { return nil, err @@ -432,7 +355,7 @@ func otherFiles(p *jsonPackage) [][]string { // createDriverResponse uses the "go list" command to expand the pattern // words and return a response for the specified packages. -func (state *golistState) createDriverResponse(words ...string) (*driverResponse, error) { +func (state *golistState) createDriverResponse(words ...string) (*DriverResponse, error) { // go list uses the following identifiers in ImportPath and Imports: // // "p" -- importable package or main (command) @@ -459,7 +382,7 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse pkgs := make(map[string]*Package) additionalErrors := make(map[string][]Error) // Decode the JSON and convert it to Package form. - response := &driverResponse{ + response := &DriverResponse{ GoVersion: goVersion, } for dec := json.NewDecoder(buf); dec.More(); { @@ -917,6 +840,7 @@ func (state *golistState) cfgInvocation() gocommand.Invocation { Env: cfg.Env, Logf: cfg.Logf, WorkingDir: cfg.Dir, + Overlay: cfg.goListOverlayFile, } } @@ -925,26 +849,6 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, cfg := state.cfg inv := state.cfgInvocation() - - // For Go versions 1.16 and above, `go list` accepts overlays directly via - // the -overlay flag. Set it, if it's available. - // - // The check for "list" is not necessarily required, but we should avoid - // getting the go version if possible. - if verb == "list" { - goVersion, err := state.getGoVersion() - if err != nil { - return nil, err - } - if goVersion >= 16 { - filename, cleanup, err := state.writeOverlays() - if err != nil { - return nil, err - } - defer cleanup() - inv.Overlay = filename - } - } inv.Verb = verb inv.Args = args gocmdRunner := cfg.gocmdRunner @@ -1091,67 +995,6 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, return stdout, nil } -// OverlayJSON is the format overlay files are expected to be in. -// The Replace map maps from overlaid paths to replacement paths: -// the Go command will forward all reads trying to open -// each overlaid path to its replacement path, or consider the overlaid -// path not to exist if the replacement path is empty. -// -// From golang/go#39958. -type OverlayJSON struct { - Replace map[string]string `json:"replace,omitempty"` -} - -// writeOverlays writes out files for go list's -overlay flag, as described -// above. -func (state *golistState) writeOverlays() (filename string, cleanup func(), err error) { - // Do nothing if there are no overlays in the config. - if len(state.cfg.Overlay) == 0 { - return "", func() {}, nil - } - dir, err := ioutil.TempDir("", "gopackages-*") - if err != nil { - return "", nil, err - } - // The caller must clean up this directory, unless this function returns an - // error. - cleanup = func() { - os.RemoveAll(dir) - } - defer func() { - if err != nil { - cleanup() - } - }() - overlays := map[string]string{} - for k, v := range state.cfg.Overlay { - // Create a unique filename for the overlaid files, to avoid - // creating nested directories. - noSeparator := strings.Join(strings.Split(filepath.ToSlash(k), "/"), "") - f, err := ioutil.TempFile(dir, fmt.Sprintf("*-%s", noSeparator)) - if err != nil { - return "", func() {}, err - } - if _, err := f.Write(v); err != nil { - return "", func() {}, err - } - if err := f.Close(); err != nil { - return "", func() {}, err - } - overlays[k] = f.Name() - } - b, err := json.Marshal(OverlayJSON{Replace: overlays}) - if err != nil { - return "", func() {}, err - } - // Write out the overlay file that contains the filepath mappings. - filename = filepath.Join(dir, "overlay.json") - if err := ioutil.WriteFile(filename, b, 0665); err != nil { - return "", func() {}, err - } - return filename, cleanup, nil -} - func containsGoFile(s []string) bool { for _, f := range s { if strings.HasSuffix(f, ".go") { @@ -1180,3 +1023,44 @@ func cmdDebugStr(cmd *exec.Cmd) string { } return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) } + +// getSizesForArgs queries 'go list' for the appropriate +// Compiler and GOARCH arguments to pass to [types.SizesFor]. +func getSizesForArgs(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) { + inv.Verb = "list" + inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"} + stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) + var goarch, compiler string + if rawErr != nil { + rawErrMsg := rawErr.Error() + if strings.Contains(rawErrMsg, "cannot find main module") || + strings.Contains(rawErrMsg, "go.mod file not found") { + // User's running outside of a module. + // All bets are off. Get GOARCH and guess compiler is gc. + // TODO(matloob): Is this a problem in practice? + inv.Verb = "env" + inv.Args = []string{"GOARCH"} + envout, enverr := gocmdRunner.Run(ctx, inv) + if enverr != nil { + return "", "", enverr + } + goarch = strings.TrimSpace(envout.String()) + compiler = "gc" + } else if friendlyErr != nil { + return "", "", friendlyErr + } else { + // This should be unreachable, but be defensive + // in case RunRaw's error results are inconsistent. + return "", "", rawErr + } + } else { + fields := strings.Fields(stdout.String()) + if len(fields) < 2 { + return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", + stdout.String(), stderr.String()) + } + goarch = fields[0] + compiler = fields[1] + } + return compiler, goarch, nil +} diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go index 9576b472f9..d823c474ad 100644 --- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go +++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go @@ -6,314 +6,11 @@ package packages import ( "encoding/json" - "fmt" - "go/parser" - "go/token" - "os" "path/filepath" - "regexp" - "sort" - "strconv" - "strings" "golang.org/x/tools/internal/gocommand" ) -// processGolistOverlay provides rudimentary support for adding -// files that don't exist on disk to an overlay. The results can be -// sometimes incorrect. -// TODO(matloob): Handle unsupported cases, including the following: -// - determining the correct package to add given a new import path -func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) { - havePkgs := make(map[string]string) // importPath -> non-test package ID - needPkgsSet := make(map[string]bool) - modifiedPkgsSet := make(map[string]bool) - - pkgOfDir := make(map[string][]*Package) - for _, pkg := range response.dr.Packages { - // This is an approximation of import path to id. This can be - // wrong for tests, vendored packages, and a number of other cases. - havePkgs[pkg.PkgPath] = pkg.ID - dir, err := commonDir(pkg.GoFiles) - if err != nil { - return nil, nil, err - } - if dir != "" { - pkgOfDir[dir] = append(pkgOfDir[dir], pkg) - } - } - - // If no new imports are added, it is safe to avoid loading any needPkgs. - // Otherwise, it's hard to tell which package is actually being loaded - // (due to vendoring) and whether any modified package will show up - // in the transitive set of dependencies (because new imports are added, - // potentially modifying the transitive set of dependencies). - var overlayAddsImports bool - - // If both a package and its test package are created by the overlay, we - // need the real package first. Process all non-test files before test - // files, and make the whole process deterministic while we're at it. - var overlayFiles []string - for opath := range state.cfg.Overlay { - overlayFiles = append(overlayFiles, opath) - } - sort.Slice(overlayFiles, func(i, j int) bool { - iTest := strings.HasSuffix(overlayFiles[i], "_test.go") - jTest := strings.HasSuffix(overlayFiles[j], "_test.go") - if iTest != jTest { - return !iTest // non-tests are before tests. - } - return overlayFiles[i] < overlayFiles[j] - }) - for _, opath := range overlayFiles { - contents := state.cfg.Overlay[opath] - base := filepath.Base(opath) - dir := filepath.Dir(opath) - var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant - var testVariantOf *Package // if opath is a test file, this is the package it is testing - var fileExists bool - isTestFile := strings.HasSuffix(opath, "_test.go") - pkgName, ok := extractPackageName(opath, contents) - if !ok { - // Don't bother adding a file that doesn't even have a parsable package statement - // to the overlay. - continue - } - // If all the overlay files belong to a different package, change the - // package name to that package. - maybeFixPackageName(pkgName, isTestFile, pkgOfDir[dir]) - nextPackage: - for _, p := range response.dr.Packages { - if pkgName != p.Name && p.ID != "command-line-arguments" { - continue - } - for _, f := range p.GoFiles { - if !sameFile(filepath.Dir(f), dir) { - continue - } - // Make sure to capture information on the package's test variant, if needed. - if isTestFile && !hasTestFiles(p) { - // TODO(matloob): Are there packages other than the 'production' variant - // of a package that this can match? This shouldn't match the test main package - // because the file is generated in another directory. - testVariantOf = p - continue nextPackage - } else if !isTestFile && hasTestFiles(p) { - // We're examining a test variant, but the overlaid file is - // a non-test file. Because the overlay implementation - // (currently) only adds a file to one package, skip this - // package, so that we can add the file to the production - // variant of the package. (https://golang.org/issue/36857 - // tracks handling overlays on both the production and test - // variant of a package). - continue nextPackage - } - if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath { - // We have already seen the production version of the - // for which p is a test variant. - if hasTestFiles(p) { - testVariantOf = pkg - } - } - pkg = p - if filepath.Base(f) == base { - fileExists = true - } - } - } - // The overlay could have included an entirely new package or an - // ad-hoc package. An ad-hoc package is one that we have manually - // constructed from inadequate `go list` results for a file= query. - // It will have the ID command-line-arguments. - if pkg == nil || pkg.ID == "command-line-arguments" { - // Try to find the module or gopath dir the file is contained in. - // Then for modules, add the module opath to the beginning. - pkgPath, ok, err := state.getPkgPath(dir) - if err != nil { - return nil, nil, err - } - if !ok { - break - } - var forTest string // only set for x tests - isXTest := strings.HasSuffix(pkgName, "_test") - if isXTest { - forTest = pkgPath - pkgPath += "_test" - } - id := pkgPath - if isTestFile { - if isXTest { - id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest) - } else { - id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath) - } - } - if pkg != nil { - // TODO(rstambler): We should change the package's path and ID - // here. The only issue is that this messes with the roots. - } else { - // Try to reclaim a package with the same ID, if it exists in the response. - for _, p := range response.dr.Packages { - if reclaimPackage(p, id, opath, contents) { - pkg = p - break - } - } - // Otherwise, create a new package. - if pkg == nil { - pkg = &Package{ - PkgPath: pkgPath, - ID: id, - Name: pkgName, - Imports: make(map[string]*Package), - } - response.addPackage(pkg) - havePkgs[pkg.PkgPath] = id - // Add the production package's sources for a test variant. - if isTestFile && !isXTest && testVariantOf != nil { - pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...) - pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...) - // Add the package under test and its imports to the test variant. - pkg.forTest = testVariantOf.PkgPath - for k, v := range testVariantOf.Imports { - pkg.Imports[k] = &Package{ID: v.ID} - } - } - if isXTest { - pkg.forTest = forTest - } - } - } - } - if !fileExists { - pkg.GoFiles = append(pkg.GoFiles, opath) - // TODO(matloob): Adding the file to CompiledGoFiles can exhibit the wrong behavior - // if the file will be ignored due to its build tags. - pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath) - modifiedPkgsSet[pkg.ID] = true - } - imports, err := extractImports(opath, contents) - if err != nil { - // Let the parser or type checker report errors later. - continue - } - for _, imp := range imports { - // TODO(rstambler): If the package is an x test and the import has - // a test variant, make sure to replace it. - if _, found := pkg.Imports[imp]; found { - continue - } - overlayAddsImports = true - id, ok := havePkgs[imp] - if !ok { - var err error - id, err = state.resolveImport(dir, imp) - if err != nil { - return nil, nil, err - } - } - pkg.Imports[imp] = &Package{ID: id} - // Add dependencies to the non-test variant version of this package as well. - if testVariantOf != nil { - testVariantOf.Imports[imp] = &Package{ID: id} - } - } - } - - // toPkgPath guesses the package path given the id. - toPkgPath := func(sourceDir, id string) (string, error) { - if i := strings.IndexByte(id, ' '); i >= 0 { - return state.resolveImport(sourceDir, id[:i]) - } - return state.resolveImport(sourceDir, id) - } - - // Now that new packages have been created, do another pass to determine - // the new set of missing packages. - for _, pkg := range response.dr.Packages { - for _, imp := range pkg.Imports { - if len(pkg.GoFiles) == 0 { - return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath) - } - pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID) - if err != nil { - return nil, nil, err - } - if _, ok := havePkgs[pkgPath]; !ok { - needPkgsSet[pkgPath] = true - } - } - } - - if overlayAddsImports { - needPkgs = make([]string, 0, len(needPkgsSet)) - for pkg := range needPkgsSet { - needPkgs = append(needPkgs, pkg) - } - } - modifiedPkgs = make([]string, 0, len(modifiedPkgsSet)) - for pkg := range modifiedPkgsSet { - modifiedPkgs = append(modifiedPkgs, pkg) - } - return modifiedPkgs, needPkgs, err -} - -// resolveImport finds the ID of a package given its import path. -// In particular, it will find the right vendored copy when in GOPATH mode. -func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) { - env, err := state.getEnv() - if err != nil { - return "", err - } - if env["GOMOD"] != "" { - return importPath, nil - } - - searchDir := sourceDir - for { - vendorDir := filepath.Join(searchDir, "vendor") - exists, ok := state.vendorDirs[vendorDir] - if !ok { - info, err := os.Stat(vendorDir) - exists = err == nil && info.IsDir() - state.vendorDirs[vendorDir] = exists - } - - if exists { - vendoredPath := filepath.Join(vendorDir, importPath) - if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() { - // We should probably check for .go files here, but shame on anyone who fools us. - path, ok, err := state.getPkgPath(vendoredPath) - if err != nil { - return "", err - } - if ok { - return path, nil - } - } - } - - // We know we've hit the top of the filesystem when we Dir / and get /, - // or C:\ and get C:\, etc. - next := filepath.Dir(searchDir) - if next == searchDir { - break - } - searchDir = next - } - return importPath, nil -} - -func hasTestFiles(p *Package) bool { - for _, f := range p.GoFiles { - if strings.HasSuffix(f, "_test.go") { - return true - } - } - return false -} - // determineRootDirs returns a mapping from absolute directories that could // contain code to their corresponding import path prefixes. func (state *golistState) determineRootDirs() (map[string]string, error) { @@ -384,192 +81,3 @@ func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) { } return m, nil } - -func extractImports(filename string, contents []byte) ([]string, error) { - f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset? - if err != nil { - return nil, err - } - var res []string - for _, imp := range f.Imports { - quotedPath := imp.Path.Value - path, err := strconv.Unquote(quotedPath) - if err != nil { - return nil, err - } - res = append(res, path) - } - return res, nil -} - -// reclaimPackage attempts to reuse a package that failed to load in an overlay. -// -// If the package has errors and has no Name, GoFiles, or Imports, -// then it's possible that it doesn't yet exist on disk. -func reclaimPackage(pkg *Package, id string, filename string, contents []byte) bool { - // TODO(rstambler): Check the message of the actual error? - // It differs between $GOPATH and module mode. - if pkg.ID != id { - return false - } - if len(pkg.Errors) != 1 { - return false - } - if pkg.Name != "" || pkg.ExportFile != "" { - return false - } - if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 { - return false - } - if len(pkg.Imports) > 0 { - return false - } - pkgName, ok := extractPackageName(filename, contents) - if !ok { - return false - } - pkg.Name = pkgName - pkg.Errors = nil - return true -} - -func extractPackageName(filename string, contents []byte) (string, bool) { - // TODO(rstambler): Check the message of the actual error? - // It differs between $GOPATH and module mode. - f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset? - if err != nil { - return "", false - } - return f.Name.Name, true -} - -// commonDir returns the directory that all files are in, "" if files is empty, -// or an error if they aren't in the same directory. -func commonDir(files []string) (string, error) { - seen := make(map[string]bool) - for _, f := range files { - seen[filepath.Dir(f)] = true - } - if len(seen) > 1 { - return "", fmt.Errorf("files (%v) are in more than one directory: %v", files, seen) - } - for k := range seen { - // seen has only one element; return it. - return k, nil - } - return "", nil // no files -} - -// It is possible that the files in the disk directory dir have a different package -// name from newName, which is deduced from the overlays. If they all have a different -// package name, and they all have the same package name, then that name becomes -// the package name. -// It returns true if it changes the package name, false otherwise. -func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package) { - names := make(map[string]int) - for _, p := range pkgsOfDir { - names[p.Name]++ - } - if len(names) != 1 { - // some files are in different packages - return - } - var oldName string - for k := range names { - oldName = k - } - if newName == oldName { - return - } - // We might have a case where all of the package names in the directory are - // the same, but the overlay file is for an x test, which belongs to its - // own package. If the x test does not yet exist on disk, we may not yet - // have its package name on disk, but we should not rename the packages. - // - // We use a heuristic to determine if this file belongs to an x test: - // The test file should have a package name whose package name has a _test - // suffix or looks like "newName_test". - maybeXTest := strings.HasPrefix(oldName+"_test", newName) || strings.HasSuffix(newName, "_test") - if isTestFile && maybeXTest { - return - } - for _, p := range pkgsOfDir { - p.Name = newName - } -} - -// This function is copy-pasted from -// https://github.com/golang/go/blob/9706f510a5e2754595d716bd64be8375997311fb/src/cmd/go/internal/search/search.go#L360. -// It should be deleted when we remove support for overlays from go/packages. -// -// NOTE: This does not handle any ./... or ./ style queries, as this function -// doesn't know the working directory. -// -// matchPattern(pattern)(name) reports whether -// name matches pattern. Pattern is a limited glob -// pattern in which '...' means 'any string' and there -// is no other special syntax. -// Unfortunately, there are two special cases. Quoting "go help packages": -// -// First, /... at the end of the pattern can match an empty string, -// so that net/... matches both net and packages in its subdirectories, like net/http. -// Second, any slash-separated pattern element containing a wildcard never -// participates in a match of the "vendor" element in the path of a vendored -// package, so that ./... does not match packages in subdirectories of -// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do. -// Note, however, that a directory named vendor that itself contains code -// is not a vendored package: cmd/vendor would be a command named vendor, -// and the pattern cmd/... matches it. -func matchPattern(pattern string) func(name string) bool { - // Convert pattern to regular expression. - // The strategy for the trailing /... is to nest it in an explicit ? expression. - // The strategy for the vendor exclusion is to change the unmatchable - // vendor strings to a disallowed code point (vendorChar) and to use - // "(anything but that codepoint)*" as the implementation of the ... wildcard. - // This is a bit complicated but the obvious alternative, - // namely a hand-written search like in most shell glob matchers, - // is too easy to make accidentally exponential. - // Using package regexp guarantees linear-time matching. - - const vendorChar = "\x00" - - if strings.Contains(pattern, vendorChar) { - return func(name string) bool { return false } - } - - re := regexp.QuoteMeta(pattern) - re = replaceVendor(re, vendorChar) - switch { - case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`): - re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)` - case re == vendorChar+`/\.\.\.`: - re = `(/vendor|/` + vendorChar + `/\.\.\.)` - case strings.HasSuffix(re, `/\.\.\.`): - re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?` - } - re = strings.ReplaceAll(re, `\.\.\.`, `[^`+vendorChar+`]*`) - - reg := regexp.MustCompile(`^` + re + `$`) - - return func(name string) bool { - if strings.Contains(name, vendorChar) { - return false - } - return reg.MatchString(replaceVendor(name, vendorChar)) - } -} - -// replaceVendor returns the result of replacing -// non-trailing vendor path elements in x with repl. -func replaceVendor(x, repl string) string { - if !strings.Contains(x, "vendor") { - return x - } - elem := strings.Split(x, "/") - for i := 0; i < len(elem)-1; i++ { - if elem[i] == "vendor" { - elem[i] = repl - } - } - return strings.Join(elem, "/") -} diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go index 124a6fe143..0b6bfaff80 100644 --- a/vendor/golang.org/x/tools/go/packages/packages.go +++ b/vendor/golang.org/x/tools/go/packages/packages.go @@ -9,6 +9,7 @@ package packages import ( "context" "encoding/json" + "errors" "fmt" "go/ast" "go/parser" @@ -16,7 +17,6 @@ import ( "go/token" "go/types" "io" - "io/ioutil" "log" "os" "path/filepath" @@ -25,20 +25,31 @@ import ( "sync" "time" + "golang.org/x/sync/errgroup" + "golang.org/x/tools/go/gcexportdata" "golang.org/x/tools/internal/gocommand" "golang.org/x/tools/internal/packagesinternal" - "golang.org/x/tools/internal/typeparams" "golang.org/x/tools/internal/typesinternal" + "golang.org/x/tools/internal/versions" ) // A LoadMode controls the amount of detail to return when loading. // The bits below can be combined to specify which fields should be // filled in the result packages. +// // The zero value is a special case, equivalent to combining // the NeedName, NeedFiles, and NeedCompiledGoFiles bits. +// // ID and Errors (if present) will always be filled. -// Load may return more information than requested. +// [Load] may return more information than requested. +// +// Unfortunately there are a number of open bugs related to +// interactions among the LoadMode bits: +// - https://github.com/golang/go/issues/56633 +// - https://github.com/golang/go/issues/56677 +// - https://github.com/golang/go/issues/58726 +// - https://github.com/golang/go/issues/63517 type LoadMode int const ( @@ -64,7 +75,7 @@ const ( // NeedTypes adds Types, Fset, and IllTyped. NeedTypes - // NeedSyntax adds Syntax. + // NeedSyntax adds Syntax and Fset. NeedSyntax // NeedTypesInfo adds TypesInfo. @@ -121,15 +132,21 @@ const ( // A Config specifies details about how packages should be loaded. // The zero value is a valid configuration. +// // Calls to Load do not modify this struct. +// +// TODO(adonovan): #67702: this is currently false: in fact, +// calls to [Load] do not modify the public fields of this struct, but +// may modify hidden fields, so concurrent calls to [Load] must not +// use the same Config. But perhaps we should reestablish the +// documented invariant. type Config struct { // Mode controls the level of information returned for each package. Mode LoadMode // Context specifies the context for the load operation. - // If the context is cancelled, the loader may stop early - // and return an ErrCancelled error. - // If Context is nil, the load cannot be cancelled. + // Cancelling the context may cause [Load] to abort and + // return an error. Context context.Context // Logf is the logger for the config. @@ -198,50 +215,23 @@ type Config struct { // setting Tests may have no effect. Tests bool - // Overlay provides a mapping of absolute file paths to file contents. - // If the file with the given path already exists, the parser will use the - // alternative file contents provided by the map. + // Overlay is a mapping from absolute file paths to file contents. // - // Overlays provide incomplete support for when a given file doesn't - // already exist on disk. See the package doc above for more details. + // For each map entry, [Load] uses the alternative file + // contents provided by the overlay mapping instead of reading + // from the file system. This mechanism can be used to enable + // editor-integrated tools to correctly analyze the contents + // of modified but unsaved buffers, for example. + // + // The overlay mapping is passed to the build system's driver + // (see "The driver protocol") so that it too can report + // consistent package metadata about unsaved files. However, + // drivers may vary in their level of support for overlays. Overlay map[string][]byte -} -// driver is the type for functions that query the build system for the -// packages named by the patterns. -type driver func(cfg *Config, patterns ...string) (*driverResponse, error) - -// driverResponse contains the results for a driver query. -type driverResponse struct { - // NotHandled is returned if the request can't be handled by the current - // driver. If an external driver returns a response with NotHandled, the - // rest of the driverResponse is ignored, and go/packages will fallback - // to the next driver. If go/packages is extended in the future to support - // lists of multiple drivers, go/packages will fall back to the next driver. - NotHandled bool - - // Compiler and Arch are the arguments pass of types.SizesFor - // to get a types.Sizes to use when type checking. - Compiler string - Arch string - - // Roots is the set of package IDs that make up the root packages. - // We have to encode this separately because when we encode a single package - // we cannot know if it is one of the roots as that requires knowledge of the - // graph it is part of. - Roots []string `json:",omitempty"` - - // Packages is the full set of packages in the graph. - // The packages are not connected into a graph. - // The Imports if populated will be stubs that only have their ID set. - // Imports will be connected and then type and syntax information added in a - // later pass (see refine). - Packages []*Package - - // GoVersion is the minor version number used by the driver - // (e.g. the go command on the PATH) when selecting .go files. - // Zero means unknown. - GoVersion int + // goListOverlayFile is the JSON file that encodes the Overlay + // mapping, used by 'go list -overlay=...' + goListOverlayFile string } // Load loads and returns the Go packages named by the given patterns. @@ -249,8 +239,22 @@ type driverResponse struct { // Config specifies loading options; // nil behaves the same as an empty Config. // -// Load returns an error if any of the patterns was invalid -// as defined by the underlying build system. +// The [Config.Mode] field is a set of bits that determine what kinds +// of information should be computed and returned. Modes that require +// more information tend to be slower. See [LoadMode] for details +// and important caveats. Its zero value is equivalent to +// NeedName | NeedFiles | NeedCompiledGoFiles. +// +// Each call to Load returns a new set of [Package] instances. +// The Packages and their Imports form a directed acyclic graph. +// +// If the [NeedTypes] mode flag was set, each call to Load uses a new +// [types.Importer], so [types.Object] and [types.Type] values from +// different calls to Load must not be mixed as they will have +// inconsistent notions of type identity. +// +// If any of the patterns was invalid as defined by the +// underlying build system, Load returns an error. // It may return an empty list of packages without an error, // for instance for an empty expansion of a valid wildcard. // Errors associated with a particular package are recorded in the @@ -259,34 +263,162 @@ type driverResponse struct { // proceeding with further analysis. The PrintErrors function is // provided for convenient display of all errors. func Load(cfg *Config, patterns ...string) ([]*Package, error) { - l := newLoader(cfg) - response, err := defaultDriver(&l.Config, patterns...) + ld := newLoader(cfg) + response, external, err := defaultDriver(&ld.Config, patterns...) if err != nil { return nil, err } - l.sizes = types.SizesFor(response.Compiler, response.Arch) - return l.refine(response) + + ld.sizes = types.SizesFor(response.Compiler, response.Arch) + if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 { + // Type size information is needed but unavailable. + if external { + // An external driver may fail to populate the Compiler/GOARCH fields, + // especially since they are relatively new (see #63700). + // Provide a sensible fallback in this case. + ld.sizes = types.SizesFor("gc", runtime.GOARCH) + if ld.sizes == nil { // gccgo-only arch + ld.sizes = types.SizesFor("gc", "amd64") + } + } else { + // Go list should never fail to deliver accurate size information. + // Reject the whole Load since the error is the same for every package. + return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q", + response.Compiler, response.Arch) + } + } + + return ld.refine(response) } // defaultDriver is a driver that implements go/packages' fallback behavior. // It will try to request to an external driver, if one exists. If there's // no external driver, or the driver returns a response with NotHandled set, // defaultDriver will fall back to the go list driver. -func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) { - driver := findExternalDriver(cfg) - if driver == nil { - driver = goListDriver +// The boolean result indicates that an external driver handled the request. +func defaultDriver(cfg *Config, patterns ...string) (*DriverResponse, bool, error) { + const ( + // windowsArgMax specifies the maximum command line length for + // the Windows' CreateProcess function. + windowsArgMax = 32767 + // maxEnvSize is a very rough estimation of the maximum environment + // size of a user. + maxEnvSize = 16384 + // safeArgMax specifies the maximum safe command line length to use + // by the underlying driver excl. the environment. We choose the Windows' + // ARG_MAX as the starting point because it's one of the lowest ARG_MAX + // constants out of the different supported platforms, + // e.g., https://www.in-ulm.de/~mascheck/various/argmax/#results. + safeArgMax = windowsArgMax - maxEnvSize + ) + chunks, err := splitIntoChunks(patterns, safeArgMax) + if err != nil { + return nil, false, err + } + + if driver := findExternalDriver(cfg); driver != nil { + response, err := callDriverOnChunks(driver, cfg, chunks) + if err != nil { + return nil, false, err + } else if !response.NotHandled { + return response, true, nil + } + // (fall through) } - response, err := driver(cfg, patterns...) + + // go list fallback + // + // Write overlays once, as there are many calls + // to 'go list' (one per chunk plus others too). + overlay, cleanupOverlay, err := gocommand.WriteOverlays(cfg.Overlay) + if err != nil { + return nil, false, err + } + defer cleanupOverlay() + cfg.goListOverlayFile = overlay + + response, err := callDriverOnChunks(goListDriver, cfg, chunks) if err != nil { - return response, err - } else if response.NotHandled { - return goListDriver(cfg, patterns...) + return nil, false, err } - return response, nil + return response, false, err +} + +// splitIntoChunks chunks the slice so that the total number of characters +// in a chunk is no longer than argMax. +func splitIntoChunks(patterns []string, argMax int) ([][]string, error) { + if argMax <= 0 { + return nil, errors.New("failed to split patterns into chunks, negative safe argMax value") + } + var chunks [][]string + charsInChunk := 0 + nextChunkStart := 0 + for i, v := range patterns { + vChars := len(v) + if vChars > argMax { + // a single pattern is longer than the maximum safe ARG_MAX, hardly should happen + return nil, errors.New("failed to split patterns into chunks, a pattern is too long") + } + charsInChunk += vChars + 1 // +1 is for a whitespace between patterns that has to be counted too + if charsInChunk > argMax { + chunks = append(chunks, patterns[nextChunkStart:i]) + nextChunkStart = i + charsInChunk = vChars + } + } + // add the last chunk + if nextChunkStart < len(patterns) { + chunks = append(chunks, patterns[nextChunkStart:]) + } + return chunks, nil +} + +func callDriverOnChunks(driver driver, cfg *Config, chunks [][]string) (*DriverResponse, error) { + if len(chunks) == 0 { + return driver(cfg) + } + responses := make([]*DriverResponse, len(chunks)) + errNotHandled := errors.New("driver returned NotHandled") + var g errgroup.Group + for i, chunk := range chunks { + i := i + chunk := chunk + g.Go(func() (err error) { + responses[i], err = driver(cfg, chunk...) + if responses[i] != nil && responses[i].NotHandled { + err = errNotHandled + } + return err + }) + } + if err := g.Wait(); err != nil { + if errors.Is(err, errNotHandled) { + return &DriverResponse{NotHandled: true}, nil + } + return nil, err + } + return mergeResponses(responses...), nil +} + +func mergeResponses(responses ...*DriverResponse) *DriverResponse { + if len(responses) == 0 { + return nil + } + response := newDeduper() + response.dr.NotHandled = false + response.dr.Compiler = responses[0].Compiler + response.dr.Arch = responses[0].Arch + response.dr.GoVersion = responses[0].GoVersion + for _, v := range responses { + response.addAll(v) + } + return response.dr } // A Package describes a loaded Go package. +// +// It also defines part of the JSON schema of [DriverResponse]. +// See the package documentation for an overview. type Package struct { // ID is a unique identifier for a package, // in a syntax provided by the underlying build system. @@ -345,19 +477,30 @@ type Package struct { // to corresponding loaded Packages. Imports map[string]*Package + // Module is the module information for the package if it exists. + // + // Note: it may be missing for std and cmd; see Go issue #65816. + Module *Module + + // -- The following fields are not part of the driver JSON schema. -- + // Types provides type information for the package. // The NeedTypes LoadMode bit sets this field for packages matching the // patterns; type information for dependencies may be missing or incomplete, // unless NeedDeps and NeedImports are also set. - Types *types.Package + // + // Each call to [Load] returns a consistent set of type + // symbols, as defined by the comment at [types.Identical]. + // Avoid mixing type information from two or more calls to [Load]. + Types *types.Package `json:"-"` // Fset provides position information for Types, TypesInfo, and Syntax. // It is set only when Types is set. - Fset *token.FileSet + Fset *token.FileSet `json:"-"` // IllTyped indicates whether the package or any dependency contains errors. // It is set only when Types is set. - IllTyped bool + IllTyped bool `json:"-"` // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles. // @@ -367,26 +510,28 @@ type Package struct { // // Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are // removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles. - Syntax []*ast.File + Syntax []*ast.File `json:"-"` // TypesInfo provides type information about the package's syntax trees. // It is set only when Syntax is set. - TypesInfo *types.Info + TypesInfo *types.Info `json:"-"` // TypesSizes provides the effective size function for types in TypesInfo. - TypesSizes types.Sizes + TypesSizes types.Sizes `json:"-"` + + // -- internal -- // forTest is the package under test, if any. forTest string // depsErrors is the DepsErrors field from the go list response, if any. depsErrors []*packagesinternal.PackageError - - // module is the module information for the package if it exists. - Module *Module } // Module provides module information for a package. +// +// It also defines part of the JSON schema of [DriverResponse]. +// See the package documentation for an overview. type Module struct { Path string // module path Version string // module version @@ -412,12 +557,6 @@ func init() { packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError { return p.(*Package).depsErrors } - packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner { - return config.(*Config).gocmdRunner - } - packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) { - config.(*Config).gocmdRunner = runner - } packagesinternal.SetModFile = func(config interface{}, value string) { config.(*Config).modFile = value } @@ -525,6 +664,7 @@ func (p *Package) UnmarshalJSON(b []byte) error { OtherFiles: flat.OtherFiles, EmbedFiles: flat.EmbedFiles, EmbedPatterns: flat.EmbedPatterns, + IgnoredFiles: flat.IgnoredFiles, ExportFile: flat.ExportFile, } if len(flat.Imports) > 0 { @@ -554,7 +694,7 @@ type loaderPackage struct { type loader struct { pkgs map[string]*loaderPackage Config - sizes types.Sizes + sizes types.Sizes // non-nil if needed by mode parseCache map[string]*parseValue parseCacheMu sync.Mutex exportMu sync.Mutex // enforces mutual exclusion of exportdata operations @@ -634,7 +774,7 @@ func newLoader(cfg *Config) *loader { // refine connects the supplied packages into a graph and then adds type // and syntax information as requested by the LoadMode. -func (ld *loader) refine(response *driverResponse) ([]*Package, error) { +func (ld *loader) refine(response *DriverResponse) ([]*Package, error) { roots := response.Roots rootMap := make(map[string]int, len(roots)) for i, root := range roots { @@ -679,39 +819,38 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) { } } - // Materialize the import graph. - - const ( - white = 0 // new - grey = 1 // in progress - black = 2 // complete - ) - - // visit traverses the import graph, depth-first, - // and materializes the graph as Packages.Imports. - // - // Valid imports are saved in the Packages.Import map. - // Invalid imports (cycles and missing nodes) are saved in the importErrors map. - // Thus, even in the presence of both kinds of errors, the Import graph remains a DAG. - // - // visit returns whether the package needs src or has a transitive - // dependency on a package that does. These are the only packages - // for which we load source code. - var stack []*loaderPackage - var visit func(lpkg *loaderPackage) bool - var srcPkgs []*loaderPackage - visit = func(lpkg *loaderPackage) bool { - switch lpkg.color { - case black: - return lpkg.needsrc - case grey: - panic("internal error: grey node") - } - lpkg.color = grey - stack = append(stack, lpkg) // push - stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports - // If NeedImports isn't set, the imports fields will all be zeroed out. - if ld.Mode&NeedImports != 0 { + if ld.Mode&NeedImports != 0 { + // Materialize the import graph. + + const ( + white = 0 // new + grey = 1 // in progress + black = 2 // complete + ) + + // visit traverses the import graph, depth-first, + // and materializes the graph as Packages.Imports. + // + // Valid imports are saved in the Packages.Import map. + // Invalid imports (cycles and missing nodes) are saved in the importErrors map. + // Thus, even in the presence of both kinds of errors, + // the Import graph remains a DAG. + // + // visit returns whether the package needs src or has a transitive + // dependency on a package that does. These are the only packages + // for which we load source code. + var stack []*loaderPackage + var visit func(lpkg *loaderPackage) bool + visit = func(lpkg *loaderPackage) bool { + switch lpkg.color { + case black: + return lpkg.needsrc + case grey: + panic("internal error: grey node") + } + lpkg.color = grey + stack = append(stack, lpkg) // push + stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports lpkg.Imports = make(map[string]*Package, len(stubs)) for importPath, ipkg := range stubs { var importErr error @@ -735,40 +874,39 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) { } lpkg.Imports[importPath] = imp.Package } - } - if lpkg.needsrc { - srcPkgs = append(srcPkgs, lpkg) - } - if ld.Mode&NeedTypesSizes != 0 { - lpkg.TypesSizes = ld.sizes - } - stack = stack[:len(stack)-1] // pop - lpkg.color = black - return lpkg.needsrc - } + // Complete type information is required for the + // immediate dependencies of each source package. + if lpkg.needsrc && ld.Mode&NeedTypes != 0 { + for _, ipkg := range lpkg.Imports { + ld.pkgs[ipkg.ID].needtypes = true + } + } - if ld.Mode&NeedImports == 0 { - // We do this to drop the stub import packages that we are not even going to try to resolve. - for _, lpkg := range initial { - lpkg.Imports = nil + // NeedTypeSizes causes TypeSizes to be set even + // on packages for which types aren't needed. + if ld.Mode&NeedTypesSizes != 0 { + lpkg.TypesSizes = ld.sizes + } + stack = stack[:len(stack)-1] // pop + lpkg.color = black + + return lpkg.needsrc } - } else { + // For each initial package, create its import DAG. for _, lpkg := range initial { visit(lpkg) } - } - if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 { - for _, lpkg := range srcPkgs { - // Complete type information is required for the - // immediate dependencies of each source package. - for _, ipkg := range lpkg.Imports { - imp := ld.pkgs[ipkg.ID] - imp.needtypes = true - } + + } else { + // !NeedImports: drop the stub (ID-only) import packages + // that we are not even going to try to resolve. + for _, lpkg := range initial { + lpkg.Imports = nil } } + // Load type data and syntax if needed, starting at // the initial packages (roots of the import DAG). if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { @@ -783,6 +921,12 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) { wg.Wait() } + // If the context is done, return its error and + // throw out [likely] incomplete packages. + if err := ld.Context.Err(); err != nil { + return nil, err + } + result := make([]*Package, len(initial)) for i, lpkg := range initial { result[i] = lpkg.Package @@ -816,12 +960,14 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) { } if ld.requestedMode&NeedTypes == 0 { ld.pkgs[i].Types = nil - ld.pkgs[i].Fset = nil ld.pkgs[i].IllTyped = false } if ld.requestedMode&NeedSyntax == 0 { ld.pkgs[i].Syntax = nil } + if ld.requestedMode&NeedTypes == 0 && ld.requestedMode&NeedSyntax == 0 { + ld.pkgs[i].Fset = nil + } if ld.requestedMode&NeedTypesInfo == 0 { ld.pkgs[i].TypesInfo = nil } @@ -878,6 +1024,14 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name) lpkg.Fset = ld.Fset + // Start shutting down if the context is done and do not load + // source or export data files. + // Packages that import this one will have ld.Context.Err() != nil. + // ld.Context.Err() will be returned later by refine. + if ld.Context.Err() != nil { + return + } + // Subtle: we populate all Types fields with an empty Package // before loading export data so that export data processing // never has to create a types.Package for an indirect dependency, @@ -997,15 +1151,23 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { return } + // Start shutting down if the context is done and do not type check. + // Packages that import this one will have ld.Context.Err() != nil. + // ld.Context.Err() will be returned later by refine. + if ld.Context.Err() != nil { + return + } + lpkg.TypesInfo = &types.Info{ Types: make(map[ast.Expr]types.TypeAndValue), Defs: make(map[*ast.Ident]types.Object), Uses: make(map[*ast.Ident]types.Object), Implicits: make(map[ast.Node]types.Object), + Instances: make(map[*ast.Ident]types.Instance), Scopes: make(map[ast.Node]*types.Scope), Selections: make(map[*ast.SelectorExpr]*types.Selection), } - typeparams.InitInstanceInfo(lpkg.TypesInfo) + versions.InitFileVersions(lpkg.TypesInfo) lpkg.TypesSizes = ld.sizes importer := importerFunc(func(path string) (*types.Package, error) { @@ -1043,10 +1205,10 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial, Error: appendError, - Sizes: ld.sizes, + Sizes: ld.sizes, // may be nil } if lpkg.Module != nil && lpkg.Module.GoVersion != "" { - typesinternal.SetGoVersion(tc, "go"+lpkg.Module.GoVersion) + tc.GoVersion = "go" + lpkg.Module.GoVersion } if (ld.Mode & typecheckCgo) != 0 { if !typesinternal.SetUsesCgo(tc) { @@ -1057,10 +1219,24 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { return } } - types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) + typErr := types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) lpkg.importErrors = nil // no longer needed + // In go/types go1.21 and go1.22, Checker.Files failed fast with a + // a "too new" error, without calling tc.Error and without + // proceeding to type-check the package (#66525). + // We rely on the runtimeVersion error to give the suggested remedy. + if typErr != nil && len(lpkg.Errors) == 0 && len(lpkg.Syntax) > 0 { + if msg := typErr.Error(); strings.HasPrefix(msg, "package requires newer Go version") { + appendError(types.Error{ + Fset: ld.Fset, + Pos: lpkg.Syntax[0].Package, + Msg: msg, + }) + } + } + // If !Cgo, the type-checker uses FakeImportC mode, so // it doesn't invoke the importer for import "C", // nor report an error for the import, @@ -1082,6 +1258,12 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { } } + // If types.Checker.Files had an error that was unreported, + // make sure to report the unknown error so the package is illTyped. + if typErr != nil && len(lpkg.Errors) == 0 { + appendError(typErr) + } + // Record accumulated errors. illTyped := len(lpkg.Errors) > 0 if !illTyped { @@ -1127,7 +1309,7 @@ func (ld *loader) parseFile(filename string) (*ast.File, error) { var err error if src == nil { ioLimit <- true // wait - src, err = ioutil.ReadFile(filename) + src, err = os.ReadFile(filename) <-ioLimit // signal } if err != nil { @@ -1153,11 +1335,6 @@ func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { parsed := make([]*ast.File, n) errors := make([]error, n) for i, file := range filenames { - if ld.Config.Context.Err() != nil { - parsed[i] = nil - errors[i] = ld.Config.Context.Err() - continue - } wg.Add(1) go func(i int, filename string) { parsed[i], errors[i] = ld.parseFile(filename) @@ -1323,6 +1500,10 @@ func impliedLoadMode(loadMode LoadMode) LoadMode { // All these things require knowing the import graph. loadMode |= NeedImports } + if loadMode&NeedTypes != 0 { + // Types require the GoVersion from Module. + loadMode |= NeedModule + } return loadMode } diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go index a1dcc40b72..df14ffd94d 100644 --- a/vendor/golang.org/x/tools/go/packages/visit.go +++ b/vendor/golang.org/x/tools/go/packages/visit.go @@ -49,11 +49,20 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { // PrintErrors returns the number of errors printed. func PrintErrors(pkgs []*Package) int { var n int + errModules := make(map[*Module]bool) Visit(pkgs, nil, func(pkg *Package) { for _, err := range pkg.Errors { fmt.Fprintln(os.Stderr, err) n++ } + + // Print pkg.Module.Error once if present. + mod := pkg.Module + if mod != nil && mod.Error != nil && !errModules[mod] { + errModules[mod] = true + fmt.Fprintln(os.Stderr, mod.Error.Err) + n++ + } }) return n } diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go index fa5834baf7..9ada177758 100644 --- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go +++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go @@ -26,15 +26,15 @@ package objectpath import ( "fmt" "go/types" - "sort" "strconv" "strings" - _ "unsafe" - "golang.org/x/tools/internal/typeparams" + "golang.org/x/tools/internal/aliases" "golang.org/x/tools/internal/typesinternal" ) +// TODO(adonovan): think about generic aliases. + // A Path is an opaque name that identifies a types.Object // relative to its package. Conceptually, the name consists of a // sequence of destructuring operations applied to the package scope @@ -51,7 +51,7 @@ type Path string // // PO package->object Package.Scope.Lookup // OT object->type Object.Type -// TT type->type Type.{Elem,Key,Params,Results,Underlying} [EKPRU] +// TT type->type Type.{Elem,Key,{,{,Recv}Type}Params,Results,Underlying,Rhs} [EKPRUTrCa] // TO type->object Type.{At,Field,Method,Obj} [AFMO] // // All valid paths start with a package and end at an object @@ -63,8 +63,8 @@ type Path string // - The only PO operator is Package.Scope.Lookup, which requires an identifier. // - The only OT operator is Object.Type, // which we encode as '.' because dot cannot appear in an identifier. -// - The TT operators are encoded as [EKPRUTC]; -// one of these (TypeParam) requires an integer operand, +// - The TT operators are encoded as [EKPRUTrCa]; +// two of these ({,Recv}TypeParams) require an integer operand, // which is encoded as a string of decimal digits. // - The TO operators are encoded as [AFMO]; // three of these (At,Field,Method) require an integer operand, @@ -98,19 +98,21 @@ const ( opType = '.' // .Type() (Object) // type->type operators - opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map) - opKey = 'K' // .Key() (Map) - opParams = 'P' // .Params() (Signature) - opResults = 'R' // .Results() (Signature) - opUnderlying = 'U' // .Underlying() (Named) - opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature) - opConstraint = 'C' // .Constraint() (TypeParam) + opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map) + opKey = 'K' // .Key() (Map) + opParams = 'P' // .Params() (Signature) + opResults = 'R' // .Results() (Signature) + opUnderlying = 'U' // .Underlying() (Named) + opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature) + opRecvTypeParam = 'r' // .RecvTypeParams.At(i) (Signature) + opConstraint = 'C' // .Constraint() (TypeParam) + opRhs = 'a' // .Rhs() (Alias) // type->object operators - opAt = 'A' // .At(i) (Tuple) - opField = 'F' // .Field(i) (Struct) - opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored) - opObj = 'O' // .Obj() (Named, TypeParam) + opAt = 'A' // .At(i) (Tuple) + opField = 'F' // .Field(i) (Struct) + opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored) + opObj = 'O' // .Obj() (Named, TypeParam) ) // For is equivalent to new(Encoder).For(obj). @@ -123,20 +125,7 @@ func For(obj types.Object) (Path, error) { // An Encoder amortizes the cost of encoding the paths of multiple objects. // The zero value of an Encoder is ready to use. type Encoder struct { - scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects - namedMethodsMemo map[*types.Named][]*types.Func // memoization of namedMethods() - skipMethodSorting bool -} - -// Expose back doors so that gopls can avoid method sorting, which can dominate -// analysis on certain repositories. -// -// TODO(golang/go#61443): remove this. -func init() { - typesinternal.SkipEncoderMethodSorting = func(enc interface{}) { - enc.(*Encoder).skipMethodSorting = true - } - typesinternal.ObjectpathObject = object + scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects } // For returns the path to an object relative to its package, @@ -239,7 +228,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) { // Reject obviously non-viable cases. switch obj := obj.(type) { case *types.TypeName: - if _, ok := obj.Type().(*typeparams.TypeParam); !ok { + if _, ok := aliases.Unalias(obj.Type()).(*types.TypeParam); !ok { // With the exception of type parameters, only package-level type names // have a path. return "", fmt.Errorf("no path for %v", obj) @@ -291,21 +280,26 @@ func (enc *Encoder) For(obj types.Object) (Path, error) { path = append(path, opType) T := o.Type() + if alias, ok := T.(*aliases.Alias); ok { + if r := findTypeParam(obj, aliases.TypeParams(alias), path, opTypeParam, nil); r != nil { + return Path(r), nil + } + if r := find(obj, aliases.Rhs(alias), append(path, opRhs), nil); r != nil { + return Path(r), nil + } - if tname.IsAlias() { - // type alias + } else if tname.IsAlias() { + // legacy alias if r := find(obj, T, path, nil); r != nil { return Path(r), nil } - } else { - if named, _ := T.(*types.Named); named != nil { - if r := findTypeParam(obj, typeparams.ForNamed(named), path, nil); r != nil { - // generic named type - return Path(r), nil - } - } + + } else if named, ok := T.(*types.Named); ok { // defined (named) type - if r := find(obj, T.Underlying(), append(path, opUnderlying), nil); r != nil { + if r := findTypeParam(obj, named.TypeParams(), path, opTypeParam, nil); r != nil { + return Path(r), nil + } + if r := find(obj, named.Underlying(), append(path, opUnderlying), nil); r != nil { return Path(r), nil } } @@ -326,33 +320,20 @@ func (enc *Encoder) For(obj types.Object) (Path, error) { } // Inspect declared methods of defined types. - if T, ok := o.Type().(*types.Named); ok { + if T, ok := aliases.Unalias(o.Type()).(*types.Named); ok { path = append(path, opType) - if !enc.skipMethodSorting { - // Note that method index here is always with respect - // to canonical ordering of methods, regardless of how - // they appear in the underlying type. - for i, m := range enc.namedMethods(T) { - path2 := appendOpArg(path, opMethod, i) - if m == obj { - return Path(path2), nil // found declared method - } - if r := find(obj, m.Type(), append(path2, opType), nil); r != nil { - return Path(r), nil - } + // The method index here is always with respect + // to the underlying go/types data structures, + // which ultimately derives from source order + // and must be preserved by export data. + for i := 0; i < T.NumMethods(); i++ { + m := T.Method(i) + path2 := appendOpArg(path, opMethod, i) + if m == obj { + return Path(path2), nil // found declared method } - } else { - // This branch must match the logic in the branch above, using go/types - // APIs without sorting. - for i := 0; i < T.NumMethods(); i++ { - m := T.Method(i) - path2 := appendOpArg(path, opMethod, i) - if m == obj { - return Path(path2), nil // found declared method - } - if r := find(obj, m.Type(), append(path2, opType), nil); r != nil { - return Path(r), nil - } + if r := find(obj, m.Type(), append(path2, opType), nil); r != nil { + return Path(r), nil } } } @@ -420,17 +401,12 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) { // of objectpath will only be giving us origin methods, anyway, as referring // to instantiated methods is usually not useful. - if typeparams.OriginMethod(meth) != meth { + if meth.Origin() != meth { return "", false } - recvT := meth.Type().(*types.Signature).Recv().Type() - if ptr, ok := recvT.(*types.Pointer); ok { - recvT = ptr.Elem() - } - - named, ok := recvT.(*types.Named) - if !ok { + _, named := typesinternal.ReceiverNamed(meth.Type().(*types.Signature).Recv()) + if named == nil { return "", false } @@ -448,22 +424,13 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) { path = append(path, name...) path = append(path, opType) - if !enc.skipMethodSorting { - for i, m := range enc.namedMethods(named) { - if m == meth { - path = appendOpArg(path, opMethod, i) - return Path(path), true - } - } - } else { - // This branch must match the logic of the branch above, using go/types - // APIs without sorting. - for i := 0; i < named.NumMethods(); i++ { - m := named.Method(i) - if m == meth { - path = appendOpArg(path, opMethod, i) - return Path(path), true - } + // Method indices are w.r.t. the go/types data structures, + // ultimately deriving from source order, + // which is preserved by export data. + for i := 0; i < named.NumMethods(); i++ { + if named.Method(i) == meth { + path = appendOpArg(path, opMethod, i) + return Path(path), true } } @@ -482,6 +449,8 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) { // nil, it will be allocated as necessary. func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte { switch T := T.(type) { + case *aliases.Alias: + return find(obj, aliases.Unalias(T), path, seen) case *types.Basic, *types.Named: // Named types belonging to pkg were handled already, // so T must belong to another package. No path. @@ -500,7 +469,10 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName] } return find(obj, T.Elem(), append(path, opElem), seen) case *types.Signature: - if r := findTypeParam(obj, typeparams.ForSignature(T), path, seen); r != nil { + if r := findTypeParam(obj, T.RecvTypeParams(), path, opRecvTypeParam, nil); r != nil { + return r + } + if r := findTypeParam(obj, T.TypeParams(), path, opTypeParam, seen); r != nil { return r } if r := find(obj, T.Params(), append(path, opParams), seen); r != nil { @@ -543,7 +515,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName] } } return nil - case *typeparams.TypeParam: + case *types.TypeParam: name := T.Obj() if name == obj { return append(path, opObj) @@ -563,10 +535,10 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName] panic(T) } -func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte { +func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, op byte, seen map[*types.TypeName]bool) []byte { for i := 0; i < list.Len(); i++ { tparam := list.At(i) - path2 := appendOpArg(path, opTypeParam, i) + path2 := appendOpArg(path, op, i) if r := find(obj, tparam, path2, seen); r != nil { return r } @@ -576,12 +548,7 @@ func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte // Object returns the object denoted by path p within the package pkg. func Object(pkg *types.Package, p Path) (types.Object, error) { - return object(pkg, string(p), false) -} - -// Note: the skipMethodSorting parameter must match the value of -// Encoder.skipMethodSorting used during encoding. -func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.Object, error) { + pathstr := string(p) if pathstr == "" { return nil, fmt.Errorf("empty path") } @@ -605,7 +572,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O } // abstraction of *types.{Named,Signature} type hasTypeParams interface { - TypeParams() *typeparams.TypeParamList + TypeParams() *types.TypeParamList } // abstraction of *types.{Named,TypeParam} type hasObj interface { @@ -623,10 +590,10 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O code := suffix[0] suffix = suffix[1:] - // Codes [AFM] have an integer operand. + // Codes [AFMTr] have an integer operand. var index int switch code { - case opAt, opField, opMethod, opTypeParam: + case opAt, opField, opMethod, opTypeParam, opRecvTypeParam: rest := strings.TrimLeft(suffix, "0123456789") numerals := suffix[:len(suffix)-len(rest)] suffix = rest @@ -659,6 +626,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O // Inv: t != nil, obj == nil + t = aliases.Unalias(t) switch code { case opElem: hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map @@ -695,6 +663,16 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O } t = named.Underlying() + case opRhs: + if alias, ok := t.(*aliases.Alias); ok { + t = aliases.Rhs(alias) + } else if false && aliases.Enabled() { + // The Enabled check is too expensive, so for now we + // simply assume that aliases are not enabled. + // TODO(adonovan): replace with "if true {" when go1.24 is assured. + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t) + } + case opTypeParam: hasTypeParams, ok := t.(hasTypeParams) // Named, Signature if !ok { @@ -706,8 +684,19 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O } t = tparams.At(index) + case opRecvTypeParam: + sig, ok := t.(*types.Signature) // Signature + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) + } + rtparams := sig.RecvTypeParams() + if n := rtparams.Len(); index >= n { + return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) + } + t = rtparams.At(index) + case opConstraint: - tparam, ok := t.(*typeparams.TypeParam) + tparam, ok := t.(*types.TypeParam) if !ok { return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t) } @@ -747,12 +736,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O if index >= t.NumMethods() { return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) } - if skipMethodSorting { - obj = t.Method(index) - } else { - methods := namedMethods(t) // (unmemoized) - obj = methods[index] // Id-ordered - } + obj = t.Method(index) default: return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t) @@ -772,6 +756,10 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O } } + if obj == nil { + panic(p) // path does not end in an object-valued operator + } + if obj.Pkg() != pkg { return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj) } @@ -779,33 +767,6 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O return obj, nil // success } -// namedMethods returns the methods of a Named type in ascending Id order. -func namedMethods(named *types.Named) []*types.Func { - methods := make([]*types.Func, named.NumMethods()) - for i := range methods { - methods[i] = named.Method(i) - } - sort.Slice(methods, func(i, j int) bool { - return methods[i].Id() < methods[j].Id() - }) - return methods -} - -// namedMethods is a memoization of the namedMethods function. Callers must not modify the result. -func (enc *Encoder) namedMethods(named *types.Named) []*types.Func { - m := enc.namedMethodsMemo - if m == nil { - m = make(map[*types.Named][]*types.Func) - enc.namedMethodsMemo = m - } - methods, ok := m[named] - if !ok { - methods = namedMethods(named) // allocates and sorts - m[named] = methods - } - return methods -} - // scopeObjects is a memoization of scope objects. // Callers must not modify the result. func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object { diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases.go b/vendor/golang.org/x/tools/internal/aliases/aliases.go new file mode 100644 index 0000000000..f7798e3354 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/aliases/aliases.go @@ -0,0 +1,38 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package aliases + +import ( + "go/token" + "go/types" +) + +// Package aliases defines backward compatible shims +// for the types.Alias type representation added in 1.22. +// This defines placeholders for x/tools until 1.26. + +// NewAlias creates a new TypeName in Package pkg that +// is an alias for the type rhs. +// +// The enabled parameter determines whether the resulting [TypeName]'s +// type is an [types.Alias]. Its value must be the result of a call to +// [Enabled], which computes the effective value of +// GODEBUG=gotypesalias=... by invoking the type checker. The Enabled +// function is expensive and should be called once per task (e.g. +// package import), not once per call to NewAlias. +// +// Precondition: enabled || len(tparams)==0. +// If materialized aliases are disabled, there must not be any type parameters. +func NewAlias(enabled bool, pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName { + if enabled { + tname := types.NewTypeName(pos, pkg, name, nil) + newAlias(tname, rhs, tparams) + return tname + } + if len(tparams) > 0 { + panic("cannot create an alias with type parameters when gotypesalias is not enabled") + } + return types.NewTypeName(pos, pkg, name, rhs) +} diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go b/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go new file mode 100644 index 0000000000..a775fcc4be --- /dev/null +++ b/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go @@ -0,0 +1,37 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.22 +// +build !go1.22 + +package aliases + +import ( + "go/types" +) + +// Alias is a placeholder for a go/types.Alias for <=1.21. +// It will never be created by go/types. +type Alias struct{} + +func (*Alias) String() string { panic("unreachable") } +func (*Alias) Underlying() types.Type { panic("unreachable") } +func (*Alias) Obj() *types.TypeName { panic("unreachable") } +func Rhs(alias *Alias) types.Type { panic("unreachable") } +func TypeParams(alias *Alias) *types.TypeParamList { panic("unreachable") } +func SetTypeParams(alias *Alias, tparams []*types.TypeParam) { panic("unreachable") } +func TypeArgs(alias *Alias) *types.TypeList { panic("unreachable") } +func Origin(alias *Alias) *Alias { panic("unreachable") } + +// Unalias returns the type t for go <=1.21. +func Unalias(t types.Type) types.Type { return t } + +func newAlias(name *types.TypeName, rhs types.Type, tparams []*types.TypeParam) *Alias { + panic("unreachable") +} + +// Enabled reports whether [NewAlias] should create [types.Alias] types. +// +// Before go1.22, this function always returns false. +func Enabled() bool { return false } diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go b/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go new file mode 100644 index 0000000000..31c159e42e --- /dev/null +++ b/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go @@ -0,0 +1,98 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.22 +// +build go1.22 + +package aliases + +import ( + "go/ast" + "go/parser" + "go/token" + "go/types" +) + +// Alias is an alias of types.Alias. +type Alias = types.Alias + +// Rhs returns the type on the right-hand side of the alias declaration. +func Rhs(alias *Alias) types.Type { + if alias, ok := any(alias).(interface{ Rhs() types.Type }); ok { + return alias.Rhs() // go1.23+ + } + + // go1.22's Alias didn't have the Rhs method, + // so Unalias is the best we can do. + return Unalias(alias) +} + +// TypeParams returns the type parameter list of the alias. +func TypeParams(alias *Alias) *types.TypeParamList { + if alias, ok := any(alias).(interface{ TypeParams() *types.TypeParamList }); ok { + return alias.TypeParams() // go1.23+ + } + return nil +} + +// SetTypeParams sets the type parameters of the alias type. +func SetTypeParams(alias *Alias, tparams []*types.TypeParam) { + if alias, ok := any(alias).(interface { + SetTypeParams(tparams []*types.TypeParam) + }); ok { + alias.SetTypeParams(tparams) // go1.23+ + } else if len(tparams) > 0 { + panic("cannot set type parameters of an Alias type in go1.22") + } +} + +// TypeArgs returns the type arguments used to instantiate the Alias type. +func TypeArgs(alias *Alias) *types.TypeList { + if alias, ok := any(alias).(interface{ TypeArgs() *types.TypeList }); ok { + return alias.TypeArgs() // go1.23+ + } + return nil // empty (go1.22) +} + +// Origin returns the generic Alias type of which alias is an instance. +// If alias is not an instance of a generic alias, Origin returns alias. +func Origin(alias *Alias) *Alias { + if alias, ok := any(alias).(interface{ Origin() *types.Alias }); ok { + return alias.Origin() // go1.23+ + } + return alias // not an instance of a generic alias (go1.22) +} + +// Unalias is a wrapper of types.Unalias. +func Unalias(t types.Type) types.Type { return types.Unalias(t) } + +// newAlias is an internal alias around types.NewAlias. +// Direct usage is discouraged as the moment. +// Try to use NewAlias instead. +func newAlias(tname *types.TypeName, rhs types.Type, tparams []*types.TypeParam) *Alias { + a := types.NewAlias(tname, rhs) + SetTypeParams(a, tparams) + return a +} + +// Enabled reports whether [NewAlias] should create [types.Alias] types. +// +// This function is expensive! Call it sparingly. +func Enabled() bool { + // The only reliable way to compute the answer is to invoke go/types. + // We don't parse the GODEBUG environment variable, because + // (a) it's tricky to do so in a manner that is consistent + // with the godebug package; in particular, a simple + // substring check is not good enough. The value is a + // rightmost-wins list of options. But more importantly: + // (b) it is impossible to detect changes to the effective + // setting caused by os.Setenv("GODEBUG"), as happens in + // many tests. Therefore any attempt to cache the result + // is just incorrect. + fset := token.NewFileSet() + f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", 0) + pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil) + _, enabled := pkg.Scope().Lookup("A").Type().(*types.Alias) + return enabled +} diff --git a/vendor/golang.org/x/tools/internal/event/keys/util.go b/vendor/golang.org/x/tools/internal/event/keys/util.go new file mode 100644 index 0000000000..c0e8e731c9 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/keys/util.go @@ -0,0 +1,21 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package keys + +import ( + "sort" + "strings" +) + +// Join returns a canonical join of the keys in S: +// a sorted comma-separated string list. +func Join[S ~[]T, T ~string](s S) string { + strs := make([]string, 0, len(s)) + for _, v := range s { + strs = append(strs, string(v)) + } + sort.Strings(strs) + return strings.Join(strs, ",") +} diff --git a/vendor/golang.org/x/tools/internal/event/tag/tag.go b/vendor/golang.org/x/tools/internal/event/tag/tag.go deleted file mode 100644 index 581b26c204..0000000000 --- a/vendor/golang.org/x/tools/internal/event/tag/tag.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package tag provides the labels used for telemetry throughout gopls. -package tag - -import ( - "golang.org/x/tools/internal/event/keys" -) - -var ( - // create the label keys we use - Method = keys.NewString("method", "") - StatusCode = keys.NewString("status.code", "") - StatusMessage = keys.NewString("status.message", "") - RPCID = keys.NewString("id", "") - RPCDirection = keys.NewString("direction", "") - File = keys.NewString("file", "") - Directory = keys.New("directory", "") - URI = keys.New("URI", "") - Package = keys.NewString("package", "") // sorted comma-separated list of Package IDs - PackagePath = keys.NewString("package_path", "") - Query = keys.New("query", "") - Snapshot = keys.NewUInt64("snapshot", "") - Operation = keys.NewString("operation", "") - - Position = keys.New("position", "") - Category = keys.NewString("category", "") - PackageCount = keys.NewInt("packages", "") - Files = keys.New("files", "") - Port = keys.NewInt("port", "") - Type = keys.New("type", "") - HoverKind = keys.NewString("hoverkind", "") - - NewServer = keys.NewString("new_server", "A new server was added") - EndServer = keys.NewString("end_server", "A server was shut down") - - ServerID = keys.NewString("server", "The server ID an event is related to") - Logfile = keys.NewString("logfile", "") - DebugAddress = keys.NewString("debug_address", "") - GoplsPath = keys.NewString("gopls_path", "") - ClientID = keys.NewString("client_id", "") - - Level = keys.NewInt("level", "The logging level") -) - -var ( - // create the stats we measure - Started = keys.NewInt64("started", "Count of started RPCs.") - ReceivedBytes = keys.NewInt64("received_bytes", "Bytes received.") //, unit.Bytes) - SentBytes = keys.NewInt64("sent_bytes", "Bytes sent.") //, unit.Bytes) - Latency = keys.NewFloat64("latency_ms", "Elapsed time in milliseconds") //, unit.Milliseconds) -) - -const ( - Inbound = "in" - Outbound = "out" -) diff --git a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go index b1223713b9..39df91124a 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go @@ -29,7 +29,6 @@ import ( "go/token" "go/types" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -221,7 +220,7 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func switch hdr { case "$$B\n": var data []byte - data, err = ioutil.ReadAll(buf) + data, err = io.ReadAll(buf) if err != nil { break } @@ -260,13 +259,6 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func return } -func deref(typ types.Type) types.Type { - if p, _ := typ.(*types.Pointer); p != nil { - return p.Elem() - } - return typ -} - type byPath []*types.Package func (a byPath) Len() int { return len(a) } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go index 6103dd7102..5f283281a2 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go @@ -2,9 +2,227 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Indexed binary package export. -// This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go; -// see that file for specification of the format. +// Indexed package export. +// +// The indexed export data format is an evolution of the previous +// binary export data format. Its chief contribution is introducing an +// index table, which allows efficient random access of individual +// declarations and inline function bodies. In turn, this allows +// avoiding unnecessary work for compilation units that import large +// packages. +// +// +// The top-level data format is structured as: +// +// Header struct { +// Tag byte // 'i' +// Version uvarint +// StringSize uvarint +// DataSize uvarint +// } +// +// Strings [StringSize]byte +// Data [DataSize]byte +// +// MainIndex []struct{ +// PkgPath stringOff +// PkgName stringOff +// PkgHeight uvarint +// +// Decls []struct{ +// Name stringOff +// Offset declOff +// } +// } +// +// Fingerprint [8]byte +// +// uvarint means a uint64 written out using uvarint encoding. +// +// []T means a uvarint followed by that many T objects. In other +// words: +// +// Len uvarint +// Elems [Len]T +// +// stringOff means a uvarint that indicates an offset within the +// Strings section. At that offset is another uvarint, followed by +// that many bytes, which form the string value. +// +// declOff means a uvarint that indicates an offset within the Data +// section where the associated declaration can be found. +// +// +// There are five kinds of declarations, distinguished by their first +// byte: +// +// type Var struct { +// Tag byte // 'V' +// Pos Pos +// Type typeOff +// } +// +// type Func struct { +// Tag byte // 'F' or 'G' +// Pos Pos +// TypeParams []typeOff // only present if Tag == 'G' +// Signature Signature +// } +// +// type Const struct { +// Tag byte // 'C' +// Pos Pos +// Value Value +// } +// +// type Type struct { +// Tag byte // 'T' or 'U' +// Pos Pos +// TypeParams []typeOff // only present if Tag == 'U' +// Underlying typeOff +// +// Methods []struct{ // omitted if Underlying is an interface type +// Pos Pos +// Name stringOff +// Recv Param +// Signature Signature +// } +// } +// +// type Alias struct { +// Tag byte // 'A' or 'B' +// Pos Pos +// TypeParams []typeOff // only present if Tag == 'B' +// Type typeOff +// } +// +// // "Automatic" declaration of each typeparam +// type TypeParam struct { +// Tag byte // 'P' +// Pos Pos +// Implicit bool +// Constraint typeOff +// } +// +// typeOff means a uvarint that either indicates a predeclared type, +// or an offset into the Data section. If the uvarint is less than +// predeclReserved, then it indicates the index into the predeclared +// types list (see predeclared in bexport.go for order). Otherwise, +// subtracting predeclReserved yields the offset of a type descriptor. +// +// Value means a type, kind, and type-specific value. See +// (*exportWriter).value for details. +// +// +// There are twelve kinds of type descriptors, distinguished by an itag: +// +// type DefinedType struct { +// Tag itag // definedType +// Name stringOff +// PkgPath stringOff +// } +// +// type PointerType struct { +// Tag itag // pointerType +// Elem typeOff +// } +// +// type SliceType struct { +// Tag itag // sliceType +// Elem typeOff +// } +// +// type ArrayType struct { +// Tag itag // arrayType +// Len uint64 +// Elem typeOff +// } +// +// type ChanType struct { +// Tag itag // chanType +// Dir uint64 // 1 RecvOnly; 2 SendOnly; 3 SendRecv +// Elem typeOff +// } +// +// type MapType struct { +// Tag itag // mapType +// Key typeOff +// Elem typeOff +// } +// +// type FuncType struct { +// Tag itag // signatureType +// PkgPath stringOff +// Signature Signature +// } +// +// type StructType struct { +// Tag itag // structType +// PkgPath stringOff +// Fields []struct { +// Pos Pos +// Name stringOff +// Type typeOff +// Embedded bool +// Note stringOff +// } +// } +// +// type InterfaceType struct { +// Tag itag // interfaceType +// PkgPath stringOff +// Embeddeds []struct { +// Pos Pos +// Type typeOff +// } +// Methods []struct { +// Pos Pos +// Name stringOff +// Signature Signature +// } +// } +// +// // Reference to a type param declaration +// type TypeParamType struct { +// Tag itag // typeParamType +// Name stringOff +// PkgPath stringOff +// } +// +// // Instantiation of a generic type (like List[T2] or List[int]) +// type InstanceType struct { +// Tag itag // instanceType +// Pos pos +// TypeArgs []typeOff +// BaseType typeOff +// } +// +// type UnionType struct { +// Tag itag // interfaceType +// Terms []struct { +// tilde bool +// Type typeOff +// } +// } +// +// +// +// type Signature struct { +// Params []Param +// Results []Param +// Variadic bool // omitted if Results is empty +// } +// +// type Param struct { +// Pos Pos +// Name stringOff +// Type typOff +// } +// +// +// Pos encodes a file:line:column triple, incorporating a simple delta +// encoding scheme within a data object. See exportWriter.pos for +// details. package gcimporter @@ -23,8 +241,8 @@ import ( "strings" "golang.org/x/tools/go/types/objectpath" + "golang.org/x/tools/internal/aliases" "golang.org/x/tools/internal/tokeninternal" - "golang.org/x/tools/internal/typeparams" ) // IExportShallow encodes "shallow" export data for the specified package. @@ -464,7 +682,7 @@ func (p *iexporter) doDecl(obj types.Object) { switch obj := obj.(type) { case *types.Var: - w.tag('V') + w.tag(varTag) w.pos(obj.Pos()) w.typ(obj.Type(), obj.Pkg()) @@ -481,10 +699,10 @@ func (p *iexporter) doDecl(obj types.Object) { } // Function. - if typeparams.ForSignature(sig).Len() == 0 { - w.tag('F') + if sig.TypeParams().Len() == 0 { + w.tag(funcTag) } else { - w.tag('G') + w.tag(genericFuncTag) } w.pos(obj.Pos()) // The tparam list of the function type is the declaration of the type @@ -494,27 +712,27 @@ func (p *iexporter) doDecl(obj types.Object) { // // While importing the type parameters, tparamList computes and records // their export name, so that it can be later used when writing the index. - if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 { + if tparams := sig.TypeParams(); tparams.Len() > 0 { w.tparamList(obj.Name(), tparams, obj.Pkg()) } w.signature(sig) case *types.Const: - w.tag('C') + w.tag(constTag) w.pos(obj.Pos()) w.value(obj.Type(), obj.Val()) case *types.TypeName: t := obj.Type() - if tparam, ok := t.(*typeparams.TypeParam); ok { - w.tag('P') + if tparam, ok := aliases.Unalias(t).(*types.TypeParam); ok { + w.tag(typeParamTag) w.pos(obj.Pos()) constraint := tparam.Constraint() if p.version >= iexportVersionGo1_18 { implicit := false - if iface, _ := constraint.(*types.Interface); iface != nil { - implicit = typeparams.IsImplicit(iface) + if iface, _ := aliases.Unalias(constraint).(*types.Interface); iface != nil { + implicit = iface.IsImplicit() } w.bool(implicit) } @@ -523,8 +741,26 @@ func (p *iexporter) doDecl(obj types.Object) { } if obj.IsAlias() { - w.tag('A') + alias, materialized := t.(*aliases.Alias) // may fail when aliases are not enabled + + var tparams *types.TypeParamList + if materialized { + tparams = aliases.TypeParams(alias) + } + if tparams.Len() == 0 { + w.tag(aliasTag) + } else { + w.tag(genericAliasTag) + } w.pos(obj.Pos()) + if tparams.Len() > 0 { + w.tparamList(obj.Name(), tparams, obj.Pkg()) + } + if materialized { + // Preserve materialized aliases, + // even of non-exported types. + t = aliases.Rhs(alias) + } w.typ(t, obj.Pkg()) break } @@ -535,20 +771,20 @@ func (p *iexporter) doDecl(obj types.Object) { panic(internalErrorf("%s is not a defined type", t)) } - if typeparams.ForNamed(named).Len() == 0 { - w.tag('T') + if named.TypeParams().Len() == 0 { + w.tag(typeTag) } else { - w.tag('U') + w.tag(genericTypeTag) } w.pos(obj.Pos()) - if typeparams.ForNamed(named).Len() > 0 { + if named.TypeParams().Len() > 0 { // While importing the type parameters, tparamList computes and records // their export name, so that it can be later used when writing the index. - w.tparamList(obj.Name(), typeparams.ForNamed(named), obj.Pkg()) + w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg()) } - underlying := obj.Type().Underlying() + underlying := named.Underlying() w.typ(underlying, obj.Pkg()) if types.IsInterface(t) { @@ -565,7 +801,7 @@ func (p *iexporter) doDecl(obj types.Object) { // Receiver type parameters are type arguments of the receiver type, so // their name must be qualified before exporting recv. - if rparams := typeparams.RecvTypeParams(sig); rparams.Len() > 0 { + if rparams := sig.RecvTypeParams(); rparams.Len() > 0 { prefix := obj.Name() + "." + m.Name() for i := 0; i < rparams.Len(); i++ { rparam := rparams.At(i) @@ -739,20 +975,31 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { }() } switch t := t.(type) { + case *aliases.Alias: + if targs := aliases.TypeArgs(t); targs.Len() > 0 { + w.startType(instanceType) + w.pos(t.Obj().Pos()) + w.typeList(targs, pkg) + w.typ(aliases.Origin(t), pkg) + return + } + w.startType(aliasType) + w.qualifiedType(t.Obj()) + case *types.Named: - if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 { + if targs := t.TypeArgs(); targs.Len() > 0 { w.startType(instanceType) // TODO(rfindley): investigate if this position is correct, and if it // matters. w.pos(t.Obj().Pos()) w.typeList(targs, pkg) - w.typ(typeparams.NamedTypeOrigin(t), pkg) + w.typ(t.Origin(), pkg) return } w.startType(definedType) w.qualifiedType(t.Obj()) - case *typeparams.TypeParam: + case *types.TypeParam: w.startType(typeParamType) w.qualifiedType(t.Obj()) @@ -844,7 +1091,7 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { for i := 0; i < n; i++ { ft := t.EmbeddedType(i) tPkg := pkg - if named, _ := ft.(*types.Named); named != nil { + if named, _ := aliases.Unalias(ft).(*types.Named); named != nil { w.pos(named.Obj().Pos()) } else { w.pos(token.NoPos) @@ -868,7 +1115,7 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { w.signature(sig) } - case *typeparams.Union: + case *types.Union: w.startType(unionType) nt := t.Len() w.uint64(uint64(nt)) @@ -948,14 +1195,14 @@ func (w *exportWriter) signature(sig *types.Signature) { } } -func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) { +func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) { w.uint64(uint64(ts.Len())) for i := 0; i < ts.Len(); i++ { w.typ(ts.At(i), pkg) } } -func (w *exportWriter) tparamList(prefix string, list *typeparams.TypeParamList, pkg *types.Package) { +func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) { ll := uint64(list.Len()) w.uint64(ll) for i := 0; i < list.Len(); i++ { @@ -973,7 +1220,7 @@ const blankMarker = "$" // differs from its actual object name: it is prefixed with a qualifier, and // blank type parameter names are disambiguated by their index in the type // parameter list. -func tparamExportName(prefix string, tparam *typeparams.TypeParam) string { +func tparamExportName(prefix string, tparam *types.TypeParam) string { assert(prefix != "") name := tparam.Obj().Name() if name == "_" { diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go index 8e64cf644f..ed2d562959 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Indexed package import. -// See cmd/compile/internal/gc/iexport.go for the export data format. +// See iexport.go for the export data format. // This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go. @@ -22,7 +22,8 @@ import ( "strings" "golang.org/x/tools/go/types/objectpath" - "golang.org/x/tools/internal/typeparams" + "golang.org/x/tools/internal/aliases" + "golang.org/x/tools/internal/typesinternal" ) type intReader struct { @@ -79,6 +80,20 @@ const ( typeParamType instanceType unionType + aliasType +) + +// Object tags +const ( + varTag = 'V' + funcTag = 'F' + genericFuncTag = 'G' + constTag = 'C' + aliasTag = 'A' + genericAliasTag = 'B' + typeParamTag = 'P' + typeTag = 'T' + genericTypeTag = 'U' ) // IImportData imports a package from the serialized package data @@ -195,6 +210,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte p := iimporter{ version: int(version), ipath: path, + aliases: aliases.Enabled(), shallow: shallow, reportf: reportf, @@ -225,6 +241,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte // Gather the relevant packages from the manifest. items := make([]GetPackagesItem, r.uint64()) + uniquePkgPaths := make(map[string]bool) for i := range items { pkgPathOff := r.uint64() pkgPath := p.stringAt(pkgPathOff) @@ -249,6 +266,12 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte } items[i].nameIndex = nameIndex + + uniquePkgPaths[pkgPath] = true + } + // Debugging #63822; hypothesis: there are duplicate PkgPaths. + if len(uniquePkgPaths) != len(items) { + reportf("found duplicate PkgPaths while reading export data manifest: %v", items) } // Request packages all at once from the client, @@ -316,12 +339,12 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte } // SetConstraint can't be called if the constraint type is not yet complete. - // When type params are created in the 'P' case of (*importReader).obj(), + // When type params are created in the typeParamTag case of (*importReader).obj(), // the associated constraint type may not be complete due to recursion. // Therefore, we defer calling SetConstraint there, and call it here instead // after all types are complete. for _, d := range p.later { - typeparams.SetTypeParamConstraint(d.t, d.constraint) + d.t.SetConstraint(d.constraint) } for _, typ := range p.interfaceList { @@ -339,7 +362,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte } type setConstraintArgs struct { - t *typeparams.TypeParam + t *types.TypeParam constraint types.Type } @@ -347,6 +370,7 @@ type iimporter struct { version int ipath string + aliases bool shallow bool reportf ReportFunc // if non-nil, used to report bugs @@ -516,7 +540,7 @@ func canReuse(def *types.Named, rhs types.Type) bool { if def == nil { return true } - iface, _ := rhs.(*types.Interface) + iface, _ := aliases.Unalias(rhs).(*types.Interface) if iface == nil { return true } @@ -538,25 +562,29 @@ func (r *importReader) obj(name string) { pos := r.pos() switch tag { - case 'A': + case aliasTag, genericAliasTag: + var tparams []*types.TypeParam + if tag == genericAliasTag { + tparams = r.tparamList() + } typ := r.typ() + obj := aliases.NewAlias(r.p.aliases, pos, r.currPkg, name, typ, tparams) + r.declare(obj) - r.declare(types.NewTypeName(pos, r.currPkg, name, typ)) - - case 'C': + case constTag: typ, val := r.value() r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) - case 'F', 'G': - var tparams []*typeparams.TypeParam - if tag == 'G' { + case funcTag, genericFuncTag: + var tparams []*types.TypeParam + if tag == genericFuncTag { tparams = r.tparamList() } sig := r.signature(nil, nil, tparams) r.declare(types.NewFunc(pos, r.currPkg, name, sig)) - case 'T', 'U': + case typeTag, genericTypeTag: // Types can be recursive. We need to setup a stub // declaration before recursing. obj := types.NewTypeName(pos, r.currPkg, name, nil) @@ -564,9 +592,9 @@ func (r *importReader) obj(name string) { // Declare obj before calling r.tparamList, so the new type name is recognized // if used in the constraint of one of its own typeparams (see #48280). r.declare(obj) - if tag == 'U' { + if tag == genericTypeTag { tparams := r.tparamList() - typeparams.SetForNamed(named, tparams) + named.SetTypeParams(tparams) } underlying := r.p.typAt(r.uint64(), named).Underlying() @@ -581,14 +609,13 @@ func (r *importReader) obj(name string) { // If the receiver has any targs, set those as the // rparams of the method (since those are the // typeparams being used in the method sig/body). - base := baseType(recv.Type()) - assert(base != nil) - targs := typeparams.NamedTypeArgs(base) - var rparams []*typeparams.TypeParam + _, recvNamed := typesinternal.ReceiverNamed(recv) + targs := recvNamed.TypeArgs() + var rparams []*types.TypeParam if targs.Len() > 0 { - rparams = make([]*typeparams.TypeParam, targs.Len()) + rparams = make([]*types.TypeParam, targs.Len()) for i := range rparams { - rparams[i] = targs.At(i).(*typeparams.TypeParam) + rparams[i] = aliases.Unalias(targs.At(i)).(*types.TypeParam) } } msig := r.signature(recv, rparams, nil) @@ -597,7 +624,7 @@ func (r *importReader) obj(name string) { } } - case 'P': + case typeParamTag: // We need to "declare" a typeparam in order to have a name that // can be referenced recursively (if needed) in the type param's // bound. @@ -606,7 +633,7 @@ func (r *importReader) obj(name string) { } name0 := tparamName(name) tn := types.NewTypeName(pos, r.currPkg, name0, nil) - t := typeparams.NewTypeParam(tn, nil) + t := types.NewTypeParam(tn, nil) // To handle recursive references to the typeparam within its // bound, save the partial type in tparamIndex before reading the bounds. @@ -618,11 +645,11 @@ func (r *importReader) obj(name string) { } constraint := r.typ() if implicit { - iface, _ := constraint.(*types.Interface) + iface, _ := aliases.Unalias(constraint).(*types.Interface) if iface == nil { errorf("non-interface constraint marked implicit") } - typeparams.MarkImplicit(iface) + iface.MarkImplicit() } // The constraint type may not be complete, if we // are in the middle of a type recursion involving type @@ -630,7 +657,7 @@ func (r *importReader) obj(name string) { // completely set up all types in ImportData. r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) - case 'V': + case varTag: typ := r.typ() r.declare(types.NewVar(pos, r.currPkg, name, typ)) @@ -825,7 +852,7 @@ func (r *importReader) typ() types.Type { } func isInterface(t types.Type) bool { - _, ok := t.(*types.Interface) + _, ok := aliases.Unalias(t).(*types.Interface) return ok } @@ -835,7 +862,7 @@ func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } func (r *importReader) doType(base *types.Named) (res types.Type) { k := r.kind() if debug { - r.p.trace("importing type %d (base: %s)", k, base) + r.p.trace("importing type %d (base: %v)", k, base) r.p.indent++ defer func() { r.p.indent-- @@ -847,7 +874,7 @@ func (r *importReader) doType(base *types.Named) (res types.Type) { errorf("unexpected kind tag in %q: %v", r.p.ipath, k) return nil - case definedType: + case aliasType, definedType: pkg, name := r.qualifiedIdent() r.p.doDecl(pkg, name) return pkg.Scope().Lookup(name).(*types.TypeName).Type() @@ -966,7 +993,7 @@ func (r *importReader) doType(base *types.Named) (res types.Type) { // The imported instantiated type doesn't include any methods, so // we must always use the methods of the base (orig) type. // TODO provide a non-nil *Environment - t, _ := typeparams.Instantiate(nil, baseType, targs, false) + t, _ := types.Instantiate(nil, baseType, targs, false) // Workaround for golang/go#61561. See the doc for instanceList for details. r.p.instanceList = append(r.p.instanceList, t) @@ -976,11 +1003,11 @@ func (r *importReader) doType(base *types.Named) (res types.Type) { if r.p.version < iexportVersionGenerics { errorf("unexpected instantiation type") } - terms := make([]*typeparams.Term, r.uint64()) + terms := make([]*types.Term, r.uint64()) for i := range terms { - terms[i] = typeparams.NewTerm(r.bool(), r.typ()) + terms[i] = types.NewTerm(r.bool(), r.typ()) } - return typeparams.NewUnion(terms) + return types.NewUnion(terms) } } @@ -1008,23 +1035,23 @@ func (r *importReader) objectPathObject() types.Object { return obj } -func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature { +func (r *importReader) signature(recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature { params := r.paramList() results := r.paramList() variadic := params.Len() > 0 && r.bool() - return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic) + return types.NewSignatureType(recv, rparams, tparams, params, results, variadic) } -func (r *importReader) tparamList() []*typeparams.TypeParam { +func (r *importReader) tparamList() []*types.TypeParam { n := r.uint64() if n == 0 { return nil } - xs := make([]*typeparams.TypeParam, n) + xs := make([]*types.TypeParam, n) for i := range xs { // Note: the standard library importer is tolerant of nil types here, // though would panic in SetTypeParams. - xs[i] = r.typ().(*typeparams.TypeParam) + xs[i] = aliases.Unalias(r.typ()).(*types.TypeParam) } return xs } @@ -1071,13 +1098,3 @@ func (r *importReader) byte() byte { } return x } - -func baseType(typ types.Type) *types.Named { - // pointer receivers are never types.Named types - if p, _ := typ.(*types.Pointer); p != nil { - typ = p.Elem() - } - // receiver base types are always (possibly generic) types.Named types - n, _ := typ.(*types.Named) - return n -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support_go117.go b/vendor/golang.org/x/tools/internal/gcimporter/support_go117.go deleted file mode 100644 index d892273efb..0000000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/support_go117.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.18 -// +build !go1.18 - -package gcimporter - -import "go/types" - -const iexportVersion = iexportVersionGo1_11 - -func additionalPredeclared() []types.Type { - return nil -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go b/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go index edbe6ea704..0cd3b91b65 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package gcimporter import "go/types" diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go index 286bf44548..38b624cada 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !(go1.18 && goexperiment.unified) -// +build !go1.18 !goexperiment.unified +//go:build !goexperiment.unified +// +build !goexperiment.unified package gcimporter diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go index b5d69ffbe6..b5118d0b3a 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 && goexperiment.unified -// +build go1.18,goexperiment.unified +//go:build goexperiment.unified +// +build goexperiment.unified package gcimporter diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go deleted file mode 100644 index 8eb20729c2..0000000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.18 -// +build !go1.18 - -package gcimporter - -import ( - "fmt" - "go/token" - "go/types" -) - -func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { - err = fmt.Errorf("go/tools compiled with a Go version earlier than 1.18 cannot read unified IR export data") - return -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go index b977435f62..f0742f5404 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go @@ -4,9 +4,6 @@ // Derived from go/internal/gcimporter/ureader.go -//go:build go1.18 -// +build go1.18 - package gcimporter import ( @@ -16,6 +13,7 @@ import ( "sort" "strings" + "golang.org/x/tools/internal/aliases" "golang.org/x/tools/internal/pkgbits" ) @@ -28,6 +26,7 @@ type pkgReader struct { ctxt *types.Context imports map[string]*types.Package // previously imported packages, indexed by path + aliases bool // create types.Alias nodes // lazily initialized arrays corresponding to the unified IR // PosBase, Pkg, and Type sections, respectively. @@ -53,8 +52,7 @@ func (pr *pkgReader) later(fn func()) { // See cmd/compile/internal/noder.derivedInfo. type derivedInfo struct { - idx pkgbits.Index - needed bool + idx pkgbits.Index } // See cmd/compile/internal/noder.typeInfo. @@ -101,6 +99,7 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st ctxt: ctxt, imports: imports, + aliases: aliases.Enabled(), posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), @@ -110,13 +109,17 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) pkg := r.pkg() - r.Bool() // has init + if r.Version().Has(pkgbits.HasInit) { + r.Bool() + } for i, n := 0, r.Len(); i < n; i++ { // As if r.obj(), but avoiding the Scope.Lookup call, // to avoid eager loading of imports. r.Sync(pkgbits.SyncObject) - assert(!r.Bool()) + if r.Version().Has(pkgbits.DerivedFuncInstance) { + assert(!r.Bool()) + } r.p.objIdx(r.Reloc(pkgbits.RelocObj)) assert(r.Len() == 0) } @@ -165,7 +168,7 @@ type readerDict struct { // tparams is a slice of the constructed TypeParams for the element. tparams []*types.TypeParam - // devived is a slice of types derived from tparams, which may be + // derived is a slice of types derived from tparams, which may be // instantiated while reading the current element. derived []derivedInfo derivedTypes []types.Type // lazily instantiated from derived @@ -471,7 +474,9 @@ func (r *reader) param() *types.Var { func (r *reader) obj() (types.Object, []types.Type) { r.Sync(pkgbits.SyncObject) - assert(!r.Bool()) + if r.Version().Has(pkgbits.DerivedFuncInstance) { + assert(!r.Bool()) + } pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) obj := pkgScope(pkg).Lookup(name) @@ -525,8 +530,12 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { case pkgbits.ObjAlias: pos := r.pos() + var tparams []*types.TypeParam + if r.Version().Has(pkgbits.AliasTypeParamNames) { + tparams = r.typeParamNames() + } typ := r.typ() - declare(types.NewTypeName(pos, objPkg, objName, typ)) + declare(aliases.NewAlias(r.p.aliases, pos, objPkg, objName, typ, tparams)) case pkgbits.ObjConst: pos := r.pos() @@ -553,7 +562,7 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { // If the underlying type is an interface, we need to // duplicate its methods so we can replace the receiver // parameter's type (#49906). - if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 { + if iface, ok := aliases.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 { methods := make([]*types.Func, iface.NumExplicitMethods()) for i := range methods { fn := iface.ExplicitMethod(i) @@ -632,7 +641,10 @@ func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { dict.derived = make([]derivedInfo, r.Len()) dict.derivedTypes = make([]types.Type, len(dict.derived)) for i := range dict.derived { - dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()} + dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.RelocType)} + if r.Version().Has(pkgbits.DerivedInfoNeeded) { + assert(!r.Bool()) + } } pr.retireReader(r) diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go index 53cf66da01..2e59ff8558 100644 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go +++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go @@ -8,11 +8,14 @@ package gocommand import ( "bytes" "context" + "encoding/json" "errors" "fmt" "io" "log" "os" + "os/exec" + "path/filepath" "reflect" "regexp" "runtime" @@ -21,12 +24,9 @@ import ( "sync" "time" - exec "golang.org/x/sys/execabs" - "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/event/keys" "golang.org/x/tools/internal/event/label" - "golang.org/x/tools/internal/event/tag" ) // An Runner will run go command invocations and serialize @@ -56,11 +56,14 @@ func (runner *Runner) initialize() { // 1.14: go: updating go.mod: existing contents have changed since last read var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`) -// verb is an event label for the go command verb. -var verb = keys.NewString("verb", "go command verb") +// event keys for go command invocations +var ( + verb = keys.NewString("verb", "go command verb") + directory = keys.NewString("directory", "") +) func invLabels(inv Invocation) []label.Label { - return []label.Label{verb.Of(inv.Verb), tag.Directory.Of(inv.WorkingDir)} + return []label.Label{verb.Of(inv.Verb), directory.Of(inv.WorkingDir)} } // Run is a convenience wrapper around RunRaw. @@ -85,6 +88,7 @@ func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stde // RunRaw runs the invocation, serializing requests only if they fight over // go.mod changes. +// Postcondition: both error results have same nilness. func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...) defer done() @@ -95,23 +99,24 @@ func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv) // If we encounter a load concurrency error, we need to retry serially. - if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) { - return stdout, stderr, friendlyErr, err + if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) { + event.Error(ctx, "Load concurrency error, will retry serially", err) + + // Run serially by calling runPiped. + stdout.Reset() + stderr.Reset() + friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr) } - event.Error(ctx, "Load concurrency error, will retry serially", err) - // Run serially by calling runPiped. - stdout.Reset() - stderr.Reset() - friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr) return stdout, stderr, friendlyErr, err } +// Postcondition: both error results have same nilness. func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { // Wait for 1 worker to become available. select { case <-ctx.Done(): - return nil, nil, nil, ctx.Err() + return nil, nil, ctx.Err(), ctx.Err() case runner.inFlight <- struct{}{}: defer func() { <-runner.inFlight }() } @@ -121,6 +126,7 @@ func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes return stdout, stderr, friendlyErr, err } +// Postcondition: both error results have same nilness. func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) { // Make sure the runner is always initialized. runner.initialize() @@ -129,7 +135,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde // runPiped commands. select { case <-ctx.Done(): - return nil, ctx.Err() + return ctx.Err(), ctx.Err() case runner.serialized <- struct{}{}: defer func() { <-runner.serialized }() } @@ -139,7 +145,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde for i := 0; i < maxInFlight; i++ { select { case <-ctx.Done(): - return nil, ctx.Err() + return ctx.Err(), ctx.Err() case runner.inFlight <- struct{}{}: // Make sure we always "return" any workers we took. defer func() { <-runner.inFlight }() @@ -156,12 +162,17 @@ type Invocation struct { BuildFlags []string // If ModFlag is set, the go command is invoked with -mod=ModFlag. + // TODO(rfindley): remove, in favor of Args. ModFlag string // If ModFile is set, the go command is invoked with -modfile=ModFile. + // TODO(rfindley): remove, in favor of Args. ModFile string - // If Overlay is set, the go command is invoked with -overlay=Overlay. + // Overlay is the name of the JSON overlay file that describes + // unsaved editor buffers; see [WriteOverlays]. + // If set, the go command is invoked with -overlay=Overlay. + // TODO(rfindley): remove, in favor of Args. Overlay string // If CleanEnv is set, the invocation will run only with the environment @@ -172,6 +183,7 @@ type Invocation struct { Logf func(format string, args ...interface{}) } +// Postcondition: both error results have same nilness. func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) { rawError = i.run(ctx, stdout, stderr) if rawError != nil { @@ -188,12 +200,14 @@ func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io return } -func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { - log := i.Logf - if log == nil { - log = func(string, ...interface{}) {} +// logf logs if i.Logf is non-nil. +func (i *Invocation) logf(format string, args ...any) { + if i.Logf != nil { + i.Logf(format, args...) } +} +func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { goArgs := []string{i.Verb} appendModFile := func() { @@ -247,12 +261,15 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { waitDelay.Set(reflect.ValueOf(30 * time.Second)) } - // On darwin the cwd gets resolved to the real path, which breaks anything that - // expects the working directory to keep the original path, including the + // The cwd gets resolved to the real path. On Darwin, where + // /tmp is a symlink, this breaks anything that expects the + // working directory to keep the original path, including the // go command when dealing with modules. - // The Go stdlib has a special feature where if the cwd and the PWD are the - // same node then it trusts the PWD, so by setting it in the env for the child - // process we fix up all the paths returned by the go command. + // + // os.Getwd has a special feature where if the cwd and the PWD + // are the same node then it trusts the PWD, so by setting it + // in the env for the child process we fix up all the paths + // returned by the go command. if !i.CleanEnv { cmd.Env = os.Environ() } @@ -262,7 +279,12 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { cmd.Dir = i.WorkingDir } - defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now()) + debugStr := cmdDebugStr(cmd) + i.logf("starting %v", debugStr) + start := time.Now() + defer func() { + i.logf("%s for %v", time.Since(start), debugStr) + }() return runCmdContext(ctx, cmd) } @@ -343,6 +365,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) { } } + startTime := time.Now() err = cmd.Start() if stdoutW != nil { // The child process has inherited the pipe file, @@ -369,7 +392,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) { case err := <-resChan: return err case <-timer.C: - HandleHangingGoCommand(cmd.Process) + HandleHangingGoCommand(startTime, cmd) case <-ctx.Done(): } } else { @@ -403,7 +426,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) { return <-resChan } -func HandleHangingGoCommand(proc *os.Process) { +func HandleHangingGoCommand(start time.Time, cmd *exec.Cmd) { switch runtime.GOOS { case "linux", "darwin", "freebsd", "netbsd": fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND @@ -436,7 +459,7 @@ See golang/go#54461 for more details.`) panic(fmt.Sprintf("running %s: %v", listFiles, err)) } } - panic(fmt.Sprintf("detected hanging go command (pid %d): see golang/go#54461 for more details", proc.Pid)) + panic(fmt.Sprintf("detected hanging go command (golang/go#54461); waited %s\n\tcommand:%s\n\tpid:%d", time.Since(start), cmd, cmd.Process.Pid)) } func cmdDebugStr(cmd *exec.Cmd) string { @@ -460,3 +483,73 @@ func cmdDebugStr(cmd *exec.Cmd) string { } return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) } + +// WriteOverlays writes each value in the overlay (see the Overlay +// field of go/packages.Config) to a temporary file and returns the name +// of a JSON file describing the mapping that is suitable for the "go +// list -overlay" flag. +// +// On success, the caller must call the cleanup function exactly once +// when the files are no longer needed. +func WriteOverlays(overlay map[string][]byte) (filename string, cleanup func(), err error) { + // Do nothing if there are no overlays in the config. + if len(overlay) == 0 { + return "", func() {}, nil + } + + dir, err := os.MkdirTemp("", "gocommand-*") + if err != nil { + return "", nil, err + } + + // The caller must clean up this directory, + // unless this function returns an error. + // (The cleanup operand of each return + // statement below is ignored.) + defer func() { + cleanup = func() { + os.RemoveAll(dir) + } + if err != nil { + cleanup() + cleanup = nil + } + }() + + // Write each map entry to a temporary file. + overlays := make(map[string]string) + for k, v := range overlay { + // Use a unique basename for each file (001-foo.go), + // to avoid creating nested directories. + base := fmt.Sprintf("%d-%s", 1+len(overlays), filepath.Base(k)) + filename := filepath.Join(dir, base) + err := os.WriteFile(filename, v, 0666) + if err != nil { + return "", nil, err + } + overlays[k] = filename + } + + // Write the JSON overlay file that maps logical file names to temp files. + // + // OverlayJSON is the format overlay files are expected to be in. + // The Replace map maps from overlaid paths to replacement paths: + // the Go command will forward all reads trying to open + // each overlaid path to its replacement path, or consider the overlaid + // path not to exist if the replacement path is empty. + // + // From golang/go#39958. + type OverlayJSON struct { + Replace map[string]string `json:"replace,omitempty"` + } + b, err := json.Marshal(OverlayJSON{Replace: overlays}) + if err != nil { + return "", nil, err + } + filename = filepath.Join(dir, "overlay.json") + if err := os.WriteFile(filename, b, 0666); err != nil { + return "", nil, err + } + + return filename, nil, nil +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go index 2d3d408c0b..e38d1fb488 100644 --- a/vendor/golang.org/x/tools/internal/gocommand/vendor.go +++ b/vendor/golang.org/x/tools/internal/gocommand/vendor.go @@ -107,3 +107,57 @@ func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*Modul } return mod, lines[4] == "go1.14", nil } + +// WorkspaceVendorEnabled reports whether workspace vendoring is enabled. It takes a *Runner to execute Go commands +// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, +// of which only Verb and Args are modified to run the appropriate Go command. +// Inspired by setDefaultBuildMod in modload/init.go +func WorkspaceVendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, []*ModuleJSON, error) { + inv.Verb = "env" + inv.Args = []string{"GOWORK"} + stdout, err := r.Run(ctx, inv) + if err != nil { + return false, nil, err + } + goWork := string(bytes.TrimSpace(stdout.Bytes())) + if fi, err := os.Stat(filepath.Join(filepath.Dir(goWork), "vendor")); err == nil && fi.IsDir() { + mainMods, err := getWorkspaceMainModules(ctx, inv, r) + if err != nil { + return false, nil, err + } + return true, mainMods, nil + } + return false, nil, nil +} + +// getWorkspaceMainModules gets the main modules' information. +// This is the information needed to figure out if vendoring should be enabled. +func getWorkspaceMainModules(ctx context.Context, inv Invocation, r *Runner) ([]*ModuleJSON, error) { + const format = `{{.Path}} +{{.Dir}} +{{.GoMod}} +{{.GoVersion}} +` + inv.Verb = "list" + inv.Args = []string{"-m", "-f", format} + stdout, err := r.Run(ctx, inv) + if err != nil { + return nil, err + } + + lines := strings.Split(strings.TrimSuffix(stdout.String(), "\n"), "\n") + if len(lines) < 4 { + return nil, fmt.Errorf("unexpected stdout: %q", stdout.String()) + } + mods := make([]*ModuleJSON, 0, len(lines)/4) + for i := 0; i < len(lines); i += 4 { + mods = append(mods, &ModuleJSON{ + Path: lines[i], + Dir: lines[i+1], + GoMod: lines[i+2], + GoVersion: lines[i+3], + Main: true, + }) + } + return mods, nil +} diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go index d9950b1f0b..44719de173 100644 --- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go +++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go @@ -5,10 +5,6 @@ // Package packagesinternal exposes internal-only fields from go/packages. package packagesinternal -import ( - "golang.org/x/tools/internal/gocommand" -) - var GetForTest = func(p interface{}) string { return "" } var GetDepsErrors = func(p interface{}) []*PackageError { return nil } @@ -18,10 +14,6 @@ type PackageError struct { Err string // the error itself } -var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil } - -var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {} - var TypecheckCgo int var DepsErrors int // must be set as a LoadMode to call GetDepsErrors var ForTest int // must be set as a LoadMode to call GetForTest diff --git a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go index b92e8e6eb3..f6cb37c5c3 100644 --- a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go +++ b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go @@ -21,7 +21,7 @@ import ( // export data. type PkgDecoder struct { // version is the file format version. - version uint32 + version Version // sync indicates whether the file uses sync markers. sync bool @@ -68,8 +68,6 @@ func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync } // NewPkgDecoder returns a PkgDecoder initialized to read the Unified // IR export data from input. pkgPath is the package path for the // compilation unit that produced the export data. -// -// TODO(mdempsky): Remove pkgPath parameter; unneeded since CL 391014. func NewPkgDecoder(pkgPath, input string) PkgDecoder { pr := PkgDecoder{ pkgPath: pkgPath, @@ -80,14 +78,15 @@ func NewPkgDecoder(pkgPath, input string) PkgDecoder { r := strings.NewReader(input) - assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil) + var ver uint32 + assert(binary.Read(r, binary.LittleEndian, &ver) == nil) + pr.version = Version(ver) - switch pr.version { - default: - panic(fmt.Errorf("unsupported version: %v", pr.version)) - case 0: - // no flags - case 1: + if pr.version >= numVersions { + panic(fmt.Errorf("cannot decode %q, export data version %d is greater than maximum supported version %d", pkgPath, pr.version, numVersions-1)) + } + + if pr.version.Has(Flags) { var flags uint32 assert(binary.Read(r, binary.LittleEndian, &flags) == nil) pr.sync = flags&flagSyncMarkers != 0 @@ -102,7 +101,9 @@ func NewPkgDecoder(pkgPath, input string) PkgDecoder { assert(err == nil) pr.elemData = input[pos:] - assert(len(pr.elemData)-8 == int(pr.elemEnds[len(pr.elemEnds)-1])) + + const fingerprintSize = 8 + assert(len(pr.elemData)-fingerprintSize == int(pr.elemEnds[len(pr.elemEnds)-1])) return pr } @@ -136,7 +137,7 @@ func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int { absIdx += int(pr.elemEndsEnds[k-1]) } if absIdx >= int(pr.elemEndsEnds[k]) { - errorf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds) + panicf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds) } return absIdx } @@ -193,9 +194,7 @@ func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder { Idx: idx, } - // TODO(mdempsky) r.data.Reset(...) after #44505 is resolved. - r.Data = *strings.NewReader(pr.DataIdx(k, idx)) - + r.Data.Reset(pr.DataIdx(k, idx)) r.Sync(SyncRelocs) r.Relocs = make([]RelocEnt, r.Len()) for i := range r.Relocs { @@ -244,7 +243,7 @@ type Decoder struct { func (r *Decoder) checkErr(err error) { if err != nil { - errorf("unexpected decoding error: %w", err) + panicf("unexpected decoding error: %w", err) } } @@ -515,3 +514,6 @@ func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) { return path, name, tag } + +// Version reports the version of the bitstream. +func (w *Decoder) Version() Version { return w.common.version } diff --git a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go index 6482617a4f..c17a12399d 100644 --- a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go +++ b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go @@ -12,18 +12,15 @@ import ( "io" "math/big" "runtime" + "strings" ) -// currentVersion is the current version number. -// -// - v0: initial prototype -// -// - v1: adds the flags uint32 word -const currentVersion uint32 = 1 - // A PkgEncoder provides methods for encoding a package's Unified IR // export data. type PkgEncoder struct { + // version of the bitstream. + version Version + // elems holds the bitstream for previously encoded elements. elems [numRelocs][]string @@ -47,8 +44,9 @@ func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 } // export data files, but can help diagnosing desync errors in // higher-level Unified IR reader/writer code. If syncFrames is // negative, then sync markers are omitted entirely. -func NewPkgEncoder(syncFrames int) PkgEncoder { +func NewPkgEncoder(version Version, syncFrames int) PkgEncoder { return PkgEncoder{ + version: version, stringsIdx: make(map[string]Index), syncFrames: syncFrames, } @@ -64,13 +62,15 @@ func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) { assert(binary.Write(out, binary.LittleEndian, x) == nil) } - writeUint32(currentVersion) + writeUint32(uint32(pw.version)) - var flags uint32 - if pw.SyncMarkers() { - flags |= flagSyncMarkers + if pw.version.Has(Flags) { + var flags uint32 + if pw.SyncMarkers() { + flags |= flagSyncMarkers + } + writeUint32(flags) } - writeUint32(flags) // Write elemEndsEnds. var sum uint32 @@ -159,7 +159,7 @@ type Encoder struct { // Flush finalizes the element's bitstream and returns its Index. func (w *Encoder) Flush() Index { - var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved + var sb strings.Builder // Backup the data so we write the relocations at the front. var tmp bytes.Buffer @@ -189,7 +189,7 @@ func (w *Encoder) Flush() Index { func (w *Encoder) checkErr(err error) { if err != nil { - errorf("unexpected encoding error: %v", err) + panicf("unexpected encoding error: %v", err) } } @@ -320,8 +320,14 @@ func (w *Encoder) Code(c Code) { // section (if not already present), and then writing a relocation // into the element bitstream. func (w *Encoder) String(s string) { + w.StringRef(w.p.StringIdx(s)) +} + +// StringRef writes a reference to the given index, which must be a +// previously encoded string value. +func (w *Encoder) StringRef(idx Index) { w.Sync(SyncString) - w.Reloc(RelocString, w.p.StringIdx(s)) + w.Reloc(RelocString, idx) } // Strings encodes and writes a variable-length slice of strings into @@ -348,7 +354,7 @@ func (w *Encoder) Value(val constant.Value) { func (w *Encoder) scalar(val constant.Value) { switch v := constant.Val(val).(type) { default: - errorf("unhandled %v (%v)", val, val.Kind()) + panicf("unhandled %v (%v)", val, val.Kind()) case bool: w.Code(ValBool) w.Bool(v) @@ -381,3 +387,6 @@ func (w *Encoder) bigFloat(v *big.Float) { b := v.Append(nil, 'p', -1) w.String(string(b)) // TODO: More efficient encoding. } + +// Version reports the version of the bitstream. +func (w *Encoder) Version() Version { return w.p.version } diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go deleted file mode 100644 index 5294f6a63e..0000000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.7 -// +build !go1.7 - -// TODO(mdempsky): Remove after #44505 is resolved - -package pkgbits - -import "runtime" - -func walkFrames(pcs []uintptr, visit frameVisitor) { - for _, pc := range pcs { - fn := runtime.FuncForPC(pc) - file, line := fn.FileLine(pc) - - visit(file, line, fn.Name(), pc-fn.Entry()) - } -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go deleted file mode 100644 index 2324ae7adf..0000000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.7 -// +build go1.7 - -package pkgbits - -import "runtime" - -// walkFrames calls visit for each call frame represented by pcs. -// -// pcs should be a slice of PCs, as returned by runtime.Callers. -func walkFrames(pcs []uintptr, visit frameVisitor) { - if len(pcs) == 0 { - return - } - - frames := runtime.CallersFrames(pcs) - for { - frame, more := frames.Next() - visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) - if !more { - return - } - } -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/support.go b/vendor/golang.org/x/tools/internal/pkgbits/support.go index ad26d3b28c..50534a2955 100644 --- a/vendor/golang.org/x/tools/internal/pkgbits/support.go +++ b/vendor/golang.org/x/tools/internal/pkgbits/support.go @@ -12,6 +12,6 @@ func assert(b bool) { } } -func errorf(format string, args ...interface{}) { +func panicf(format string, args ...any) { panic(fmt.Errorf(format, args...)) } diff --git a/vendor/golang.org/x/tools/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/internal/pkgbits/sync.go index 5bd51ef717..1520b73afb 100644 --- a/vendor/golang.org/x/tools/internal/pkgbits/sync.go +++ b/vendor/golang.org/x/tools/internal/pkgbits/sync.go @@ -6,6 +6,7 @@ package pkgbits import ( "fmt" + "runtime" "strings" ) @@ -23,6 +24,24 @@ func fmtFrames(pcs ...uintptr) []string { type frameVisitor func(file string, line int, name string, offset uintptr) +// walkFrames calls visit for each call frame represented by pcs. +// +// pcs should be a slice of PCs, as returned by runtime.Callers. +func walkFrames(pcs []uintptr, visit frameVisitor) { + if len(pcs) == 0 { + return + } + + frames := runtime.CallersFrames(pcs) + for { + frame, more := frames.Next() + visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) + if !more { + return + } + } +} + // SyncMarker is an enum type that represents markers that may be // written to export data to ensure the reader and writer stay // synchronized. @@ -110,4 +129,8 @@ const ( SyncStmtsEnd SyncLabel SyncOptLabel + + SyncMultiExpr + SyncRType + SyncConvRTTI ) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go index 4a5b0ca5f2..582ad56d3e 100644 --- a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go +++ b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go @@ -74,11 +74,14 @@ func _() { _ = x[SyncStmtsEnd-64] _ = x[SyncLabel-65] _ = x[SyncOptLabel-66] + _ = x[SyncMultiExpr-67] + _ = x[SyncRType-68] + _ = x[SyncConvRTTI-69] } -const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel" +const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabelMultiExprRTypeConvRTTI" -var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458} +var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458, 467, 472, 480} func (i SyncMarker) String() string { i -= 1 diff --git a/vendor/golang.org/x/tools/internal/pkgbits/version.go b/vendor/golang.org/x/tools/internal/pkgbits/version.go new file mode 100644 index 0000000000..53af9df22b --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/version.go @@ -0,0 +1,85 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +// Version indicates a version of a unified IR bitstream. +// Each Version indicates the addition, removal, or change of +// new data in the bitstream. +// +// These are serialized to disk and the interpretation remains fixed. +type Version uint32 + +const ( + // V0: initial prototype. + // + // All data that is not assigned a Field is in version V0 + // and has not been deprecated. + V0 Version = iota + + // V1: adds the Flags uint32 word + V1 + + // V2: removes unused legacy fields and supports type parameters for aliases. + // - remove the legacy "has init" bool from the public root + // - remove obj's "derived func instance" bool + // - add a TypeParamNames field to ObjAlias + // - remove derived info "needed" bool + V2 + + numVersions = iota +) + +// Field denotes a unit of data in the serialized unified IR bitstream. +// It is conceptually a like field in a structure. +// +// We only really need Fields when the data may or may not be present +// in a stream based on the Version of the bitstream. +// +// Unlike much of pkgbits, Fields are not serialized and +// can change values as needed. +type Field int + +const ( + // Flags in a uint32 in the header of a bitstream + // that is used to indicate whether optional features are enabled. + Flags Field = iota + + // Deprecated: HasInit was a bool indicating whether a package + // has any init functions. + HasInit + + // Deprecated: DerivedFuncInstance was a bool indicating + // whether an object was a function instance. + DerivedFuncInstance + + // ObjAlias has a list of TypeParamNames. + AliasTypeParamNames + + // Deprecated: DerivedInfoNeeded was a bool indicating + // whether a type was a derived type. + DerivedInfoNeeded + + numFields = iota +) + +// introduced is the version a field was added. +var introduced = [numFields]Version{ + Flags: V1, + AliasTypeParamNames: V2, +} + +// removed is the version a field was removed in or 0 for fields +// that have not yet been deprecated. +// (So removed[f]-1 is the last version it is included in.) +var removed = [numFields]Version{ + HasInit: V2, + DerivedFuncInstance: V2, + DerivedInfoNeeded: V2, +} + +// Has reports whether field f is present in a bitstream at version v. +func (v Version) Has(f Field) bool { + return introduced[f] <= v && (v < removed[f] || removed[f] == V0) +} diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go new file mode 100644 index 0000000000..cdaac9ab34 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/stdlib/manifest.go @@ -0,0 +1,17431 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate.go. DO NOT EDIT. + +package stdlib + +var PackageSymbols = map[string][]Symbol{ + "archive/tar": { + {"(*Header).FileInfo", Method, 1}, + {"(*Reader).Next", Method, 0}, + {"(*Reader).Read", Method, 0}, + {"(*Writer).AddFS", Method, 22}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Write", Method, 0}, + {"(*Writer).WriteHeader", Method, 0}, + {"(Format).String", Method, 10}, + {"ErrFieldTooLong", Var, 0}, + {"ErrHeader", Var, 0}, + {"ErrInsecurePath", Var, 20}, + {"ErrWriteAfterClose", Var, 0}, + {"ErrWriteTooLong", Var, 0}, + {"FileInfoHeader", Func, 1}, + {"FileInfoNames", Type, 23}, + {"Format", Type, 10}, + {"FormatGNU", Const, 10}, + {"FormatPAX", Const, 10}, + {"FormatUSTAR", Const, 10}, + {"FormatUnknown", Const, 10}, + {"Header", Type, 0}, + {"Header.AccessTime", Field, 0}, + {"Header.ChangeTime", Field, 0}, + {"Header.Devmajor", Field, 0}, + {"Header.Devminor", Field, 0}, + {"Header.Format", Field, 10}, + {"Header.Gid", Field, 0}, + {"Header.Gname", Field, 0}, + {"Header.Linkname", Field, 0}, + {"Header.ModTime", Field, 0}, + {"Header.Mode", Field, 0}, + {"Header.Name", Field, 0}, + {"Header.PAXRecords", Field, 10}, + {"Header.Size", Field, 0}, + {"Header.Typeflag", Field, 0}, + {"Header.Uid", Field, 0}, + {"Header.Uname", Field, 0}, + {"Header.Xattrs", Field, 3}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"Reader", Type, 0}, + {"TypeBlock", Const, 0}, + {"TypeChar", Const, 0}, + {"TypeCont", Const, 0}, + {"TypeDir", Const, 0}, + {"TypeFifo", Const, 0}, + {"TypeGNULongLink", Const, 1}, + {"TypeGNULongName", Const, 1}, + {"TypeGNUSparse", Const, 3}, + {"TypeLink", Const, 0}, + {"TypeReg", Const, 0}, + {"TypeRegA", Const, 0}, + {"TypeSymlink", Const, 0}, + {"TypeXGlobalHeader", Const, 0}, + {"TypeXHeader", Const, 0}, + {"Writer", Type, 0}, + }, + "archive/zip": { + {"(*File).DataOffset", Method, 2}, + {"(*File).FileInfo", Method, 0}, + {"(*File).ModTime", Method, 0}, + {"(*File).Mode", Method, 0}, + {"(*File).Open", Method, 0}, + {"(*File).OpenRaw", Method, 17}, + {"(*File).SetModTime", Method, 0}, + {"(*File).SetMode", Method, 0}, + {"(*FileHeader).FileInfo", Method, 0}, + {"(*FileHeader).ModTime", Method, 0}, + {"(*FileHeader).Mode", Method, 0}, + {"(*FileHeader).SetModTime", Method, 0}, + {"(*FileHeader).SetMode", Method, 0}, + {"(*ReadCloser).Close", Method, 0}, + {"(*ReadCloser).Open", Method, 16}, + {"(*ReadCloser).RegisterDecompressor", Method, 6}, + {"(*Reader).Open", Method, 16}, + {"(*Reader).RegisterDecompressor", Method, 6}, + {"(*Writer).AddFS", Method, 22}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Copy", Method, 17}, + {"(*Writer).Create", Method, 0}, + {"(*Writer).CreateHeader", Method, 0}, + {"(*Writer).CreateRaw", Method, 17}, + {"(*Writer).Flush", Method, 4}, + {"(*Writer).RegisterCompressor", Method, 6}, + {"(*Writer).SetComment", Method, 10}, + {"(*Writer).SetOffset", Method, 5}, + {"Compressor", Type, 2}, + {"Decompressor", Type, 2}, + {"Deflate", Const, 0}, + {"ErrAlgorithm", Var, 0}, + {"ErrChecksum", Var, 0}, + {"ErrFormat", Var, 0}, + {"ErrInsecurePath", Var, 20}, + {"File", Type, 0}, + {"File.FileHeader", Field, 0}, + {"FileHeader", Type, 0}, + {"FileHeader.CRC32", Field, 0}, + {"FileHeader.Comment", Field, 0}, + {"FileHeader.CompressedSize", Field, 0}, + {"FileHeader.CompressedSize64", Field, 1}, + {"FileHeader.CreatorVersion", Field, 0}, + {"FileHeader.ExternalAttrs", Field, 0}, + {"FileHeader.Extra", Field, 0}, + {"FileHeader.Flags", Field, 0}, + {"FileHeader.Method", Field, 0}, + {"FileHeader.Modified", Field, 10}, + {"FileHeader.ModifiedDate", Field, 0}, + {"FileHeader.ModifiedTime", Field, 0}, + {"FileHeader.Name", Field, 0}, + {"FileHeader.NonUTF8", Field, 10}, + {"FileHeader.ReaderVersion", Field, 0}, + {"FileHeader.UncompressedSize", Field, 0}, + {"FileHeader.UncompressedSize64", Field, 1}, + {"FileInfoHeader", Func, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"OpenReader", Func, 0}, + {"ReadCloser", Type, 0}, + {"ReadCloser.Reader", Field, 0}, + {"Reader", Type, 0}, + {"Reader.Comment", Field, 0}, + {"Reader.File", Field, 0}, + {"RegisterCompressor", Func, 2}, + {"RegisterDecompressor", Func, 2}, + {"Store", Const, 0}, + {"Writer", Type, 0}, + }, + "bufio": { + {"(*Reader).Buffered", Method, 0}, + {"(*Reader).Discard", Method, 5}, + {"(*Reader).Peek", Method, 0}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).ReadByte", Method, 0}, + {"(*Reader).ReadBytes", Method, 0}, + {"(*Reader).ReadLine", Method, 0}, + {"(*Reader).ReadRune", Method, 0}, + {"(*Reader).ReadSlice", Method, 0}, + {"(*Reader).ReadString", Method, 0}, + {"(*Reader).Reset", Method, 2}, + {"(*Reader).Size", Method, 10}, + {"(*Reader).UnreadByte", Method, 0}, + {"(*Reader).UnreadRune", Method, 0}, + {"(*Reader).WriteTo", Method, 1}, + {"(*Scanner).Buffer", Method, 6}, + {"(*Scanner).Bytes", Method, 1}, + {"(*Scanner).Err", Method, 1}, + {"(*Scanner).Scan", Method, 1}, + {"(*Scanner).Split", Method, 1}, + {"(*Scanner).Text", Method, 1}, + {"(*Writer).Available", Method, 0}, + {"(*Writer).AvailableBuffer", Method, 18}, + {"(*Writer).Buffered", Method, 0}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).ReadFrom", Method, 1}, + {"(*Writer).Reset", Method, 2}, + {"(*Writer).Size", Method, 10}, + {"(*Writer).Write", Method, 0}, + {"(*Writer).WriteByte", Method, 0}, + {"(*Writer).WriteRune", Method, 0}, + {"(*Writer).WriteString", Method, 0}, + {"(ReadWriter).Available", Method, 0}, + {"(ReadWriter).AvailableBuffer", Method, 18}, + {"(ReadWriter).Discard", Method, 5}, + {"(ReadWriter).Flush", Method, 0}, + {"(ReadWriter).Peek", Method, 0}, + {"(ReadWriter).Read", Method, 0}, + {"(ReadWriter).ReadByte", Method, 0}, + {"(ReadWriter).ReadBytes", Method, 0}, + {"(ReadWriter).ReadFrom", Method, 1}, + {"(ReadWriter).ReadLine", Method, 0}, + {"(ReadWriter).ReadRune", Method, 0}, + {"(ReadWriter).ReadSlice", Method, 0}, + {"(ReadWriter).ReadString", Method, 0}, + {"(ReadWriter).UnreadByte", Method, 0}, + {"(ReadWriter).UnreadRune", Method, 0}, + {"(ReadWriter).Write", Method, 0}, + {"(ReadWriter).WriteByte", Method, 0}, + {"(ReadWriter).WriteRune", Method, 0}, + {"(ReadWriter).WriteString", Method, 0}, + {"(ReadWriter).WriteTo", Method, 1}, + {"ErrAdvanceTooFar", Var, 1}, + {"ErrBadReadCount", Var, 15}, + {"ErrBufferFull", Var, 0}, + {"ErrFinalToken", Var, 6}, + {"ErrInvalidUnreadByte", Var, 0}, + {"ErrInvalidUnreadRune", Var, 0}, + {"ErrNegativeAdvance", Var, 1}, + {"ErrNegativeCount", Var, 0}, + {"ErrTooLong", Var, 1}, + {"MaxScanTokenSize", Const, 1}, + {"NewReadWriter", Func, 0}, + {"NewReader", Func, 0}, + {"NewReaderSize", Func, 0}, + {"NewScanner", Func, 1}, + {"NewWriter", Func, 0}, + {"NewWriterSize", Func, 0}, + {"ReadWriter", Type, 0}, + {"ReadWriter.Reader", Field, 0}, + {"ReadWriter.Writer", Field, 0}, + {"Reader", Type, 0}, + {"ScanBytes", Func, 1}, + {"ScanLines", Func, 1}, + {"ScanRunes", Func, 1}, + {"ScanWords", Func, 1}, + {"Scanner", Type, 1}, + {"SplitFunc", Type, 1}, + {"Writer", Type, 0}, + }, + "bytes": { + {"(*Buffer).Available", Method, 21}, + {"(*Buffer).AvailableBuffer", Method, 21}, + {"(*Buffer).Bytes", Method, 0}, + {"(*Buffer).Cap", Method, 5}, + {"(*Buffer).Grow", Method, 1}, + {"(*Buffer).Len", Method, 0}, + {"(*Buffer).Next", Method, 0}, + {"(*Buffer).Read", Method, 0}, + {"(*Buffer).ReadByte", Method, 0}, + {"(*Buffer).ReadBytes", Method, 0}, + {"(*Buffer).ReadFrom", Method, 0}, + {"(*Buffer).ReadRune", Method, 0}, + {"(*Buffer).ReadString", Method, 0}, + {"(*Buffer).Reset", Method, 0}, + {"(*Buffer).String", Method, 0}, + {"(*Buffer).Truncate", Method, 0}, + {"(*Buffer).UnreadByte", Method, 0}, + {"(*Buffer).UnreadRune", Method, 0}, + {"(*Buffer).Write", Method, 0}, + {"(*Buffer).WriteByte", Method, 0}, + {"(*Buffer).WriteRune", Method, 0}, + {"(*Buffer).WriteString", Method, 0}, + {"(*Buffer).WriteTo", Method, 0}, + {"(*Reader).Len", Method, 0}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).ReadAt", Method, 0}, + {"(*Reader).ReadByte", Method, 0}, + {"(*Reader).ReadRune", Method, 0}, + {"(*Reader).Reset", Method, 7}, + {"(*Reader).Seek", Method, 0}, + {"(*Reader).Size", Method, 5}, + {"(*Reader).UnreadByte", Method, 0}, + {"(*Reader).UnreadRune", Method, 0}, + {"(*Reader).WriteTo", Method, 1}, + {"Buffer", Type, 0}, + {"Clone", Func, 20}, + {"Compare", Func, 0}, + {"Contains", Func, 0}, + {"ContainsAny", Func, 7}, + {"ContainsFunc", Func, 21}, + {"ContainsRune", Func, 7}, + {"Count", Func, 0}, + {"Cut", Func, 18}, + {"CutPrefix", Func, 20}, + {"CutSuffix", Func, 20}, + {"Equal", Func, 0}, + {"EqualFold", Func, 0}, + {"ErrTooLarge", Var, 0}, + {"Fields", Func, 0}, + {"FieldsFunc", Func, 0}, + {"HasPrefix", Func, 0}, + {"HasSuffix", Func, 0}, + {"Index", Func, 0}, + {"IndexAny", Func, 0}, + {"IndexByte", Func, 0}, + {"IndexFunc", Func, 0}, + {"IndexRune", Func, 0}, + {"Join", Func, 0}, + {"LastIndex", Func, 0}, + {"LastIndexAny", Func, 0}, + {"LastIndexByte", Func, 5}, + {"LastIndexFunc", Func, 0}, + {"Map", Func, 0}, + {"MinRead", Const, 0}, + {"NewBuffer", Func, 0}, + {"NewBufferString", Func, 0}, + {"NewReader", Func, 0}, + {"Reader", Type, 0}, + {"Repeat", Func, 0}, + {"Replace", Func, 0}, + {"ReplaceAll", Func, 12}, + {"Runes", Func, 0}, + {"Split", Func, 0}, + {"SplitAfter", Func, 0}, + {"SplitAfterN", Func, 0}, + {"SplitN", Func, 0}, + {"Title", Func, 0}, + {"ToLower", Func, 0}, + {"ToLowerSpecial", Func, 0}, + {"ToTitle", Func, 0}, + {"ToTitleSpecial", Func, 0}, + {"ToUpper", Func, 0}, + {"ToUpperSpecial", Func, 0}, + {"ToValidUTF8", Func, 13}, + {"Trim", Func, 0}, + {"TrimFunc", Func, 0}, + {"TrimLeft", Func, 0}, + {"TrimLeftFunc", Func, 0}, + {"TrimPrefix", Func, 1}, + {"TrimRight", Func, 0}, + {"TrimRightFunc", Func, 0}, + {"TrimSpace", Func, 0}, + {"TrimSuffix", Func, 1}, + }, + "cmp": { + {"Compare", Func, 21}, + {"Less", Func, 21}, + {"Or", Func, 22}, + {"Ordered", Type, 21}, + }, + "compress/bzip2": { + {"(StructuralError).Error", Method, 0}, + {"NewReader", Func, 0}, + {"StructuralError", Type, 0}, + }, + "compress/flate": { + {"(*ReadError).Error", Method, 0}, + {"(*WriteError).Error", Method, 0}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Reset", Method, 2}, + {"(*Writer).Write", Method, 0}, + {"(CorruptInputError).Error", Method, 0}, + {"(InternalError).Error", Method, 0}, + {"BestCompression", Const, 0}, + {"BestSpeed", Const, 0}, + {"CorruptInputError", Type, 0}, + {"DefaultCompression", Const, 0}, + {"HuffmanOnly", Const, 7}, + {"InternalError", Type, 0}, + {"NewReader", Func, 0}, + {"NewReaderDict", Func, 0}, + {"NewWriter", Func, 0}, + {"NewWriterDict", Func, 0}, + {"NoCompression", Const, 0}, + {"ReadError", Type, 0}, + {"ReadError.Err", Field, 0}, + {"ReadError.Offset", Field, 0}, + {"Reader", Type, 0}, + {"Resetter", Type, 4}, + {"WriteError", Type, 0}, + {"WriteError.Err", Field, 0}, + {"WriteError.Offset", Field, 0}, + {"Writer", Type, 0}, + }, + "compress/gzip": { + {"(*Reader).Close", Method, 0}, + {"(*Reader).Multistream", Method, 4}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).Reset", Method, 3}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Flush", Method, 1}, + {"(*Writer).Reset", Method, 2}, + {"(*Writer).Write", Method, 0}, + {"BestCompression", Const, 0}, + {"BestSpeed", Const, 0}, + {"DefaultCompression", Const, 0}, + {"ErrChecksum", Var, 0}, + {"ErrHeader", Var, 0}, + {"Header", Type, 0}, + {"Header.Comment", Field, 0}, + {"Header.Extra", Field, 0}, + {"Header.ModTime", Field, 0}, + {"Header.Name", Field, 0}, + {"Header.OS", Field, 0}, + {"HuffmanOnly", Const, 8}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"NewWriterLevel", Func, 0}, + {"NoCompression", Const, 0}, + {"Reader", Type, 0}, + {"Reader.Header", Field, 0}, + {"Writer", Type, 0}, + {"Writer.Header", Field, 0}, + }, + "compress/lzw": { + {"(*Reader).Close", Method, 17}, + {"(*Reader).Read", Method, 17}, + {"(*Reader).Reset", Method, 17}, + {"(*Writer).Close", Method, 17}, + {"(*Writer).Reset", Method, 17}, + {"(*Writer).Write", Method, 17}, + {"LSB", Const, 0}, + {"MSB", Const, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"Order", Type, 0}, + {"Reader", Type, 17}, + {"Writer", Type, 17}, + }, + "compress/zlib": { + {"(*Writer).Close", Method, 0}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Reset", Method, 2}, + {"(*Writer).Write", Method, 0}, + {"BestCompression", Const, 0}, + {"BestSpeed", Const, 0}, + {"DefaultCompression", Const, 0}, + {"ErrChecksum", Var, 0}, + {"ErrDictionary", Var, 0}, + {"ErrHeader", Var, 0}, + {"HuffmanOnly", Const, 8}, + {"NewReader", Func, 0}, + {"NewReaderDict", Func, 0}, + {"NewWriter", Func, 0}, + {"NewWriterLevel", Func, 0}, + {"NewWriterLevelDict", Func, 0}, + {"NoCompression", Const, 0}, + {"Resetter", Type, 4}, + {"Writer", Type, 0}, + }, + "container/heap": { + {"Fix", Func, 2}, + {"Init", Func, 0}, + {"Interface", Type, 0}, + {"Pop", Func, 0}, + {"Push", Func, 0}, + {"Remove", Func, 0}, + }, + "container/list": { + {"(*Element).Next", Method, 0}, + {"(*Element).Prev", Method, 0}, + {"(*List).Back", Method, 0}, + {"(*List).Front", Method, 0}, + {"(*List).Init", Method, 0}, + {"(*List).InsertAfter", Method, 0}, + {"(*List).InsertBefore", Method, 0}, + {"(*List).Len", Method, 0}, + {"(*List).MoveAfter", Method, 2}, + {"(*List).MoveBefore", Method, 2}, + {"(*List).MoveToBack", Method, 0}, + {"(*List).MoveToFront", Method, 0}, + {"(*List).PushBack", Method, 0}, + {"(*List).PushBackList", Method, 0}, + {"(*List).PushFront", Method, 0}, + {"(*List).PushFrontList", Method, 0}, + {"(*List).Remove", Method, 0}, + {"Element", Type, 0}, + {"Element.Value", Field, 0}, + {"List", Type, 0}, + {"New", Func, 0}, + }, + "container/ring": { + {"(*Ring).Do", Method, 0}, + {"(*Ring).Len", Method, 0}, + {"(*Ring).Link", Method, 0}, + {"(*Ring).Move", Method, 0}, + {"(*Ring).Next", Method, 0}, + {"(*Ring).Prev", Method, 0}, + {"(*Ring).Unlink", Method, 0}, + {"New", Func, 0}, + {"Ring", Type, 0}, + {"Ring.Value", Field, 0}, + }, + "context": { + {"AfterFunc", Func, 21}, + {"Background", Func, 7}, + {"CancelCauseFunc", Type, 20}, + {"CancelFunc", Type, 7}, + {"Canceled", Var, 7}, + {"Cause", Func, 20}, + {"Context", Type, 7}, + {"DeadlineExceeded", Var, 7}, + {"TODO", Func, 7}, + {"WithCancel", Func, 7}, + {"WithCancelCause", Func, 20}, + {"WithDeadline", Func, 7}, + {"WithDeadlineCause", Func, 21}, + {"WithTimeout", Func, 7}, + {"WithTimeoutCause", Func, 21}, + {"WithValue", Func, 7}, + {"WithoutCancel", Func, 21}, + }, + "crypto": { + {"(Hash).Available", Method, 0}, + {"(Hash).HashFunc", Method, 4}, + {"(Hash).New", Method, 0}, + {"(Hash).Size", Method, 0}, + {"(Hash).String", Method, 15}, + {"BLAKE2b_256", Const, 9}, + {"BLAKE2b_384", Const, 9}, + {"BLAKE2b_512", Const, 9}, + {"BLAKE2s_256", Const, 9}, + {"Decrypter", Type, 5}, + {"DecrypterOpts", Type, 5}, + {"Hash", Type, 0}, + {"MD4", Const, 0}, + {"MD5", Const, 0}, + {"MD5SHA1", Const, 0}, + {"PrivateKey", Type, 0}, + {"PublicKey", Type, 2}, + {"RIPEMD160", Const, 0}, + {"RegisterHash", Func, 0}, + {"SHA1", Const, 0}, + {"SHA224", Const, 0}, + {"SHA256", Const, 0}, + {"SHA384", Const, 0}, + {"SHA3_224", Const, 4}, + {"SHA3_256", Const, 4}, + {"SHA3_384", Const, 4}, + {"SHA3_512", Const, 4}, + {"SHA512", Const, 0}, + {"SHA512_224", Const, 5}, + {"SHA512_256", Const, 5}, + {"Signer", Type, 4}, + {"SignerOpts", Type, 4}, + }, + "crypto/aes": { + {"(KeySizeError).Error", Method, 0}, + {"BlockSize", Const, 0}, + {"KeySizeError", Type, 0}, + {"NewCipher", Func, 0}, + }, + "crypto/cipher": { + {"(StreamReader).Read", Method, 0}, + {"(StreamWriter).Close", Method, 0}, + {"(StreamWriter).Write", Method, 0}, + {"AEAD", Type, 2}, + {"Block", Type, 0}, + {"BlockMode", Type, 0}, + {"NewCBCDecrypter", Func, 0}, + {"NewCBCEncrypter", Func, 0}, + {"NewCFBDecrypter", Func, 0}, + {"NewCFBEncrypter", Func, 0}, + {"NewCTR", Func, 0}, + {"NewGCM", Func, 2}, + {"NewGCMWithNonceSize", Func, 5}, + {"NewGCMWithTagSize", Func, 11}, + {"NewOFB", Func, 0}, + {"Stream", Type, 0}, + {"StreamReader", Type, 0}, + {"StreamReader.R", Field, 0}, + {"StreamReader.S", Field, 0}, + {"StreamWriter", Type, 0}, + {"StreamWriter.Err", Field, 0}, + {"StreamWriter.S", Field, 0}, + {"StreamWriter.W", Field, 0}, + }, + "crypto/des": { + {"(KeySizeError).Error", Method, 0}, + {"BlockSize", Const, 0}, + {"KeySizeError", Type, 0}, + {"NewCipher", Func, 0}, + {"NewTripleDESCipher", Func, 0}, + }, + "crypto/dsa": { + {"ErrInvalidPublicKey", Var, 0}, + {"GenerateKey", Func, 0}, + {"GenerateParameters", Func, 0}, + {"L1024N160", Const, 0}, + {"L2048N224", Const, 0}, + {"L2048N256", Const, 0}, + {"L3072N256", Const, 0}, + {"ParameterSizes", Type, 0}, + {"Parameters", Type, 0}, + {"Parameters.G", Field, 0}, + {"Parameters.P", Field, 0}, + {"Parameters.Q", Field, 0}, + {"PrivateKey", Type, 0}, + {"PrivateKey.PublicKey", Field, 0}, + {"PrivateKey.X", Field, 0}, + {"PublicKey", Type, 0}, + {"PublicKey.Parameters", Field, 0}, + {"PublicKey.Y", Field, 0}, + {"Sign", Func, 0}, + {"Verify", Func, 0}, + }, + "crypto/ecdh": { + {"(*PrivateKey).Bytes", Method, 20}, + {"(*PrivateKey).Curve", Method, 20}, + {"(*PrivateKey).ECDH", Method, 20}, + {"(*PrivateKey).Equal", Method, 20}, + {"(*PrivateKey).Public", Method, 20}, + {"(*PrivateKey).PublicKey", Method, 20}, + {"(*PublicKey).Bytes", Method, 20}, + {"(*PublicKey).Curve", Method, 20}, + {"(*PublicKey).Equal", Method, 20}, + {"Curve", Type, 20}, + {"P256", Func, 20}, + {"P384", Func, 20}, + {"P521", Func, 20}, + {"PrivateKey", Type, 20}, + {"PublicKey", Type, 20}, + {"X25519", Func, 20}, + }, + "crypto/ecdsa": { + {"(*PrivateKey).ECDH", Method, 20}, + {"(*PrivateKey).Equal", Method, 15}, + {"(*PrivateKey).Public", Method, 4}, + {"(*PrivateKey).Sign", Method, 4}, + {"(*PublicKey).ECDH", Method, 20}, + {"(*PublicKey).Equal", Method, 15}, + {"(PrivateKey).Add", Method, 0}, + {"(PrivateKey).Double", Method, 0}, + {"(PrivateKey).IsOnCurve", Method, 0}, + {"(PrivateKey).Params", Method, 0}, + {"(PrivateKey).ScalarBaseMult", Method, 0}, + {"(PrivateKey).ScalarMult", Method, 0}, + {"(PublicKey).Add", Method, 0}, + {"(PublicKey).Double", Method, 0}, + {"(PublicKey).IsOnCurve", Method, 0}, + {"(PublicKey).Params", Method, 0}, + {"(PublicKey).ScalarBaseMult", Method, 0}, + {"(PublicKey).ScalarMult", Method, 0}, + {"GenerateKey", Func, 0}, + {"PrivateKey", Type, 0}, + {"PrivateKey.D", Field, 0}, + {"PrivateKey.PublicKey", Field, 0}, + {"PublicKey", Type, 0}, + {"PublicKey.Curve", Field, 0}, + {"PublicKey.X", Field, 0}, + {"PublicKey.Y", Field, 0}, + {"Sign", Func, 0}, + {"SignASN1", Func, 15}, + {"Verify", Func, 0}, + {"VerifyASN1", Func, 15}, + }, + "crypto/ed25519": { + {"(*Options).HashFunc", Method, 20}, + {"(PrivateKey).Equal", Method, 15}, + {"(PrivateKey).Public", Method, 13}, + {"(PrivateKey).Seed", Method, 13}, + {"(PrivateKey).Sign", Method, 13}, + {"(PublicKey).Equal", Method, 15}, + {"GenerateKey", Func, 13}, + {"NewKeyFromSeed", Func, 13}, + {"Options", Type, 20}, + {"Options.Context", Field, 20}, + {"Options.Hash", Field, 20}, + {"PrivateKey", Type, 13}, + {"PrivateKeySize", Const, 13}, + {"PublicKey", Type, 13}, + {"PublicKeySize", Const, 13}, + {"SeedSize", Const, 13}, + {"Sign", Func, 13}, + {"SignatureSize", Const, 13}, + {"Verify", Func, 13}, + {"VerifyWithOptions", Func, 20}, + }, + "crypto/elliptic": { + {"(*CurveParams).Add", Method, 0}, + {"(*CurveParams).Double", Method, 0}, + {"(*CurveParams).IsOnCurve", Method, 0}, + {"(*CurveParams).Params", Method, 0}, + {"(*CurveParams).ScalarBaseMult", Method, 0}, + {"(*CurveParams).ScalarMult", Method, 0}, + {"Curve", Type, 0}, + {"CurveParams", Type, 0}, + {"CurveParams.B", Field, 0}, + {"CurveParams.BitSize", Field, 0}, + {"CurveParams.Gx", Field, 0}, + {"CurveParams.Gy", Field, 0}, + {"CurveParams.N", Field, 0}, + {"CurveParams.Name", Field, 5}, + {"CurveParams.P", Field, 0}, + {"GenerateKey", Func, 0}, + {"Marshal", Func, 0}, + {"MarshalCompressed", Func, 15}, + {"P224", Func, 0}, + {"P256", Func, 0}, + {"P384", Func, 0}, + {"P521", Func, 0}, + {"Unmarshal", Func, 0}, + {"UnmarshalCompressed", Func, 15}, + }, + "crypto/hmac": { + {"Equal", Func, 1}, + {"New", Func, 0}, + }, + "crypto/md5": { + {"BlockSize", Const, 0}, + {"New", Func, 0}, + {"Size", Const, 0}, + {"Sum", Func, 2}, + }, + "crypto/rand": { + {"Int", Func, 0}, + {"Prime", Func, 0}, + {"Read", Func, 0}, + {"Reader", Var, 0}, + }, + "crypto/rc4": { + {"(*Cipher).Reset", Method, 0}, + {"(*Cipher).XORKeyStream", Method, 0}, + {"(KeySizeError).Error", Method, 0}, + {"Cipher", Type, 0}, + {"KeySizeError", Type, 0}, + {"NewCipher", Func, 0}, + }, + "crypto/rsa": { + {"(*PSSOptions).HashFunc", Method, 4}, + {"(*PrivateKey).Decrypt", Method, 5}, + {"(*PrivateKey).Equal", Method, 15}, + {"(*PrivateKey).Precompute", Method, 0}, + {"(*PrivateKey).Public", Method, 4}, + {"(*PrivateKey).Sign", Method, 4}, + {"(*PrivateKey).Size", Method, 11}, + {"(*PrivateKey).Validate", Method, 0}, + {"(*PublicKey).Equal", Method, 15}, + {"(*PublicKey).Size", Method, 11}, + {"CRTValue", Type, 0}, + {"CRTValue.Coeff", Field, 0}, + {"CRTValue.Exp", Field, 0}, + {"CRTValue.R", Field, 0}, + {"DecryptOAEP", Func, 0}, + {"DecryptPKCS1v15", Func, 0}, + {"DecryptPKCS1v15SessionKey", Func, 0}, + {"EncryptOAEP", Func, 0}, + {"EncryptPKCS1v15", Func, 0}, + {"ErrDecryption", Var, 0}, + {"ErrMessageTooLong", Var, 0}, + {"ErrVerification", Var, 0}, + {"GenerateKey", Func, 0}, + {"GenerateMultiPrimeKey", Func, 0}, + {"OAEPOptions", Type, 5}, + {"OAEPOptions.Hash", Field, 5}, + {"OAEPOptions.Label", Field, 5}, + {"OAEPOptions.MGFHash", Field, 20}, + {"PKCS1v15DecryptOptions", Type, 5}, + {"PKCS1v15DecryptOptions.SessionKeyLen", Field, 5}, + {"PSSOptions", Type, 2}, + {"PSSOptions.Hash", Field, 4}, + {"PSSOptions.SaltLength", Field, 2}, + {"PSSSaltLengthAuto", Const, 2}, + {"PSSSaltLengthEqualsHash", Const, 2}, + {"PrecomputedValues", Type, 0}, + {"PrecomputedValues.CRTValues", Field, 0}, + {"PrecomputedValues.Dp", Field, 0}, + {"PrecomputedValues.Dq", Field, 0}, + {"PrecomputedValues.Qinv", Field, 0}, + {"PrivateKey", Type, 0}, + {"PrivateKey.D", Field, 0}, + {"PrivateKey.Precomputed", Field, 0}, + {"PrivateKey.Primes", Field, 0}, + {"PrivateKey.PublicKey", Field, 0}, + {"PublicKey", Type, 0}, + {"PublicKey.E", Field, 0}, + {"PublicKey.N", Field, 0}, + {"SignPKCS1v15", Func, 0}, + {"SignPSS", Func, 2}, + {"VerifyPKCS1v15", Func, 0}, + {"VerifyPSS", Func, 2}, + }, + "crypto/sha1": { + {"BlockSize", Const, 0}, + {"New", Func, 0}, + {"Size", Const, 0}, + {"Sum", Func, 2}, + }, + "crypto/sha256": { + {"BlockSize", Const, 0}, + {"New", Func, 0}, + {"New224", Func, 0}, + {"Size", Const, 0}, + {"Size224", Const, 0}, + {"Sum224", Func, 2}, + {"Sum256", Func, 2}, + }, + "crypto/sha512": { + {"BlockSize", Const, 0}, + {"New", Func, 0}, + {"New384", Func, 0}, + {"New512_224", Func, 5}, + {"New512_256", Func, 5}, + {"Size", Const, 0}, + {"Size224", Const, 5}, + {"Size256", Const, 5}, + {"Size384", Const, 0}, + {"Sum384", Func, 2}, + {"Sum512", Func, 2}, + {"Sum512_224", Func, 5}, + {"Sum512_256", Func, 5}, + }, + "crypto/subtle": { + {"ConstantTimeByteEq", Func, 0}, + {"ConstantTimeCompare", Func, 0}, + {"ConstantTimeCopy", Func, 0}, + {"ConstantTimeEq", Func, 0}, + {"ConstantTimeLessOrEq", Func, 2}, + {"ConstantTimeSelect", Func, 0}, + {"XORBytes", Func, 20}, + }, + "crypto/tls": { + {"(*CertificateRequestInfo).Context", Method, 17}, + {"(*CertificateRequestInfo).SupportsCertificate", Method, 14}, + {"(*CertificateVerificationError).Error", Method, 20}, + {"(*CertificateVerificationError).Unwrap", Method, 20}, + {"(*ClientHelloInfo).Context", Method, 17}, + {"(*ClientHelloInfo).SupportsCertificate", Method, 14}, + {"(*ClientSessionState).ResumptionState", Method, 21}, + {"(*Config).BuildNameToCertificate", Method, 0}, + {"(*Config).Clone", Method, 8}, + {"(*Config).DecryptTicket", Method, 21}, + {"(*Config).EncryptTicket", Method, 21}, + {"(*Config).SetSessionTicketKeys", Method, 5}, + {"(*Conn).Close", Method, 0}, + {"(*Conn).CloseWrite", Method, 8}, + {"(*Conn).ConnectionState", Method, 0}, + {"(*Conn).Handshake", Method, 0}, + {"(*Conn).HandshakeContext", Method, 17}, + {"(*Conn).LocalAddr", Method, 0}, + {"(*Conn).NetConn", Method, 18}, + {"(*Conn).OCSPResponse", Method, 0}, + {"(*Conn).Read", Method, 0}, + {"(*Conn).RemoteAddr", Method, 0}, + {"(*Conn).SetDeadline", Method, 0}, + {"(*Conn).SetReadDeadline", Method, 0}, + {"(*Conn).SetWriteDeadline", Method, 0}, + {"(*Conn).VerifyHostname", Method, 0}, + {"(*Conn).Write", Method, 0}, + {"(*ConnectionState).ExportKeyingMaterial", Method, 11}, + {"(*Dialer).Dial", Method, 15}, + {"(*Dialer).DialContext", Method, 15}, + {"(*ECHRejectionError).Error", Method, 23}, + {"(*QUICConn).Close", Method, 21}, + {"(*QUICConn).ConnectionState", Method, 21}, + {"(*QUICConn).HandleData", Method, 21}, + {"(*QUICConn).NextEvent", Method, 21}, + {"(*QUICConn).SendSessionTicket", Method, 21}, + {"(*QUICConn).SetTransportParameters", Method, 21}, + {"(*QUICConn).Start", Method, 21}, + {"(*QUICConn).StoreSession", Method, 23}, + {"(*SessionState).Bytes", Method, 21}, + {"(AlertError).Error", Method, 21}, + {"(ClientAuthType).String", Method, 15}, + {"(CurveID).String", Method, 15}, + {"(QUICEncryptionLevel).String", Method, 21}, + {"(RecordHeaderError).Error", Method, 6}, + {"(SignatureScheme).String", Method, 15}, + {"AlertError", Type, 21}, + {"Certificate", Type, 0}, + {"Certificate.Certificate", Field, 0}, + {"Certificate.Leaf", Field, 0}, + {"Certificate.OCSPStaple", Field, 0}, + {"Certificate.PrivateKey", Field, 0}, + {"Certificate.SignedCertificateTimestamps", Field, 5}, + {"Certificate.SupportedSignatureAlgorithms", Field, 14}, + {"CertificateRequestInfo", Type, 8}, + {"CertificateRequestInfo.AcceptableCAs", Field, 8}, + {"CertificateRequestInfo.SignatureSchemes", Field, 8}, + {"CertificateRequestInfo.Version", Field, 14}, + {"CertificateVerificationError", Type, 20}, + {"CertificateVerificationError.Err", Field, 20}, + {"CertificateVerificationError.UnverifiedCertificates", Field, 20}, + {"CipherSuite", Type, 14}, + {"CipherSuite.ID", Field, 14}, + {"CipherSuite.Insecure", Field, 14}, + {"CipherSuite.Name", Field, 14}, + {"CipherSuite.SupportedVersions", Field, 14}, + {"CipherSuiteName", Func, 14}, + {"CipherSuites", Func, 14}, + {"Client", Func, 0}, + {"ClientAuthType", Type, 0}, + {"ClientHelloInfo", Type, 4}, + {"ClientHelloInfo.CipherSuites", Field, 4}, + {"ClientHelloInfo.Conn", Field, 8}, + {"ClientHelloInfo.ServerName", Field, 4}, + {"ClientHelloInfo.SignatureSchemes", Field, 8}, + {"ClientHelloInfo.SupportedCurves", Field, 4}, + {"ClientHelloInfo.SupportedPoints", Field, 4}, + {"ClientHelloInfo.SupportedProtos", Field, 8}, + {"ClientHelloInfo.SupportedVersions", Field, 8}, + {"ClientSessionCache", Type, 3}, + {"ClientSessionState", Type, 3}, + {"Config", Type, 0}, + {"Config.Certificates", Field, 0}, + {"Config.CipherSuites", Field, 0}, + {"Config.ClientAuth", Field, 0}, + {"Config.ClientCAs", Field, 0}, + {"Config.ClientSessionCache", Field, 3}, + {"Config.CurvePreferences", Field, 3}, + {"Config.DynamicRecordSizingDisabled", Field, 7}, + {"Config.EncryptedClientHelloConfigList", Field, 23}, + {"Config.EncryptedClientHelloRejectionVerify", Field, 23}, + {"Config.GetCertificate", Field, 4}, + {"Config.GetClientCertificate", Field, 8}, + {"Config.GetConfigForClient", Field, 8}, + {"Config.InsecureSkipVerify", Field, 0}, + {"Config.KeyLogWriter", Field, 8}, + {"Config.MaxVersion", Field, 2}, + {"Config.MinVersion", Field, 2}, + {"Config.NameToCertificate", Field, 0}, + {"Config.NextProtos", Field, 0}, + {"Config.PreferServerCipherSuites", Field, 1}, + {"Config.Rand", Field, 0}, + {"Config.Renegotiation", Field, 7}, + {"Config.RootCAs", Field, 0}, + {"Config.ServerName", Field, 0}, + {"Config.SessionTicketKey", Field, 1}, + {"Config.SessionTicketsDisabled", Field, 1}, + {"Config.Time", Field, 0}, + {"Config.UnwrapSession", Field, 21}, + {"Config.VerifyConnection", Field, 15}, + {"Config.VerifyPeerCertificate", Field, 8}, + {"Config.WrapSession", Field, 21}, + {"Conn", Type, 0}, + {"ConnectionState", Type, 0}, + {"ConnectionState.CipherSuite", Field, 0}, + {"ConnectionState.DidResume", Field, 1}, + {"ConnectionState.ECHAccepted", Field, 23}, + {"ConnectionState.HandshakeComplete", Field, 0}, + {"ConnectionState.NegotiatedProtocol", Field, 0}, + {"ConnectionState.NegotiatedProtocolIsMutual", Field, 0}, + {"ConnectionState.OCSPResponse", Field, 5}, + {"ConnectionState.PeerCertificates", Field, 0}, + {"ConnectionState.ServerName", Field, 0}, + {"ConnectionState.SignedCertificateTimestamps", Field, 5}, + {"ConnectionState.TLSUnique", Field, 4}, + {"ConnectionState.VerifiedChains", Field, 0}, + {"ConnectionState.Version", Field, 3}, + {"CurveID", Type, 3}, + {"CurveP256", Const, 3}, + {"CurveP384", Const, 3}, + {"CurveP521", Const, 3}, + {"Dial", Func, 0}, + {"DialWithDialer", Func, 3}, + {"Dialer", Type, 15}, + {"Dialer.Config", Field, 15}, + {"Dialer.NetDialer", Field, 15}, + {"ECDSAWithP256AndSHA256", Const, 8}, + {"ECDSAWithP384AndSHA384", Const, 8}, + {"ECDSAWithP521AndSHA512", Const, 8}, + {"ECDSAWithSHA1", Const, 10}, + {"ECHRejectionError", Type, 23}, + {"ECHRejectionError.RetryConfigList", Field, 23}, + {"Ed25519", Const, 13}, + {"InsecureCipherSuites", Func, 14}, + {"Listen", Func, 0}, + {"LoadX509KeyPair", Func, 0}, + {"NewLRUClientSessionCache", Func, 3}, + {"NewListener", Func, 0}, + {"NewResumptionState", Func, 21}, + {"NoClientCert", Const, 0}, + {"PKCS1WithSHA1", Const, 8}, + {"PKCS1WithSHA256", Const, 8}, + {"PKCS1WithSHA384", Const, 8}, + {"PKCS1WithSHA512", Const, 8}, + {"PSSWithSHA256", Const, 8}, + {"PSSWithSHA384", Const, 8}, + {"PSSWithSHA512", Const, 8}, + {"ParseSessionState", Func, 21}, + {"QUICClient", Func, 21}, + {"QUICConfig", Type, 21}, + {"QUICConfig.EnableSessionEvents", Field, 23}, + {"QUICConfig.TLSConfig", Field, 21}, + {"QUICConn", Type, 21}, + {"QUICEncryptionLevel", Type, 21}, + {"QUICEncryptionLevelApplication", Const, 21}, + {"QUICEncryptionLevelEarly", Const, 21}, + {"QUICEncryptionLevelHandshake", Const, 21}, + {"QUICEncryptionLevelInitial", Const, 21}, + {"QUICEvent", Type, 21}, + {"QUICEvent.Data", Field, 21}, + {"QUICEvent.Kind", Field, 21}, + {"QUICEvent.Level", Field, 21}, + {"QUICEvent.SessionState", Field, 23}, + {"QUICEvent.Suite", Field, 21}, + {"QUICEventKind", Type, 21}, + {"QUICHandshakeDone", Const, 21}, + {"QUICNoEvent", Const, 21}, + {"QUICRejectedEarlyData", Const, 21}, + {"QUICResumeSession", Const, 23}, + {"QUICServer", Func, 21}, + {"QUICSessionTicketOptions", Type, 21}, + {"QUICSessionTicketOptions.EarlyData", Field, 21}, + {"QUICSessionTicketOptions.Extra", Field, 23}, + {"QUICSetReadSecret", Const, 21}, + {"QUICSetWriteSecret", Const, 21}, + {"QUICStoreSession", Const, 23}, + {"QUICTransportParameters", Const, 21}, + {"QUICTransportParametersRequired", Const, 21}, + {"QUICWriteData", Const, 21}, + {"RecordHeaderError", Type, 6}, + {"RecordHeaderError.Conn", Field, 12}, + {"RecordHeaderError.Msg", Field, 6}, + {"RecordHeaderError.RecordHeader", Field, 6}, + {"RenegotiateFreelyAsClient", Const, 7}, + {"RenegotiateNever", Const, 7}, + {"RenegotiateOnceAsClient", Const, 7}, + {"RenegotiationSupport", Type, 7}, + {"RequestClientCert", Const, 0}, + {"RequireAndVerifyClientCert", Const, 0}, + {"RequireAnyClientCert", Const, 0}, + {"Server", Func, 0}, + {"SessionState", Type, 21}, + {"SessionState.EarlyData", Field, 21}, + {"SessionState.Extra", Field, 21}, + {"SignatureScheme", Type, 8}, + {"TLS_AES_128_GCM_SHA256", Const, 12}, + {"TLS_AES_256_GCM_SHA384", Const, 12}, + {"TLS_CHACHA20_POLY1305_SHA256", Const, 12}, + {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", Const, 2}, + {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", Const, 8}, + {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", Const, 2}, + {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", Const, 2}, + {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", Const, 5}, + {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", Const, 8}, + {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14}, + {"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", Const, 2}, + {"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0}, + {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", Const, 0}, + {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", Const, 8}, + {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", Const, 2}, + {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", Const, 1}, + {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", Const, 5}, + {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", Const, 8}, + {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14}, + {"TLS_ECDHE_RSA_WITH_RC4_128_SHA", Const, 0}, + {"TLS_FALLBACK_SCSV", Const, 4}, + {"TLS_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0}, + {"TLS_RSA_WITH_AES_128_CBC_SHA", Const, 0}, + {"TLS_RSA_WITH_AES_128_CBC_SHA256", Const, 8}, + {"TLS_RSA_WITH_AES_128_GCM_SHA256", Const, 6}, + {"TLS_RSA_WITH_AES_256_CBC_SHA", Const, 1}, + {"TLS_RSA_WITH_AES_256_GCM_SHA384", Const, 6}, + {"TLS_RSA_WITH_RC4_128_SHA", Const, 0}, + {"VerifyClientCertIfGiven", Const, 0}, + {"VersionName", Func, 21}, + {"VersionSSL30", Const, 2}, + {"VersionTLS10", Const, 2}, + {"VersionTLS11", Const, 2}, + {"VersionTLS12", Const, 2}, + {"VersionTLS13", Const, 12}, + {"X25519", Const, 8}, + {"X509KeyPair", Func, 0}, + }, + "crypto/x509": { + {"(*CertPool).AddCert", Method, 0}, + {"(*CertPool).AddCertWithConstraint", Method, 22}, + {"(*CertPool).AppendCertsFromPEM", Method, 0}, + {"(*CertPool).Clone", Method, 19}, + {"(*CertPool).Equal", Method, 19}, + {"(*CertPool).Subjects", Method, 0}, + {"(*Certificate).CheckCRLSignature", Method, 0}, + {"(*Certificate).CheckSignature", Method, 0}, + {"(*Certificate).CheckSignatureFrom", Method, 0}, + {"(*Certificate).CreateCRL", Method, 0}, + {"(*Certificate).Equal", Method, 0}, + {"(*Certificate).Verify", Method, 0}, + {"(*Certificate).VerifyHostname", Method, 0}, + {"(*CertificateRequest).CheckSignature", Method, 5}, + {"(*OID).UnmarshalBinary", Method, 23}, + {"(*OID).UnmarshalText", Method, 23}, + {"(*RevocationList).CheckSignatureFrom", Method, 19}, + {"(CertificateInvalidError).Error", Method, 0}, + {"(ConstraintViolationError).Error", Method, 0}, + {"(HostnameError).Error", Method, 0}, + {"(InsecureAlgorithmError).Error", Method, 6}, + {"(OID).Equal", Method, 22}, + {"(OID).EqualASN1OID", Method, 22}, + {"(OID).MarshalBinary", Method, 23}, + {"(OID).MarshalText", Method, 23}, + {"(OID).String", Method, 22}, + {"(PublicKeyAlgorithm).String", Method, 10}, + {"(SignatureAlgorithm).String", Method, 6}, + {"(SystemRootsError).Error", Method, 1}, + {"(SystemRootsError).Unwrap", Method, 16}, + {"(UnhandledCriticalExtension).Error", Method, 0}, + {"(UnknownAuthorityError).Error", Method, 0}, + {"CANotAuthorizedForExtKeyUsage", Const, 10}, + {"CANotAuthorizedForThisName", Const, 0}, + {"CertPool", Type, 0}, + {"Certificate", Type, 0}, + {"Certificate.AuthorityKeyId", Field, 0}, + {"Certificate.BasicConstraintsValid", Field, 0}, + {"Certificate.CRLDistributionPoints", Field, 2}, + {"Certificate.DNSNames", Field, 0}, + {"Certificate.EmailAddresses", Field, 0}, + {"Certificate.ExcludedDNSDomains", Field, 9}, + {"Certificate.ExcludedEmailAddresses", Field, 10}, + {"Certificate.ExcludedIPRanges", Field, 10}, + {"Certificate.ExcludedURIDomains", Field, 10}, + {"Certificate.ExtKeyUsage", Field, 0}, + {"Certificate.Extensions", Field, 2}, + {"Certificate.ExtraExtensions", Field, 2}, + {"Certificate.IPAddresses", Field, 1}, + {"Certificate.IsCA", Field, 0}, + {"Certificate.Issuer", Field, 0}, + {"Certificate.IssuingCertificateURL", Field, 2}, + {"Certificate.KeyUsage", Field, 0}, + {"Certificate.MaxPathLen", Field, 0}, + {"Certificate.MaxPathLenZero", Field, 4}, + {"Certificate.NotAfter", Field, 0}, + {"Certificate.NotBefore", Field, 0}, + {"Certificate.OCSPServer", Field, 2}, + {"Certificate.PermittedDNSDomains", Field, 0}, + {"Certificate.PermittedDNSDomainsCritical", Field, 0}, + {"Certificate.PermittedEmailAddresses", Field, 10}, + {"Certificate.PermittedIPRanges", Field, 10}, + {"Certificate.PermittedURIDomains", Field, 10}, + {"Certificate.Policies", Field, 22}, + {"Certificate.PolicyIdentifiers", Field, 0}, + {"Certificate.PublicKey", Field, 0}, + {"Certificate.PublicKeyAlgorithm", Field, 0}, + {"Certificate.Raw", Field, 0}, + {"Certificate.RawIssuer", Field, 0}, + {"Certificate.RawSubject", Field, 0}, + {"Certificate.RawSubjectPublicKeyInfo", Field, 0}, + {"Certificate.RawTBSCertificate", Field, 0}, + {"Certificate.SerialNumber", Field, 0}, + {"Certificate.Signature", Field, 0}, + {"Certificate.SignatureAlgorithm", Field, 0}, + {"Certificate.Subject", Field, 0}, + {"Certificate.SubjectKeyId", Field, 0}, + {"Certificate.URIs", Field, 10}, + {"Certificate.UnhandledCriticalExtensions", Field, 5}, + {"Certificate.UnknownExtKeyUsage", Field, 0}, + {"Certificate.Version", Field, 0}, + {"CertificateInvalidError", Type, 0}, + {"CertificateInvalidError.Cert", Field, 0}, + {"CertificateInvalidError.Detail", Field, 10}, + {"CertificateInvalidError.Reason", Field, 0}, + {"CertificateRequest", Type, 3}, + {"CertificateRequest.Attributes", Field, 3}, + {"CertificateRequest.DNSNames", Field, 3}, + {"CertificateRequest.EmailAddresses", Field, 3}, + {"CertificateRequest.Extensions", Field, 3}, + {"CertificateRequest.ExtraExtensions", Field, 3}, + {"CertificateRequest.IPAddresses", Field, 3}, + {"CertificateRequest.PublicKey", Field, 3}, + {"CertificateRequest.PublicKeyAlgorithm", Field, 3}, + {"CertificateRequest.Raw", Field, 3}, + {"CertificateRequest.RawSubject", Field, 3}, + {"CertificateRequest.RawSubjectPublicKeyInfo", Field, 3}, + {"CertificateRequest.RawTBSCertificateRequest", Field, 3}, + {"CertificateRequest.Signature", Field, 3}, + {"CertificateRequest.SignatureAlgorithm", Field, 3}, + {"CertificateRequest.Subject", Field, 3}, + {"CertificateRequest.URIs", Field, 10}, + {"CertificateRequest.Version", Field, 3}, + {"ConstraintViolationError", Type, 0}, + {"CreateCertificate", Func, 0}, + {"CreateCertificateRequest", Func, 3}, + {"CreateRevocationList", Func, 15}, + {"DSA", Const, 0}, + {"DSAWithSHA1", Const, 0}, + {"DSAWithSHA256", Const, 0}, + {"DecryptPEMBlock", Func, 1}, + {"ECDSA", Const, 1}, + {"ECDSAWithSHA1", Const, 1}, + {"ECDSAWithSHA256", Const, 1}, + {"ECDSAWithSHA384", Const, 1}, + {"ECDSAWithSHA512", Const, 1}, + {"Ed25519", Const, 13}, + {"EncryptPEMBlock", Func, 1}, + {"ErrUnsupportedAlgorithm", Var, 0}, + {"Expired", Const, 0}, + {"ExtKeyUsage", Type, 0}, + {"ExtKeyUsageAny", Const, 0}, + {"ExtKeyUsageClientAuth", Const, 0}, + {"ExtKeyUsageCodeSigning", Const, 0}, + {"ExtKeyUsageEmailProtection", Const, 0}, + {"ExtKeyUsageIPSECEndSystem", Const, 1}, + {"ExtKeyUsageIPSECTunnel", Const, 1}, + {"ExtKeyUsageIPSECUser", Const, 1}, + {"ExtKeyUsageMicrosoftCommercialCodeSigning", Const, 10}, + {"ExtKeyUsageMicrosoftKernelCodeSigning", Const, 10}, + {"ExtKeyUsageMicrosoftServerGatedCrypto", Const, 1}, + {"ExtKeyUsageNetscapeServerGatedCrypto", Const, 1}, + {"ExtKeyUsageOCSPSigning", Const, 0}, + {"ExtKeyUsageServerAuth", Const, 0}, + {"ExtKeyUsageTimeStamping", Const, 0}, + {"HostnameError", Type, 0}, + {"HostnameError.Certificate", Field, 0}, + {"HostnameError.Host", Field, 0}, + {"IncompatibleUsage", Const, 1}, + {"IncorrectPasswordError", Var, 1}, + {"InsecureAlgorithmError", Type, 6}, + {"InvalidReason", Type, 0}, + {"IsEncryptedPEMBlock", Func, 1}, + {"KeyUsage", Type, 0}, + {"KeyUsageCRLSign", Const, 0}, + {"KeyUsageCertSign", Const, 0}, + {"KeyUsageContentCommitment", Const, 0}, + {"KeyUsageDataEncipherment", Const, 0}, + {"KeyUsageDecipherOnly", Const, 0}, + {"KeyUsageDigitalSignature", Const, 0}, + {"KeyUsageEncipherOnly", Const, 0}, + {"KeyUsageKeyAgreement", Const, 0}, + {"KeyUsageKeyEncipherment", Const, 0}, + {"MD2WithRSA", Const, 0}, + {"MD5WithRSA", Const, 0}, + {"MarshalECPrivateKey", Func, 2}, + {"MarshalPKCS1PrivateKey", Func, 0}, + {"MarshalPKCS1PublicKey", Func, 10}, + {"MarshalPKCS8PrivateKey", Func, 10}, + {"MarshalPKIXPublicKey", Func, 0}, + {"NameConstraintsWithoutSANs", Const, 10}, + {"NameMismatch", Const, 8}, + {"NewCertPool", Func, 0}, + {"NotAuthorizedToSign", Const, 0}, + {"OID", Type, 22}, + {"OIDFromInts", Func, 22}, + {"PEMCipher", Type, 1}, + {"PEMCipher3DES", Const, 1}, + {"PEMCipherAES128", Const, 1}, + {"PEMCipherAES192", Const, 1}, + {"PEMCipherAES256", Const, 1}, + {"PEMCipherDES", Const, 1}, + {"ParseCRL", Func, 0}, + {"ParseCertificate", Func, 0}, + {"ParseCertificateRequest", Func, 3}, + {"ParseCertificates", Func, 0}, + {"ParseDERCRL", Func, 0}, + {"ParseECPrivateKey", Func, 1}, + {"ParseOID", Func, 23}, + {"ParsePKCS1PrivateKey", Func, 0}, + {"ParsePKCS1PublicKey", Func, 10}, + {"ParsePKCS8PrivateKey", Func, 0}, + {"ParsePKIXPublicKey", Func, 0}, + {"ParseRevocationList", Func, 19}, + {"PublicKeyAlgorithm", Type, 0}, + {"PureEd25519", Const, 13}, + {"RSA", Const, 0}, + {"RevocationList", Type, 15}, + {"RevocationList.AuthorityKeyId", Field, 19}, + {"RevocationList.Extensions", Field, 19}, + {"RevocationList.ExtraExtensions", Field, 15}, + {"RevocationList.Issuer", Field, 19}, + {"RevocationList.NextUpdate", Field, 15}, + {"RevocationList.Number", Field, 15}, + {"RevocationList.Raw", Field, 19}, + {"RevocationList.RawIssuer", Field, 19}, + {"RevocationList.RawTBSRevocationList", Field, 19}, + {"RevocationList.RevokedCertificateEntries", Field, 21}, + {"RevocationList.RevokedCertificates", Field, 15}, + {"RevocationList.Signature", Field, 19}, + {"RevocationList.SignatureAlgorithm", Field, 15}, + {"RevocationList.ThisUpdate", Field, 15}, + {"RevocationListEntry", Type, 21}, + {"RevocationListEntry.Extensions", Field, 21}, + {"RevocationListEntry.ExtraExtensions", Field, 21}, + {"RevocationListEntry.Raw", Field, 21}, + {"RevocationListEntry.ReasonCode", Field, 21}, + {"RevocationListEntry.RevocationTime", Field, 21}, + {"RevocationListEntry.SerialNumber", Field, 21}, + {"SHA1WithRSA", Const, 0}, + {"SHA256WithRSA", Const, 0}, + {"SHA256WithRSAPSS", Const, 8}, + {"SHA384WithRSA", Const, 0}, + {"SHA384WithRSAPSS", Const, 8}, + {"SHA512WithRSA", Const, 0}, + {"SHA512WithRSAPSS", Const, 8}, + {"SetFallbackRoots", Func, 20}, + {"SignatureAlgorithm", Type, 0}, + {"SystemCertPool", Func, 7}, + {"SystemRootsError", Type, 1}, + {"SystemRootsError.Err", Field, 7}, + {"TooManyConstraints", Const, 10}, + {"TooManyIntermediates", Const, 0}, + {"UnconstrainedName", Const, 10}, + {"UnhandledCriticalExtension", Type, 0}, + {"UnknownAuthorityError", Type, 0}, + {"UnknownAuthorityError.Cert", Field, 8}, + {"UnknownPublicKeyAlgorithm", Const, 0}, + {"UnknownSignatureAlgorithm", Const, 0}, + {"VerifyOptions", Type, 0}, + {"VerifyOptions.CurrentTime", Field, 0}, + {"VerifyOptions.DNSName", Field, 0}, + {"VerifyOptions.Intermediates", Field, 0}, + {"VerifyOptions.KeyUsages", Field, 1}, + {"VerifyOptions.MaxConstraintComparisions", Field, 10}, + {"VerifyOptions.Roots", Field, 0}, + }, + "crypto/x509/pkix": { + {"(*CertificateList).HasExpired", Method, 0}, + {"(*Name).FillFromRDNSequence", Method, 0}, + {"(Name).String", Method, 10}, + {"(Name).ToRDNSequence", Method, 0}, + {"(RDNSequence).String", Method, 10}, + {"AlgorithmIdentifier", Type, 0}, + {"AlgorithmIdentifier.Algorithm", Field, 0}, + {"AlgorithmIdentifier.Parameters", Field, 0}, + {"AttributeTypeAndValue", Type, 0}, + {"AttributeTypeAndValue.Type", Field, 0}, + {"AttributeTypeAndValue.Value", Field, 0}, + {"AttributeTypeAndValueSET", Type, 3}, + {"AttributeTypeAndValueSET.Type", Field, 3}, + {"AttributeTypeAndValueSET.Value", Field, 3}, + {"CertificateList", Type, 0}, + {"CertificateList.SignatureAlgorithm", Field, 0}, + {"CertificateList.SignatureValue", Field, 0}, + {"CertificateList.TBSCertList", Field, 0}, + {"Extension", Type, 0}, + {"Extension.Critical", Field, 0}, + {"Extension.Id", Field, 0}, + {"Extension.Value", Field, 0}, + {"Name", Type, 0}, + {"Name.CommonName", Field, 0}, + {"Name.Country", Field, 0}, + {"Name.ExtraNames", Field, 5}, + {"Name.Locality", Field, 0}, + {"Name.Names", Field, 0}, + {"Name.Organization", Field, 0}, + {"Name.OrganizationalUnit", Field, 0}, + {"Name.PostalCode", Field, 0}, + {"Name.Province", Field, 0}, + {"Name.SerialNumber", Field, 0}, + {"Name.StreetAddress", Field, 0}, + {"RDNSequence", Type, 0}, + {"RelativeDistinguishedNameSET", Type, 0}, + {"RevokedCertificate", Type, 0}, + {"RevokedCertificate.Extensions", Field, 0}, + {"RevokedCertificate.RevocationTime", Field, 0}, + {"RevokedCertificate.SerialNumber", Field, 0}, + {"TBSCertificateList", Type, 0}, + {"TBSCertificateList.Extensions", Field, 0}, + {"TBSCertificateList.Issuer", Field, 0}, + {"TBSCertificateList.NextUpdate", Field, 0}, + {"TBSCertificateList.Raw", Field, 0}, + {"TBSCertificateList.RevokedCertificates", Field, 0}, + {"TBSCertificateList.Signature", Field, 0}, + {"TBSCertificateList.ThisUpdate", Field, 0}, + {"TBSCertificateList.Version", Field, 0}, + }, + "database/sql": { + {"(*ColumnType).DatabaseTypeName", Method, 8}, + {"(*ColumnType).DecimalSize", Method, 8}, + {"(*ColumnType).Length", Method, 8}, + {"(*ColumnType).Name", Method, 8}, + {"(*ColumnType).Nullable", Method, 8}, + {"(*ColumnType).ScanType", Method, 8}, + {"(*Conn).BeginTx", Method, 9}, + {"(*Conn).Close", Method, 9}, + {"(*Conn).ExecContext", Method, 9}, + {"(*Conn).PingContext", Method, 9}, + {"(*Conn).PrepareContext", Method, 9}, + {"(*Conn).QueryContext", Method, 9}, + {"(*Conn).QueryRowContext", Method, 9}, + {"(*Conn).Raw", Method, 13}, + {"(*DB).Begin", Method, 0}, + {"(*DB).BeginTx", Method, 8}, + {"(*DB).Close", Method, 0}, + {"(*DB).Conn", Method, 9}, + {"(*DB).Driver", Method, 0}, + {"(*DB).Exec", Method, 0}, + {"(*DB).ExecContext", Method, 8}, + {"(*DB).Ping", Method, 1}, + {"(*DB).PingContext", Method, 8}, + {"(*DB).Prepare", Method, 0}, + {"(*DB).PrepareContext", Method, 8}, + {"(*DB).Query", Method, 0}, + {"(*DB).QueryContext", Method, 8}, + {"(*DB).QueryRow", Method, 0}, + {"(*DB).QueryRowContext", Method, 8}, + {"(*DB).SetConnMaxIdleTime", Method, 15}, + {"(*DB).SetConnMaxLifetime", Method, 6}, + {"(*DB).SetMaxIdleConns", Method, 1}, + {"(*DB).SetMaxOpenConns", Method, 2}, + {"(*DB).Stats", Method, 5}, + {"(*Null).Scan", Method, 22}, + {"(*NullBool).Scan", Method, 0}, + {"(*NullByte).Scan", Method, 17}, + {"(*NullFloat64).Scan", Method, 0}, + {"(*NullInt16).Scan", Method, 17}, + {"(*NullInt32).Scan", Method, 13}, + {"(*NullInt64).Scan", Method, 0}, + {"(*NullString).Scan", Method, 0}, + {"(*NullTime).Scan", Method, 13}, + {"(*Row).Err", Method, 15}, + {"(*Row).Scan", Method, 0}, + {"(*Rows).Close", Method, 0}, + {"(*Rows).ColumnTypes", Method, 8}, + {"(*Rows).Columns", Method, 0}, + {"(*Rows).Err", Method, 0}, + {"(*Rows).Next", Method, 0}, + {"(*Rows).NextResultSet", Method, 8}, + {"(*Rows).Scan", Method, 0}, + {"(*Stmt).Close", Method, 0}, + {"(*Stmt).Exec", Method, 0}, + {"(*Stmt).ExecContext", Method, 8}, + {"(*Stmt).Query", Method, 0}, + {"(*Stmt).QueryContext", Method, 8}, + {"(*Stmt).QueryRow", Method, 0}, + {"(*Stmt).QueryRowContext", Method, 8}, + {"(*Tx).Commit", Method, 0}, + {"(*Tx).Exec", Method, 0}, + {"(*Tx).ExecContext", Method, 8}, + {"(*Tx).Prepare", Method, 0}, + {"(*Tx).PrepareContext", Method, 8}, + {"(*Tx).Query", Method, 0}, + {"(*Tx).QueryContext", Method, 8}, + {"(*Tx).QueryRow", Method, 0}, + {"(*Tx).QueryRowContext", Method, 8}, + {"(*Tx).Rollback", Method, 0}, + {"(*Tx).Stmt", Method, 0}, + {"(*Tx).StmtContext", Method, 8}, + {"(IsolationLevel).String", Method, 11}, + {"(Null).Value", Method, 22}, + {"(NullBool).Value", Method, 0}, + {"(NullByte).Value", Method, 17}, + {"(NullFloat64).Value", Method, 0}, + {"(NullInt16).Value", Method, 17}, + {"(NullInt32).Value", Method, 13}, + {"(NullInt64).Value", Method, 0}, + {"(NullString).Value", Method, 0}, + {"(NullTime).Value", Method, 13}, + {"ColumnType", Type, 8}, + {"Conn", Type, 9}, + {"DB", Type, 0}, + {"DBStats", Type, 5}, + {"DBStats.Idle", Field, 11}, + {"DBStats.InUse", Field, 11}, + {"DBStats.MaxIdleClosed", Field, 11}, + {"DBStats.MaxIdleTimeClosed", Field, 15}, + {"DBStats.MaxLifetimeClosed", Field, 11}, + {"DBStats.MaxOpenConnections", Field, 11}, + {"DBStats.OpenConnections", Field, 5}, + {"DBStats.WaitCount", Field, 11}, + {"DBStats.WaitDuration", Field, 11}, + {"Drivers", Func, 4}, + {"ErrConnDone", Var, 9}, + {"ErrNoRows", Var, 0}, + {"ErrTxDone", Var, 0}, + {"IsolationLevel", Type, 8}, + {"LevelDefault", Const, 8}, + {"LevelLinearizable", Const, 8}, + {"LevelReadCommitted", Const, 8}, + {"LevelReadUncommitted", Const, 8}, + {"LevelRepeatableRead", Const, 8}, + {"LevelSerializable", Const, 8}, + {"LevelSnapshot", Const, 8}, + {"LevelWriteCommitted", Const, 8}, + {"Named", Func, 8}, + {"NamedArg", Type, 8}, + {"NamedArg.Name", Field, 8}, + {"NamedArg.Value", Field, 8}, + {"Null", Type, 22}, + {"Null.V", Field, 22}, + {"Null.Valid", Field, 22}, + {"NullBool", Type, 0}, + {"NullBool.Bool", Field, 0}, + {"NullBool.Valid", Field, 0}, + {"NullByte", Type, 17}, + {"NullByte.Byte", Field, 17}, + {"NullByte.Valid", Field, 17}, + {"NullFloat64", Type, 0}, + {"NullFloat64.Float64", Field, 0}, + {"NullFloat64.Valid", Field, 0}, + {"NullInt16", Type, 17}, + {"NullInt16.Int16", Field, 17}, + {"NullInt16.Valid", Field, 17}, + {"NullInt32", Type, 13}, + {"NullInt32.Int32", Field, 13}, + {"NullInt32.Valid", Field, 13}, + {"NullInt64", Type, 0}, + {"NullInt64.Int64", Field, 0}, + {"NullInt64.Valid", Field, 0}, + {"NullString", Type, 0}, + {"NullString.String", Field, 0}, + {"NullString.Valid", Field, 0}, + {"NullTime", Type, 13}, + {"NullTime.Time", Field, 13}, + {"NullTime.Valid", Field, 13}, + {"Open", Func, 0}, + {"OpenDB", Func, 10}, + {"Out", Type, 9}, + {"Out.Dest", Field, 9}, + {"Out.In", Field, 9}, + {"RawBytes", Type, 0}, + {"Register", Func, 0}, + {"Result", Type, 0}, + {"Row", Type, 0}, + {"Rows", Type, 0}, + {"Scanner", Type, 0}, + {"Stmt", Type, 0}, + {"Tx", Type, 0}, + {"TxOptions", Type, 8}, + {"TxOptions.Isolation", Field, 8}, + {"TxOptions.ReadOnly", Field, 8}, + }, + "database/sql/driver": { + {"(NotNull).ConvertValue", Method, 0}, + {"(Null).ConvertValue", Method, 0}, + {"(RowsAffected).LastInsertId", Method, 0}, + {"(RowsAffected).RowsAffected", Method, 0}, + {"Bool", Var, 0}, + {"ColumnConverter", Type, 0}, + {"Conn", Type, 0}, + {"ConnBeginTx", Type, 8}, + {"ConnPrepareContext", Type, 8}, + {"Connector", Type, 10}, + {"DefaultParameterConverter", Var, 0}, + {"Driver", Type, 0}, + {"DriverContext", Type, 10}, + {"ErrBadConn", Var, 0}, + {"ErrRemoveArgument", Var, 9}, + {"ErrSkip", Var, 0}, + {"Execer", Type, 0}, + {"ExecerContext", Type, 8}, + {"Int32", Var, 0}, + {"IsScanValue", Func, 0}, + {"IsValue", Func, 0}, + {"IsolationLevel", Type, 8}, + {"NamedValue", Type, 8}, + {"NamedValue.Name", Field, 8}, + {"NamedValue.Ordinal", Field, 8}, + {"NamedValue.Value", Field, 8}, + {"NamedValueChecker", Type, 9}, + {"NotNull", Type, 0}, + {"NotNull.Converter", Field, 0}, + {"Null", Type, 0}, + {"Null.Converter", Field, 0}, + {"Pinger", Type, 8}, + {"Queryer", Type, 1}, + {"QueryerContext", Type, 8}, + {"Result", Type, 0}, + {"ResultNoRows", Var, 0}, + {"Rows", Type, 0}, + {"RowsAffected", Type, 0}, + {"RowsColumnTypeDatabaseTypeName", Type, 8}, + {"RowsColumnTypeLength", Type, 8}, + {"RowsColumnTypeNullable", Type, 8}, + {"RowsColumnTypePrecisionScale", Type, 8}, + {"RowsColumnTypeScanType", Type, 8}, + {"RowsNextResultSet", Type, 8}, + {"SessionResetter", Type, 10}, + {"Stmt", Type, 0}, + {"StmtExecContext", Type, 8}, + {"StmtQueryContext", Type, 8}, + {"String", Var, 0}, + {"Tx", Type, 0}, + {"TxOptions", Type, 8}, + {"TxOptions.Isolation", Field, 8}, + {"TxOptions.ReadOnly", Field, 8}, + {"Validator", Type, 15}, + {"Value", Type, 0}, + {"ValueConverter", Type, 0}, + {"Valuer", Type, 0}, + }, + "debug/buildinfo": { + {"BuildInfo", Type, 18}, + {"Read", Func, 18}, + {"ReadFile", Func, 18}, + }, + "debug/dwarf": { + {"(*AddrType).Basic", Method, 0}, + {"(*AddrType).Common", Method, 0}, + {"(*AddrType).Size", Method, 0}, + {"(*AddrType).String", Method, 0}, + {"(*ArrayType).Common", Method, 0}, + {"(*ArrayType).Size", Method, 0}, + {"(*ArrayType).String", Method, 0}, + {"(*BasicType).Basic", Method, 0}, + {"(*BasicType).Common", Method, 0}, + {"(*BasicType).Size", Method, 0}, + {"(*BasicType).String", Method, 0}, + {"(*BoolType).Basic", Method, 0}, + {"(*BoolType).Common", Method, 0}, + {"(*BoolType).Size", Method, 0}, + {"(*BoolType).String", Method, 0}, + {"(*CharType).Basic", Method, 0}, + {"(*CharType).Common", Method, 0}, + {"(*CharType).Size", Method, 0}, + {"(*CharType).String", Method, 0}, + {"(*CommonType).Common", Method, 0}, + {"(*CommonType).Size", Method, 0}, + {"(*ComplexType).Basic", Method, 0}, + {"(*ComplexType).Common", Method, 0}, + {"(*ComplexType).Size", Method, 0}, + {"(*ComplexType).String", Method, 0}, + {"(*Data).AddSection", Method, 14}, + {"(*Data).AddTypes", Method, 3}, + {"(*Data).LineReader", Method, 5}, + {"(*Data).Ranges", Method, 7}, + {"(*Data).Reader", Method, 0}, + {"(*Data).Type", Method, 0}, + {"(*DotDotDotType).Common", Method, 0}, + {"(*DotDotDotType).Size", Method, 0}, + {"(*DotDotDotType).String", Method, 0}, + {"(*Entry).AttrField", Method, 5}, + {"(*Entry).Val", Method, 0}, + {"(*EnumType).Common", Method, 0}, + {"(*EnumType).Size", Method, 0}, + {"(*EnumType).String", Method, 0}, + {"(*FloatType).Basic", Method, 0}, + {"(*FloatType).Common", Method, 0}, + {"(*FloatType).Size", Method, 0}, + {"(*FloatType).String", Method, 0}, + {"(*FuncType).Common", Method, 0}, + {"(*FuncType).Size", Method, 0}, + {"(*FuncType).String", Method, 0}, + {"(*IntType).Basic", Method, 0}, + {"(*IntType).Common", Method, 0}, + {"(*IntType).Size", Method, 0}, + {"(*IntType).String", Method, 0}, + {"(*LineReader).Files", Method, 14}, + {"(*LineReader).Next", Method, 5}, + {"(*LineReader).Reset", Method, 5}, + {"(*LineReader).Seek", Method, 5}, + {"(*LineReader).SeekPC", Method, 5}, + {"(*LineReader).Tell", Method, 5}, + {"(*PtrType).Common", Method, 0}, + {"(*PtrType).Size", Method, 0}, + {"(*PtrType).String", Method, 0}, + {"(*QualType).Common", Method, 0}, + {"(*QualType).Size", Method, 0}, + {"(*QualType).String", Method, 0}, + {"(*Reader).AddressSize", Method, 5}, + {"(*Reader).ByteOrder", Method, 14}, + {"(*Reader).Next", Method, 0}, + {"(*Reader).Seek", Method, 0}, + {"(*Reader).SeekPC", Method, 7}, + {"(*Reader).SkipChildren", Method, 0}, + {"(*StructType).Common", Method, 0}, + {"(*StructType).Defn", Method, 0}, + {"(*StructType).Size", Method, 0}, + {"(*StructType).String", Method, 0}, + {"(*TypedefType).Common", Method, 0}, + {"(*TypedefType).Size", Method, 0}, + {"(*TypedefType).String", Method, 0}, + {"(*UcharType).Basic", Method, 0}, + {"(*UcharType).Common", Method, 0}, + {"(*UcharType).Size", Method, 0}, + {"(*UcharType).String", Method, 0}, + {"(*UintType).Basic", Method, 0}, + {"(*UintType).Common", Method, 0}, + {"(*UintType).Size", Method, 0}, + {"(*UintType).String", Method, 0}, + {"(*UnspecifiedType).Basic", Method, 4}, + {"(*UnspecifiedType).Common", Method, 4}, + {"(*UnspecifiedType).Size", Method, 4}, + {"(*UnspecifiedType).String", Method, 4}, + {"(*UnsupportedType).Common", Method, 13}, + {"(*UnsupportedType).Size", Method, 13}, + {"(*UnsupportedType).String", Method, 13}, + {"(*VoidType).Common", Method, 0}, + {"(*VoidType).Size", Method, 0}, + {"(*VoidType).String", Method, 0}, + {"(Attr).GoString", Method, 0}, + {"(Attr).String", Method, 0}, + {"(Class).GoString", Method, 5}, + {"(Class).String", Method, 5}, + {"(DecodeError).Error", Method, 0}, + {"(Tag).GoString", Method, 0}, + {"(Tag).String", Method, 0}, + {"AddrType", Type, 0}, + {"AddrType.BasicType", Field, 0}, + {"ArrayType", Type, 0}, + {"ArrayType.CommonType", Field, 0}, + {"ArrayType.Count", Field, 0}, + {"ArrayType.StrideBitSize", Field, 0}, + {"ArrayType.Type", Field, 0}, + {"Attr", Type, 0}, + {"AttrAbstractOrigin", Const, 0}, + {"AttrAccessibility", Const, 0}, + {"AttrAddrBase", Const, 14}, + {"AttrAddrClass", Const, 0}, + {"AttrAlignment", Const, 14}, + {"AttrAllocated", Const, 0}, + {"AttrArtificial", Const, 0}, + {"AttrAssociated", Const, 0}, + {"AttrBaseTypes", Const, 0}, + {"AttrBinaryScale", Const, 14}, + {"AttrBitOffset", Const, 0}, + {"AttrBitSize", Const, 0}, + {"AttrByteSize", Const, 0}, + {"AttrCallAllCalls", Const, 14}, + {"AttrCallAllSourceCalls", Const, 14}, + {"AttrCallAllTailCalls", Const, 14}, + {"AttrCallColumn", Const, 0}, + {"AttrCallDataLocation", Const, 14}, + {"AttrCallDataValue", Const, 14}, + {"AttrCallFile", Const, 0}, + {"AttrCallLine", Const, 0}, + {"AttrCallOrigin", Const, 14}, + {"AttrCallPC", Const, 14}, + {"AttrCallParameter", Const, 14}, + {"AttrCallReturnPC", Const, 14}, + {"AttrCallTailCall", Const, 14}, + {"AttrCallTarget", Const, 14}, + {"AttrCallTargetClobbered", Const, 14}, + {"AttrCallValue", Const, 14}, + {"AttrCalling", Const, 0}, + {"AttrCommonRef", Const, 0}, + {"AttrCompDir", Const, 0}, + {"AttrConstExpr", Const, 14}, + {"AttrConstValue", Const, 0}, + {"AttrContainingType", Const, 0}, + {"AttrCount", Const, 0}, + {"AttrDataBitOffset", Const, 14}, + {"AttrDataLocation", Const, 0}, + {"AttrDataMemberLoc", Const, 0}, + {"AttrDecimalScale", Const, 14}, + {"AttrDecimalSign", Const, 14}, + {"AttrDeclColumn", Const, 0}, + {"AttrDeclFile", Const, 0}, + {"AttrDeclLine", Const, 0}, + {"AttrDeclaration", Const, 0}, + {"AttrDefaultValue", Const, 0}, + {"AttrDefaulted", Const, 14}, + {"AttrDeleted", Const, 14}, + {"AttrDescription", Const, 0}, + {"AttrDigitCount", Const, 14}, + {"AttrDiscr", Const, 0}, + {"AttrDiscrList", Const, 0}, + {"AttrDiscrValue", Const, 0}, + {"AttrDwoName", Const, 14}, + {"AttrElemental", Const, 14}, + {"AttrEncoding", Const, 0}, + {"AttrEndianity", Const, 14}, + {"AttrEntrypc", Const, 0}, + {"AttrEnumClass", Const, 14}, + {"AttrExplicit", Const, 14}, + {"AttrExportSymbols", Const, 14}, + {"AttrExtension", Const, 0}, + {"AttrExternal", Const, 0}, + {"AttrFrameBase", Const, 0}, + {"AttrFriend", Const, 0}, + {"AttrHighpc", Const, 0}, + {"AttrIdentifierCase", Const, 0}, + {"AttrImport", Const, 0}, + {"AttrInline", Const, 0}, + {"AttrIsOptional", Const, 0}, + {"AttrLanguage", Const, 0}, + {"AttrLinkageName", Const, 14}, + {"AttrLocation", Const, 0}, + {"AttrLoclistsBase", Const, 14}, + {"AttrLowerBound", Const, 0}, + {"AttrLowpc", Const, 0}, + {"AttrMacroInfo", Const, 0}, + {"AttrMacros", Const, 14}, + {"AttrMainSubprogram", Const, 14}, + {"AttrMutable", Const, 14}, + {"AttrName", Const, 0}, + {"AttrNamelistItem", Const, 0}, + {"AttrNoreturn", Const, 14}, + {"AttrObjectPointer", Const, 14}, + {"AttrOrdering", Const, 0}, + {"AttrPictureString", Const, 14}, + {"AttrPriority", Const, 0}, + {"AttrProducer", Const, 0}, + {"AttrPrototyped", Const, 0}, + {"AttrPure", Const, 14}, + {"AttrRanges", Const, 0}, + {"AttrRank", Const, 14}, + {"AttrRecursive", Const, 14}, + {"AttrReference", Const, 14}, + {"AttrReturnAddr", Const, 0}, + {"AttrRnglistsBase", Const, 14}, + {"AttrRvalueReference", Const, 14}, + {"AttrSegment", Const, 0}, + {"AttrSibling", Const, 0}, + {"AttrSignature", Const, 14}, + {"AttrSmall", Const, 14}, + {"AttrSpecification", Const, 0}, + {"AttrStartScope", Const, 0}, + {"AttrStaticLink", Const, 0}, + {"AttrStmtList", Const, 0}, + {"AttrStrOffsetsBase", Const, 14}, + {"AttrStride", Const, 0}, + {"AttrStrideSize", Const, 0}, + {"AttrStringLength", Const, 0}, + {"AttrStringLengthBitSize", Const, 14}, + {"AttrStringLengthByteSize", Const, 14}, + {"AttrThreadsScaled", Const, 14}, + {"AttrTrampoline", Const, 0}, + {"AttrType", Const, 0}, + {"AttrUpperBound", Const, 0}, + {"AttrUseLocation", Const, 0}, + {"AttrUseUTF8", Const, 0}, + {"AttrVarParam", Const, 0}, + {"AttrVirtuality", Const, 0}, + {"AttrVisibility", Const, 0}, + {"AttrVtableElemLoc", Const, 0}, + {"BasicType", Type, 0}, + {"BasicType.BitOffset", Field, 0}, + {"BasicType.BitSize", Field, 0}, + {"BasicType.CommonType", Field, 0}, + {"BasicType.DataBitOffset", Field, 18}, + {"BoolType", Type, 0}, + {"BoolType.BasicType", Field, 0}, + {"CharType", Type, 0}, + {"CharType.BasicType", Field, 0}, + {"Class", Type, 5}, + {"ClassAddrPtr", Const, 14}, + {"ClassAddress", Const, 5}, + {"ClassBlock", Const, 5}, + {"ClassConstant", Const, 5}, + {"ClassExprLoc", Const, 5}, + {"ClassFlag", Const, 5}, + {"ClassLinePtr", Const, 5}, + {"ClassLocList", Const, 14}, + {"ClassLocListPtr", Const, 5}, + {"ClassMacPtr", Const, 5}, + {"ClassRangeListPtr", Const, 5}, + {"ClassReference", Const, 5}, + {"ClassReferenceAlt", Const, 5}, + {"ClassReferenceSig", Const, 5}, + {"ClassRngList", Const, 14}, + {"ClassRngListsPtr", Const, 14}, + {"ClassStrOffsetsPtr", Const, 14}, + {"ClassString", Const, 5}, + {"ClassStringAlt", Const, 5}, + {"ClassUnknown", Const, 6}, + {"CommonType", Type, 0}, + {"CommonType.ByteSize", Field, 0}, + {"CommonType.Name", Field, 0}, + {"ComplexType", Type, 0}, + {"ComplexType.BasicType", Field, 0}, + {"Data", Type, 0}, + {"DecodeError", Type, 0}, + {"DecodeError.Err", Field, 0}, + {"DecodeError.Name", Field, 0}, + {"DecodeError.Offset", Field, 0}, + {"DotDotDotType", Type, 0}, + {"DotDotDotType.CommonType", Field, 0}, + {"Entry", Type, 0}, + {"Entry.Children", Field, 0}, + {"Entry.Field", Field, 0}, + {"Entry.Offset", Field, 0}, + {"Entry.Tag", Field, 0}, + {"EnumType", Type, 0}, + {"EnumType.CommonType", Field, 0}, + {"EnumType.EnumName", Field, 0}, + {"EnumType.Val", Field, 0}, + {"EnumValue", Type, 0}, + {"EnumValue.Name", Field, 0}, + {"EnumValue.Val", Field, 0}, + {"ErrUnknownPC", Var, 5}, + {"Field", Type, 0}, + {"Field.Attr", Field, 0}, + {"Field.Class", Field, 5}, + {"Field.Val", Field, 0}, + {"FloatType", Type, 0}, + {"FloatType.BasicType", Field, 0}, + {"FuncType", Type, 0}, + {"FuncType.CommonType", Field, 0}, + {"FuncType.ParamType", Field, 0}, + {"FuncType.ReturnType", Field, 0}, + {"IntType", Type, 0}, + {"IntType.BasicType", Field, 0}, + {"LineEntry", Type, 5}, + {"LineEntry.Address", Field, 5}, + {"LineEntry.BasicBlock", Field, 5}, + {"LineEntry.Column", Field, 5}, + {"LineEntry.Discriminator", Field, 5}, + {"LineEntry.EndSequence", Field, 5}, + {"LineEntry.EpilogueBegin", Field, 5}, + {"LineEntry.File", Field, 5}, + {"LineEntry.ISA", Field, 5}, + {"LineEntry.IsStmt", Field, 5}, + {"LineEntry.Line", Field, 5}, + {"LineEntry.OpIndex", Field, 5}, + {"LineEntry.PrologueEnd", Field, 5}, + {"LineFile", Type, 5}, + {"LineFile.Length", Field, 5}, + {"LineFile.Mtime", Field, 5}, + {"LineFile.Name", Field, 5}, + {"LineReader", Type, 5}, + {"LineReaderPos", Type, 5}, + {"New", Func, 0}, + {"Offset", Type, 0}, + {"PtrType", Type, 0}, + {"PtrType.CommonType", Field, 0}, + {"PtrType.Type", Field, 0}, + {"QualType", Type, 0}, + {"QualType.CommonType", Field, 0}, + {"QualType.Qual", Field, 0}, + {"QualType.Type", Field, 0}, + {"Reader", Type, 0}, + {"StructField", Type, 0}, + {"StructField.BitOffset", Field, 0}, + {"StructField.BitSize", Field, 0}, + {"StructField.ByteOffset", Field, 0}, + {"StructField.ByteSize", Field, 0}, + {"StructField.DataBitOffset", Field, 18}, + {"StructField.Name", Field, 0}, + {"StructField.Type", Field, 0}, + {"StructType", Type, 0}, + {"StructType.CommonType", Field, 0}, + {"StructType.Field", Field, 0}, + {"StructType.Incomplete", Field, 0}, + {"StructType.Kind", Field, 0}, + {"StructType.StructName", Field, 0}, + {"Tag", Type, 0}, + {"TagAccessDeclaration", Const, 0}, + {"TagArrayType", Const, 0}, + {"TagAtomicType", Const, 14}, + {"TagBaseType", Const, 0}, + {"TagCallSite", Const, 14}, + {"TagCallSiteParameter", Const, 14}, + {"TagCatchDwarfBlock", Const, 0}, + {"TagClassType", Const, 0}, + {"TagCoarrayType", Const, 14}, + {"TagCommonDwarfBlock", Const, 0}, + {"TagCommonInclusion", Const, 0}, + {"TagCompileUnit", Const, 0}, + {"TagCondition", Const, 3}, + {"TagConstType", Const, 0}, + {"TagConstant", Const, 0}, + {"TagDwarfProcedure", Const, 0}, + {"TagDynamicType", Const, 14}, + {"TagEntryPoint", Const, 0}, + {"TagEnumerationType", Const, 0}, + {"TagEnumerator", Const, 0}, + {"TagFileType", Const, 0}, + {"TagFormalParameter", Const, 0}, + {"TagFriend", Const, 0}, + {"TagGenericSubrange", Const, 14}, + {"TagImmutableType", Const, 14}, + {"TagImportedDeclaration", Const, 0}, + {"TagImportedModule", Const, 0}, + {"TagImportedUnit", Const, 0}, + {"TagInheritance", Const, 0}, + {"TagInlinedSubroutine", Const, 0}, + {"TagInterfaceType", Const, 0}, + {"TagLabel", Const, 0}, + {"TagLexDwarfBlock", Const, 0}, + {"TagMember", Const, 0}, + {"TagModule", Const, 0}, + {"TagMutableType", Const, 0}, + {"TagNamelist", Const, 0}, + {"TagNamelistItem", Const, 0}, + {"TagNamespace", Const, 0}, + {"TagPackedType", Const, 0}, + {"TagPartialUnit", Const, 0}, + {"TagPointerType", Const, 0}, + {"TagPtrToMemberType", Const, 0}, + {"TagReferenceType", Const, 0}, + {"TagRestrictType", Const, 0}, + {"TagRvalueReferenceType", Const, 3}, + {"TagSetType", Const, 0}, + {"TagSharedType", Const, 3}, + {"TagSkeletonUnit", Const, 14}, + {"TagStringType", Const, 0}, + {"TagStructType", Const, 0}, + {"TagSubprogram", Const, 0}, + {"TagSubrangeType", Const, 0}, + {"TagSubroutineType", Const, 0}, + {"TagTemplateAlias", Const, 3}, + {"TagTemplateTypeParameter", Const, 0}, + {"TagTemplateValueParameter", Const, 0}, + {"TagThrownType", Const, 0}, + {"TagTryDwarfBlock", Const, 0}, + {"TagTypeUnit", Const, 3}, + {"TagTypedef", Const, 0}, + {"TagUnionType", Const, 0}, + {"TagUnspecifiedParameters", Const, 0}, + {"TagUnspecifiedType", Const, 0}, + {"TagVariable", Const, 0}, + {"TagVariant", Const, 0}, + {"TagVariantPart", Const, 0}, + {"TagVolatileType", Const, 0}, + {"TagWithStmt", Const, 0}, + {"Type", Type, 0}, + {"TypedefType", Type, 0}, + {"TypedefType.CommonType", Field, 0}, + {"TypedefType.Type", Field, 0}, + {"UcharType", Type, 0}, + {"UcharType.BasicType", Field, 0}, + {"UintType", Type, 0}, + {"UintType.BasicType", Field, 0}, + {"UnspecifiedType", Type, 4}, + {"UnspecifiedType.BasicType", Field, 4}, + {"UnsupportedType", Type, 13}, + {"UnsupportedType.CommonType", Field, 13}, + {"UnsupportedType.Tag", Field, 13}, + {"VoidType", Type, 0}, + {"VoidType.CommonType", Field, 0}, + }, + "debug/elf": { + {"(*File).Close", Method, 0}, + {"(*File).DWARF", Method, 0}, + {"(*File).DynString", Method, 1}, + {"(*File).DynValue", Method, 21}, + {"(*File).DynamicSymbols", Method, 4}, + {"(*File).ImportedLibraries", Method, 0}, + {"(*File).ImportedSymbols", Method, 0}, + {"(*File).Section", Method, 0}, + {"(*File).SectionByType", Method, 0}, + {"(*File).Symbols", Method, 0}, + {"(*FormatError).Error", Method, 0}, + {"(*Prog).Open", Method, 0}, + {"(*Section).Data", Method, 0}, + {"(*Section).Open", Method, 0}, + {"(Class).GoString", Method, 0}, + {"(Class).String", Method, 0}, + {"(CompressionType).GoString", Method, 6}, + {"(CompressionType).String", Method, 6}, + {"(Data).GoString", Method, 0}, + {"(Data).String", Method, 0}, + {"(DynFlag).GoString", Method, 0}, + {"(DynFlag).String", Method, 0}, + {"(DynFlag1).GoString", Method, 21}, + {"(DynFlag1).String", Method, 21}, + {"(DynTag).GoString", Method, 0}, + {"(DynTag).String", Method, 0}, + {"(Machine).GoString", Method, 0}, + {"(Machine).String", Method, 0}, + {"(NType).GoString", Method, 0}, + {"(NType).String", Method, 0}, + {"(OSABI).GoString", Method, 0}, + {"(OSABI).String", Method, 0}, + {"(Prog).ReadAt", Method, 0}, + {"(ProgFlag).GoString", Method, 0}, + {"(ProgFlag).String", Method, 0}, + {"(ProgType).GoString", Method, 0}, + {"(ProgType).String", Method, 0}, + {"(R_386).GoString", Method, 0}, + {"(R_386).String", Method, 0}, + {"(R_390).GoString", Method, 7}, + {"(R_390).String", Method, 7}, + {"(R_AARCH64).GoString", Method, 4}, + {"(R_AARCH64).String", Method, 4}, + {"(R_ALPHA).GoString", Method, 0}, + {"(R_ALPHA).String", Method, 0}, + {"(R_ARM).GoString", Method, 0}, + {"(R_ARM).String", Method, 0}, + {"(R_LARCH).GoString", Method, 19}, + {"(R_LARCH).String", Method, 19}, + {"(R_MIPS).GoString", Method, 6}, + {"(R_MIPS).String", Method, 6}, + {"(R_PPC).GoString", Method, 0}, + {"(R_PPC).String", Method, 0}, + {"(R_PPC64).GoString", Method, 5}, + {"(R_PPC64).String", Method, 5}, + {"(R_RISCV).GoString", Method, 11}, + {"(R_RISCV).String", Method, 11}, + {"(R_SPARC).GoString", Method, 0}, + {"(R_SPARC).String", Method, 0}, + {"(R_X86_64).GoString", Method, 0}, + {"(R_X86_64).String", Method, 0}, + {"(Section).ReadAt", Method, 0}, + {"(SectionFlag).GoString", Method, 0}, + {"(SectionFlag).String", Method, 0}, + {"(SectionIndex).GoString", Method, 0}, + {"(SectionIndex).String", Method, 0}, + {"(SectionType).GoString", Method, 0}, + {"(SectionType).String", Method, 0}, + {"(SymBind).GoString", Method, 0}, + {"(SymBind).String", Method, 0}, + {"(SymType).GoString", Method, 0}, + {"(SymType).String", Method, 0}, + {"(SymVis).GoString", Method, 0}, + {"(SymVis).String", Method, 0}, + {"(Type).GoString", Method, 0}, + {"(Type).String", Method, 0}, + {"(Version).GoString", Method, 0}, + {"(Version).String", Method, 0}, + {"ARM_MAGIC_TRAMP_NUMBER", Const, 0}, + {"COMPRESS_HIOS", Const, 6}, + {"COMPRESS_HIPROC", Const, 6}, + {"COMPRESS_LOOS", Const, 6}, + {"COMPRESS_LOPROC", Const, 6}, + {"COMPRESS_ZLIB", Const, 6}, + {"COMPRESS_ZSTD", Const, 21}, + {"Chdr32", Type, 6}, + {"Chdr32.Addralign", Field, 6}, + {"Chdr32.Size", Field, 6}, + {"Chdr32.Type", Field, 6}, + {"Chdr64", Type, 6}, + {"Chdr64.Addralign", Field, 6}, + {"Chdr64.Size", Field, 6}, + {"Chdr64.Type", Field, 6}, + {"Class", Type, 0}, + {"CompressionType", Type, 6}, + {"DF_1_CONFALT", Const, 21}, + {"DF_1_DIRECT", Const, 21}, + {"DF_1_DISPRELDNE", Const, 21}, + {"DF_1_DISPRELPND", Const, 21}, + {"DF_1_EDITED", Const, 21}, + {"DF_1_ENDFILTEE", Const, 21}, + {"DF_1_GLOBAL", Const, 21}, + {"DF_1_GLOBAUDIT", Const, 21}, + {"DF_1_GROUP", Const, 21}, + {"DF_1_IGNMULDEF", Const, 21}, + {"DF_1_INITFIRST", Const, 21}, + {"DF_1_INTERPOSE", Const, 21}, + {"DF_1_KMOD", Const, 21}, + {"DF_1_LOADFLTR", Const, 21}, + {"DF_1_NOCOMMON", Const, 21}, + {"DF_1_NODEFLIB", Const, 21}, + {"DF_1_NODELETE", Const, 21}, + {"DF_1_NODIRECT", Const, 21}, + {"DF_1_NODUMP", Const, 21}, + {"DF_1_NOHDR", Const, 21}, + {"DF_1_NOKSYMS", Const, 21}, + {"DF_1_NOOPEN", Const, 21}, + {"DF_1_NORELOC", Const, 21}, + {"DF_1_NOW", Const, 21}, + {"DF_1_ORIGIN", Const, 21}, + {"DF_1_PIE", Const, 21}, + {"DF_1_SINGLETON", Const, 21}, + {"DF_1_STUB", Const, 21}, + {"DF_1_SYMINTPOSE", Const, 21}, + {"DF_1_TRANS", Const, 21}, + {"DF_1_WEAKFILTER", Const, 21}, + {"DF_BIND_NOW", Const, 0}, + {"DF_ORIGIN", Const, 0}, + {"DF_STATIC_TLS", Const, 0}, + {"DF_SYMBOLIC", Const, 0}, + {"DF_TEXTREL", Const, 0}, + {"DT_ADDRRNGHI", Const, 16}, + {"DT_ADDRRNGLO", Const, 16}, + {"DT_AUDIT", Const, 16}, + {"DT_AUXILIARY", Const, 16}, + {"DT_BIND_NOW", Const, 0}, + {"DT_CHECKSUM", Const, 16}, + {"DT_CONFIG", Const, 16}, + {"DT_DEBUG", Const, 0}, + {"DT_DEPAUDIT", Const, 16}, + {"DT_ENCODING", Const, 0}, + {"DT_FEATURE", Const, 16}, + {"DT_FILTER", Const, 16}, + {"DT_FINI", Const, 0}, + {"DT_FINI_ARRAY", Const, 0}, + {"DT_FINI_ARRAYSZ", Const, 0}, + {"DT_FLAGS", Const, 0}, + {"DT_FLAGS_1", Const, 16}, + {"DT_GNU_CONFLICT", Const, 16}, + {"DT_GNU_CONFLICTSZ", Const, 16}, + {"DT_GNU_HASH", Const, 16}, + {"DT_GNU_LIBLIST", Const, 16}, + {"DT_GNU_LIBLISTSZ", Const, 16}, + {"DT_GNU_PRELINKED", Const, 16}, + {"DT_HASH", Const, 0}, + {"DT_HIOS", Const, 0}, + {"DT_HIPROC", Const, 0}, + {"DT_INIT", Const, 0}, + {"DT_INIT_ARRAY", Const, 0}, + {"DT_INIT_ARRAYSZ", Const, 0}, + {"DT_JMPREL", Const, 0}, + {"DT_LOOS", Const, 0}, + {"DT_LOPROC", Const, 0}, + {"DT_MIPS_AUX_DYNAMIC", Const, 16}, + {"DT_MIPS_BASE_ADDRESS", Const, 16}, + {"DT_MIPS_COMPACT_SIZE", Const, 16}, + {"DT_MIPS_CONFLICT", Const, 16}, + {"DT_MIPS_CONFLICTNO", Const, 16}, + {"DT_MIPS_CXX_FLAGS", Const, 16}, + {"DT_MIPS_DELTA_CLASS", Const, 16}, + {"DT_MIPS_DELTA_CLASSSYM", Const, 16}, + {"DT_MIPS_DELTA_CLASSSYM_NO", Const, 16}, + {"DT_MIPS_DELTA_CLASS_NO", Const, 16}, + {"DT_MIPS_DELTA_INSTANCE", Const, 16}, + {"DT_MIPS_DELTA_INSTANCE_NO", Const, 16}, + {"DT_MIPS_DELTA_RELOC", Const, 16}, + {"DT_MIPS_DELTA_RELOC_NO", Const, 16}, + {"DT_MIPS_DELTA_SYM", Const, 16}, + {"DT_MIPS_DELTA_SYM_NO", Const, 16}, + {"DT_MIPS_DYNSTR_ALIGN", Const, 16}, + {"DT_MIPS_FLAGS", Const, 16}, + {"DT_MIPS_GOTSYM", Const, 16}, + {"DT_MIPS_GP_VALUE", Const, 16}, + {"DT_MIPS_HIDDEN_GOTIDX", Const, 16}, + {"DT_MIPS_HIPAGENO", Const, 16}, + {"DT_MIPS_ICHECKSUM", Const, 16}, + {"DT_MIPS_INTERFACE", Const, 16}, + {"DT_MIPS_INTERFACE_SIZE", Const, 16}, + {"DT_MIPS_IVERSION", Const, 16}, + {"DT_MIPS_LIBLIST", Const, 16}, + {"DT_MIPS_LIBLISTNO", Const, 16}, + {"DT_MIPS_LOCALPAGE_GOTIDX", Const, 16}, + {"DT_MIPS_LOCAL_GOTIDX", Const, 16}, + {"DT_MIPS_LOCAL_GOTNO", Const, 16}, + {"DT_MIPS_MSYM", Const, 16}, + {"DT_MIPS_OPTIONS", Const, 16}, + {"DT_MIPS_PERF_SUFFIX", Const, 16}, + {"DT_MIPS_PIXIE_INIT", Const, 16}, + {"DT_MIPS_PLTGOT", Const, 16}, + {"DT_MIPS_PROTECTED_GOTIDX", Const, 16}, + {"DT_MIPS_RLD_MAP", Const, 16}, + {"DT_MIPS_RLD_MAP_REL", Const, 16}, + {"DT_MIPS_RLD_TEXT_RESOLVE_ADDR", Const, 16}, + {"DT_MIPS_RLD_VERSION", Const, 16}, + {"DT_MIPS_RWPLT", Const, 16}, + {"DT_MIPS_SYMBOL_LIB", Const, 16}, + {"DT_MIPS_SYMTABNO", Const, 16}, + {"DT_MIPS_TIME_STAMP", Const, 16}, + {"DT_MIPS_UNREFEXTNO", Const, 16}, + {"DT_MOVEENT", Const, 16}, + {"DT_MOVESZ", Const, 16}, + {"DT_MOVETAB", Const, 16}, + {"DT_NEEDED", Const, 0}, + {"DT_NULL", Const, 0}, + {"DT_PLTGOT", Const, 0}, + {"DT_PLTPAD", Const, 16}, + {"DT_PLTPADSZ", Const, 16}, + {"DT_PLTREL", Const, 0}, + {"DT_PLTRELSZ", Const, 0}, + {"DT_POSFLAG_1", Const, 16}, + {"DT_PPC64_GLINK", Const, 16}, + {"DT_PPC64_OPD", Const, 16}, + {"DT_PPC64_OPDSZ", Const, 16}, + {"DT_PPC64_OPT", Const, 16}, + {"DT_PPC_GOT", Const, 16}, + {"DT_PPC_OPT", Const, 16}, + {"DT_PREINIT_ARRAY", Const, 0}, + {"DT_PREINIT_ARRAYSZ", Const, 0}, + {"DT_REL", Const, 0}, + {"DT_RELA", Const, 0}, + {"DT_RELACOUNT", Const, 16}, + {"DT_RELAENT", Const, 0}, + {"DT_RELASZ", Const, 0}, + {"DT_RELCOUNT", Const, 16}, + {"DT_RELENT", Const, 0}, + {"DT_RELSZ", Const, 0}, + {"DT_RPATH", Const, 0}, + {"DT_RUNPATH", Const, 0}, + {"DT_SONAME", Const, 0}, + {"DT_SPARC_REGISTER", Const, 16}, + {"DT_STRSZ", Const, 0}, + {"DT_STRTAB", Const, 0}, + {"DT_SYMBOLIC", Const, 0}, + {"DT_SYMENT", Const, 0}, + {"DT_SYMINENT", Const, 16}, + {"DT_SYMINFO", Const, 16}, + {"DT_SYMINSZ", Const, 16}, + {"DT_SYMTAB", Const, 0}, + {"DT_SYMTAB_SHNDX", Const, 16}, + {"DT_TEXTREL", Const, 0}, + {"DT_TLSDESC_GOT", Const, 16}, + {"DT_TLSDESC_PLT", Const, 16}, + {"DT_USED", Const, 16}, + {"DT_VALRNGHI", Const, 16}, + {"DT_VALRNGLO", Const, 16}, + {"DT_VERDEF", Const, 16}, + {"DT_VERDEFNUM", Const, 16}, + {"DT_VERNEED", Const, 0}, + {"DT_VERNEEDNUM", Const, 0}, + {"DT_VERSYM", Const, 0}, + {"Data", Type, 0}, + {"Dyn32", Type, 0}, + {"Dyn32.Tag", Field, 0}, + {"Dyn32.Val", Field, 0}, + {"Dyn64", Type, 0}, + {"Dyn64.Tag", Field, 0}, + {"Dyn64.Val", Field, 0}, + {"DynFlag", Type, 0}, + {"DynFlag1", Type, 21}, + {"DynTag", Type, 0}, + {"EI_ABIVERSION", Const, 0}, + {"EI_CLASS", Const, 0}, + {"EI_DATA", Const, 0}, + {"EI_NIDENT", Const, 0}, + {"EI_OSABI", Const, 0}, + {"EI_PAD", Const, 0}, + {"EI_VERSION", Const, 0}, + {"ELFCLASS32", Const, 0}, + {"ELFCLASS64", Const, 0}, + {"ELFCLASSNONE", Const, 0}, + {"ELFDATA2LSB", Const, 0}, + {"ELFDATA2MSB", Const, 0}, + {"ELFDATANONE", Const, 0}, + {"ELFMAG", Const, 0}, + {"ELFOSABI_86OPEN", Const, 0}, + {"ELFOSABI_AIX", Const, 0}, + {"ELFOSABI_ARM", Const, 0}, + {"ELFOSABI_AROS", Const, 11}, + {"ELFOSABI_CLOUDABI", Const, 11}, + {"ELFOSABI_FENIXOS", Const, 11}, + {"ELFOSABI_FREEBSD", Const, 0}, + {"ELFOSABI_HPUX", Const, 0}, + {"ELFOSABI_HURD", Const, 0}, + {"ELFOSABI_IRIX", Const, 0}, + {"ELFOSABI_LINUX", Const, 0}, + {"ELFOSABI_MODESTO", Const, 0}, + {"ELFOSABI_NETBSD", Const, 0}, + {"ELFOSABI_NONE", Const, 0}, + {"ELFOSABI_NSK", Const, 0}, + {"ELFOSABI_OPENBSD", Const, 0}, + {"ELFOSABI_OPENVMS", Const, 0}, + {"ELFOSABI_SOLARIS", Const, 0}, + {"ELFOSABI_STANDALONE", Const, 0}, + {"ELFOSABI_TRU64", Const, 0}, + {"EM_386", Const, 0}, + {"EM_486", Const, 0}, + {"EM_56800EX", Const, 11}, + {"EM_68HC05", Const, 11}, + {"EM_68HC08", Const, 11}, + {"EM_68HC11", Const, 11}, + {"EM_68HC12", Const, 0}, + {"EM_68HC16", Const, 11}, + {"EM_68K", Const, 0}, + {"EM_78KOR", Const, 11}, + {"EM_8051", Const, 11}, + {"EM_860", Const, 0}, + {"EM_88K", Const, 0}, + {"EM_960", Const, 0}, + {"EM_AARCH64", Const, 4}, + {"EM_ALPHA", Const, 0}, + {"EM_ALPHA_STD", Const, 0}, + {"EM_ALTERA_NIOS2", Const, 11}, + {"EM_AMDGPU", Const, 11}, + {"EM_ARC", Const, 0}, + {"EM_ARCA", Const, 11}, + {"EM_ARC_COMPACT", Const, 11}, + {"EM_ARC_COMPACT2", Const, 11}, + {"EM_ARM", Const, 0}, + {"EM_AVR", Const, 11}, + {"EM_AVR32", Const, 11}, + {"EM_BA1", Const, 11}, + {"EM_BA2", Const, 11}, + {"EM_BLACKFIN", Const, 11}, + {"EM_BPF", Const, 11}, + {"EM_C166", Const, 11}, + {"EM_CDP", Const, 11}, + {"EM_CE", Const, 11}, + {"EM_CLOUDSHIELD", Const, 11}, + {"EM_COGE", Const, 11}, + {"EM_COLDFIRE", Const, 0}, + {"EM_COOL", Const, 11}, + {"EM_COREA_1ST", Const, 11}, + {"EM_COREA_2ND", Const, 11}, + {"EM_CR", Const, 11}, + {"EM_CR16", Const, 11}, + {"EM_CRAYNV2", Const, 11}, + {"EM_CRIS", Const, 11}, + {"EM_CRX", Const, 11}, + {"EM_CSR_KALIMBA", Const, 11}, + {"EM_CUDA", Const, 11}, + {"EM_CYPRESS_M8C", Const, 11}, + {"EM_D10V", Const, 11}, + {"EM_D30V", Const, 11}, + {"EM_DSP24", Const, 11}, + {"EM_DSPIC30F", Const, 11}, + {"EM_DXP", Const, 11}, + {"EM_ECOG1", Const, 11}, + {"EM_ECOG16", Const, 11}, + {"EM_ECOG1X", Const, 11}, + {"EM_ECOG2", Const, 11}, + {"EM_ETPU", Const, 11}, + {"EM_EXCESS", Const, 11}, + {"EM_F2MC16", Const, 11}, + {"EM_FIREPATH", Const, 11}, + {"EM_FR20", Const, 0}, + {"EM_FR30", Const, 11}, + {"EM_FT32", Const, 11}, + {"EM_FX66", Const, 11}, + {"EM_H8S", Const, 0}, + {"EM_H8_300", Const, 0}, + {"EM_H8_300H", Const, 0}, + {"EM_H8_500", Const, 0}, + {"EM_HUANY", Const, 11}, + {"EM_IA_64", Const, 0}, + {"EM_INTEL205", Const, 11}, + {"EM_INTEL206", Const, 11}, + {"EM_INTEL207", Const, 11}, + {"EM_INTEL208", Const, 11}, + {"EM_INTEL209", Const, 11}, + {"EM_IP2K", Const, 11}, + {"EM_JAVELIN", Const, 11}, + {"EM_K10M", Const, 11}, + {"EM_KM32", Const, 11}, + {"EM_KMX16", Const, 11}, + {"EM_KMX32", Const, 11}, + {"EM_KMX8", Const, 11}, + {"EM_KVARC", Const, 11}, + {"EM_L10M", Const, 11}, + {"EM_LANAI", Const, 11}, + {"EM_LATTICEMICO32", Const, 11}, + {"EM_LOONGARCH", Const, 19}, + {"EM_M16C", Const, 11}, + {"EM_M32", Const, 0}, + {"EM_M32C", Const, 11}, + {"EM_M32R", Const, 11}, + {"EM_MANIK", Const, 11}, + {"EM_MAX", Const, 11}, + {"EM_MAXQ30", Const, 11}, + {"EM_MCHP_PIC", Const, 11}, + {"EM_MCST_ELBRUS", Const, 11}, + {"EM_ME16", Const, 0}, + {"EM_METAG", Const, 11}, + {"EM_MICROBLAZE", Const, 11}, + {"EM_MIPS", Const, 0}, + {"EM_MIPS_RS3_LE", Const, 0}, + {"EM_MIPS_RS4_BE", Const, 0}, + {"EM_MIPS_X", Const, 0}, + {"EM_MMA", Const, 0}, + {"EM_MMDSP_PLUS", Const, 11}, + {"EM_MMIX", Const, 11}, + {"EM_MN10200", Const, 11}, + {"EM_MN10300", Const, 11}, + {"EM_MOXIE", Const, 11}, + {"EM_MSP430", Const, 11}, + {"EM_NCPU", Const, 0}, + {"EM_NDR1", Const, 0}, + {"EM_NDS32", Const, 11}, + {"EM_NONE", Const, 0}, + {"EM_NORC", Const, 11}, + {"EM_NS32K", Const, 11}, + {"EM_OPEN8", Const, 11}, + {"EM_OPENRISC", Const, 11}, + {"EM_PARISC", Const, 0}, + {"EM_PCP", Const, 0}, + {"EM_PDP10", Const, 11}, + {"EM_PDP11", Const, 11}, + {"EM_PDSP", Const, 11}, + {"EM_PJ", Const, 11}, + {"EM_PPC", Const, 0}, + {"EM_PPC64", Const, 0}, + {"EM_PRISM", Const, 11}, + {"EM_QDSP6", Const, 11}, + {"EM_R32C", Const, 11}, + {"EM_RCE", Const, 0}, + {"EM_RH32", Const, 0}, + {"EM_RISCV", Const, 11}, + {"EM_RL78", Const, 11}, + {"EM_RS08", Const, 11}, + {"EM_RX", Const, 11}, + {"EM_S370", Const, 0}, + {"EM_S390", Const, 0}, + {"EM_SCORE7", Const, 11}, + {"EM_SEP", Const, 11}, + {"EM_SE_C17", Const, 11}, + {"EM_SE_C33", Const, 11}, + {"EM_SH", Const, 0}, + {"EM_SHARC", Const, 11}, + {"EM_SLE9X", Const, 11}, + {"EM_SNP1K", Const, 11}, + {"EM_SPARC", Const, 0}, + {"EM_SPARC32PLUS", Const, 0}, + {"EM_SPARCV9", Const, 0}, + {"EM_ST100", Const, 0}, + {"EM_ST19", Const, 11}, + {"EM_ST200", Const, 11}, + {"EM_ST7", Const, 11}, + {"EM_ST9PLUS", Const, 11}, + {"EM_STARCORE", Const, 0}, + {"EM_STM8", Const, 11}, + {"EM_STXP7X", Const, 11}, + {"EM_SVX", Const, 11}, + {"EM_TILE64", Const, 11}, + {"EM_TILEGX", Const, 11}, + {"EM_TILEPRO", Const, 11}, + {"EM_TINYJ", Const, 0}, + {"EM_TI_ARP32", Const, 11}, + {"EM_TI_C2000", Const, 11}, + {"EM_TI_C5500", Const, 11}, + {"EM_TI_C6000", Const, 11}, + {"EM_TI_PRU", Const, 11}, + {"EM_TMM_GPP", Const, 11}, + {"EM_TPC", Const, 11}, + {"EM_TRICORE", Const, 0}, + {"EM_TRIMEDIA", Const, 11}, + {"EM_TSK3000", Const, 11}, + {"EM_UNICORE", Const, 11}, + {"EM_V800", Const, 0}, + {"EM_V850", Const, 11}, + {"EM_VAX", Const, 11}, + {"EM_VIDEOCORE", Const, 11}, + {"EM_VIDEOCORE3", Const, 11}, + {"EM_VIDEOCORE5", Const, 11}, + {"EM_VISIUM", Const, 11}, + {"EM_VPP500", Const, 0}, + {"EM_X86_64", Const, 0}, + {"EM_XCORE", Const, 11}, + {"EM_XGATE", Const, 11}, + {"EM_XIMO16", Const, 11}, + {"EM_XTENSA", Const, 11}, + {"EM_Z80", Const, 11}, + {"EM_ZSP", Const, 11}, + {"ET_CORE", Const, 0}, + {"ET_DYN", Const, 0}, + {"ET_EXEC", Const, 0}, + {"ET_HIOS", Const, 0}, + {"ET_HIPROC", Const, 0}, + {"ET_LOOS", Const, 0}, + {"ET_LOPROC", Const, 0}, + {"ET_NONE", Const, 0}, + {"ET_REL", Const, 0}, + {"EV_CURRENT", Const, 0}, + {"EV_NONE", Const, 0}, + {"ErrNoSymbols", Var, 4}, + {"File", Type, 0}, + {"File.FileHeader", Field, 0}, + {"File.Progs", Field, 0}, + {"File.Sections", Field, 0}, + {"FileHeader", Type, 0}, + {"FileHeader.ABIVersion", Field, 0}, + {"FileHeader.ByteOrder", Field, 0}, + {"FileHeader.Class", Field, 0}, + {"FileHeader.Data", Field, 0}, + {"FileHeader.Entry", Field, 1}, + {"FileHeader.Machine", Field, 0}, + {"FileHeader.OSABI", Field, 0}, + {"FileHeader.Type", Field, 0}, + {"FileHeader.Version", Field, 0}, + {"FormatError", Type, 0}, + {"Header32", Type, 0}, + {"Header32.Ehsize", Field, 0}, + {"Header32.Entry", Field, 0}, + {"Header32.Flags", Field, 0}, + {"Header32.Ident", Field, 0}, + {"Header32.Machine", Field, 0}, + {"Header32.Phentsize", Field, 0}, + {"Header32.Phnum", Field, 0}, + {"Header32.Phoff", Field, 0}, + {"Header32.Shentsize", Field, 0}, + {"Header32.Shnum", Field, 0}, + {"Header32.Shoff", Field, 0}, + {"Header32.Shstrndx", Field, 0}, + {"Header32.Type", Field, 0}, + {"Header32.Version", Field, 0}, + {"Header64", Type, 0}, + {"Header64.Ehsize", Field, 0}, + {"Header64.Entry", Field, 0}, + {"Header64.Flags", Field, 0}, + {"Header64.Ident", Field, 0}, + {"Header64.Machine", Field, 0}, + {"Header64.Phentsize", Field, 0}, + {"Header64.Phnum", Field, 0}, + {"Header64.Phoff", Field, 0}, + {"Header64.Shentsize", Field, 0}, + {"Header64.Shnum", Field, 0}, + {"Header64.Shoff", Field, 0}, + {"Header64.Shstrndx", Field, 0}, + {"Header64.Type", Field, 0}, + {"Header64.Version", Field, 0}, + {"ImportedSymbol", Type, 0}, + {"ImportedSymbol.Library", Field, 0}, + {"ImportedSymbol.Name", Field, 0}, + {"ImportedSymbol.Version", Field, 0}, + {"Machine", Type, 0}, + {"NT_FPREGSET", Const, 0}, + {"NT_PRPSINFO", Const, 0}, + {"NT_PRSTATUS", Const, 0}, + {"NType", Type, 0}, + {"NewFile", Func, 0}, + {"OSABI", Type, 0}, + {"Open", Func, 0}, + {"PF_MASKOS", Const, 0}, + {"PF_MASKPROC", Const, 0}, + {"PF_R", Const, 0}, + {"PF_W", Const, 0}, + {"PF_X", Const, 0}, + {"PT_AARCH64_ARCHEXT", Const, 16}, + {"PT_AARCH64_UNWIND", Const, 16}, + {"PT_ARM_ARCHEXT", Const, 16}, + {"PT_ARM_EXIDX", Const, 16}, + {"PT_DYNAMIC", Const, 0}, + {"PT_GNU_EH_FRAME", Const, 16}, + {"PT_GNU_MBIND_HI", Const, 16}, + {"PT_GNU_MBIND_LO", Const, 16}, + {"PT_GNU_PROPERTY", Const, 16}, + {"PT_GNU_RELRO", Const, 16}, + {"PT_GNU_STACK", Const, 16}, + {"PT_HIOS", Const, 0}, + {"PT_HIPROC", Const, 0}, + {"PT_INTERP", Const, 0}, + {"PT_LOAD", Const, 0}, + {"PT_LOOS", Const, 0}, + {"PT_LOPROC", Const, 0}, + {"PT_MIPS_ABIFLAGS", Const, 16}, + {"PT_MIPS_OPTIONS", Const, 16}, + {"PT_MIPS_REGINFO", Const, 16}, + {"PT_MIPS_RTPROC", Const, 16}, + {"PT_NOTE", Const, 0}, + {"PT_NULL", Const, 0}, + {"PT_OPENBSD_BOOTDATA", Const, 16}, + {"PT_OPENBSD_NOBTCFI", Const, 23}, + {"PT_OPENBSD_RANDOMIZE", Const, 16}, + {"PT_OPENBSD_WXNEEDED", Const, 16}, + {"PT_PAX_FLAGS", Const, 16}, + {"PT_PHDR", Const, 0}, + {"PT_S390_PGSTE", Const, 16}, + {"PT_SHLIB", Const, 0}, + {"PT_SUNWSTACK", Const, 16}, + {"PT_SUNW_EH_FRAME", Const, 16}, + {"PT_TLS", Const, 0}, + {"Prog", Type, 0}, + {"Prog.ProgHeader", Field, 0}, + {"Prog.ReaderAt", Field, 0}, + {"Prog32", Type, 0}, + {"Prog32.Align", Field, 0}, + {"Prog32.Filesz", Field, 0}, + {"Prog32.Flags", Field, 0}, + {"Prog32.Memsz", Field, 0}, + {"Prog32.Off", Field, 0}, + {"Prog32.Paddr", Field, 0}, + {"Prog32.Type", Field, 0}, + {"Prog32.Vaddr", Field, 0}, + {"Prog64", Type, 0}, + {"Prog64.Align", Field, 0}, + {"Prog64.Filesz", Field, 0}, + {"Prog64.Flags", Field, 0}, + {"Prog64.Memsz", Field, 0}, + {"Prog64.Off", Field, 0}, + {"Prog64.Paddr", Field, 0}, + {"Prog64.Type", Field, 0}, + {"Prog64.Vaddr", Field, 0}, + {"ProgFlag", Type, 0}, + {"ProgHeader", Type, 0}, + {"ProgHeader.Align", Field, 0}, + {"ProgHeader.Filesz", Field, 0}, + {"ProgHeader.Flags", Field, 0}, + {"ProgHeader.Memsz", Field, 0}, + {"ProgHeader.Off", Field, 0}, + {"ProgHeader.Paddr", Field, 0}, + {"ProgHeader.Type", Field, 0}, + {"ProgHeader.Vaddr", Field, 0}, + {"ProgType", Type, 0}, + {"R_386", Type, 0}, + {"R_386_16", Const, 10}, + {"R_386_32", Const, 0}, + {"R_386_32PLT", Const, 10}, + {"R_386_8", Const, 10}, + {"R_386_COPY", Const, 0}, + {"R_386_GLOB_DAT", Const, 0}, + {"R_386_GOT32", Const, 0}, + {"R_386_GOT32X", Const, 10}, + {"R_386_GOTOFF", Const, 0}, + {"R_386_GOTPC", Const, 0}, + {"R_386_IRELATIVE", Const, 10}, + {"R_386_JMP_SLOT", Const, 0}, + {"R_386_NONE", Const, 0}, + {"R_386_PC16", Const, 10}, + {"R_386_PC32", Const, 0}, + {"R_386_PC8", Const, 10}, + {"R_386_PLT32", Const, 0}, + {"R_386_RELATIVE", Const, 0}, + {"R_386_SIZE32", Const, 10}, + {"R_386_TLS_DESC", Const, 10}, + {"R_386_TLS_DESC_CALL", Const, 10}, + {"R_386_TLS_DTPMOD32", Const, 0}, + {"R_386_TLS_DTPOFF32", Const, 0}, + {"R_386_TLS_GD", Const, 0}, + {"R_386_TLS_GD_32", Const, 0}, + {"R_386_TLS_GD_CALL", Const, 0}, + {"R_386_TLS_GD_POP", Const, 0}, + {"R_386_TLS_GD_PUSH", Const, 0}, + {"R_386_TLS_GOTDESC", Const, 10}, + {"R_386_TLS_GOTIE", Const, 0}, + {"R_386_TLS_IE", Const, 0}, + {"R_386_TLS_IE_32", Const, 0}, + {"R_386_TLS_LDM", Const, 0}, + {"R_386_TLS_LDM_32", Const, 0}, + {"R_386_TLS_LDM_CALL", Const, 0}, + {"R_386_TLS_LDM_POP", Const, 0}, + {"R_386_TLS_LDM_PUSH", Const, 0}, + {"R_386_TLS_LDO_32", Const, 0}, + {"R_386_TLS_LE", Const, 0}, + {"R_386_TLS_LE_32", Const, 0}, + {"R_386_TLS_TPOFF", Const, 0}, + {"R_386_TLS_TPOFF32", Const, 0}, + {"R_390", Type, 7}, + {"R_390_12", Const, 7}, + {"R_390_16", Const, 7}, + {"R_390_20", Const, 7}, + {"R_390_32", Const, 7}, + {"R_390_64", Const, 7}, + {"R_390_8", Const, 7}, + {"R_390_COPY", Const, 7}, + {"R_390_GLOB_DAT", Const, 7}, + {"R_390_GOT12", Const, 7}, + {"R_390_GOT16", Const, 7}, + {"R_390_GOT20", Const, 7}, + {"R_390_GOT32", Const, 7}, + {"R_390_GOT64", Const, 7}, + {"R_390_GOTENT", Const, 7}, + {"R_390_GOTOFF", Const, 7}, + {"R_390_GOTOFF16", Const, 7}, + {"R_390_GOTOFF64", Const, 7}, + {"R_390_GOTPC", Const, 7}, + {"R_390_GOTPCDBL", Const, 7}, + {"R_390_GOTPLT12", Const, 7}, + {"R_390_GOTPLT16", Const, 7}, + {"R_390_GOTPLT20", Const, 7}, + {"R_390_GOTPLT32", Const, 7}, + {"R_390_GOTPLT64", Const, 7}, + {"R_390_GOTPLTENT", Const, 7}, + {"R_390_GOTPLTOFF16", Const, 7}, + {"R_390_GOTPLTOFF32", Const, 7}, + {"R_390_GOTPLTOFF64", Const, 7}, + {"R_390_JMP_SLOT", Const, 7}, + {"R_390_NONE", Const, 7}, + {"R_390_PC16", Const, 7}, + {"R_390_PC16DBL", Const, 7}, + {"R_390_PC32", Const, 7}, + {"R_390_PC32DBL", Const, 7}, + {"R_390_PC64", Const, 7}, + {"R_390_PLT16DBL", Const, 7}, + {"R_390_PLT32", Const, 7}, + {"R_390_PLT32DBL", Const, 7}, + {"R_390_PLT64", Const, 7}, + {"R_390_RELATIVE", Const, 7}, + {"R_390_TLS_DTPMOD", Const, 7}, + {"R_390_TLS_DTPOFF", Const, 7}, + {"R_390_TLS_GD32", Const, 7}, + {"R_390_TLS_GD64", Const, 7}, + {"R_390_TLS_GDCALL", Const, 7}, + {"R_390_TLS_GOTIE12", Const, 7}, + {"R_390_TLS_GOTIE20", Const, 7}, + {"R_390_TLS_GOTIE32", Const, 7}, + {"R_390_TLS_GOTIE64", Const, 7}, + {"R_390_TLS_IE32", Const, 7}, + {"R_390_TLS_IE64", Const, 7}, + {"R_390_TLS_IEENT", Const, 7}, + {"R_390_TLS_LDCALL", Const, 7}, + {"R_390_TLS_LDM32", Const, 7}, + {"R_390_TLS_LDM64", Const, 7}, + {"R_390_TLS_LDO32", Const, 7}, + {"R_390_TLS_LDO64", Const, 7}, + {"R_390_TLS_LE32", Const, 7}, + {"R_390_TLS_LE64", Const, 7}, + {"R_390_TLS_LOAD", Const, 7}, + {"R_390_TLS_TPOFF", Const, 7}, + {"R_AARCH64", Type, 4}, + {"R_AARCH64_ABS16", Const, 4}, + {"R_AARCH64_ABS32", Const, 4}, + {"R_AARCH64_ABS64", Const, 4}, + {"R_AARCH64_ADD_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_ADR_GOT_PAGE", Const, 4}, + {"R_AARCH64_ADR_PREL_LO21", Const, 4}, + {"R_AARCH64_ADR_PREL_PG_HI21", Const, 4}, + {"R_AARCH64_ADR_PREL_PG_HI21_NC", Const, 4}, + {"R_AARCH64_CALL26", Const, 4}, + {"R_AARCH64_CONDBR19", Const, 4}, + {"R_AARCH64_COPY", Const, 4}, + {"R_AARCH64_GLOB_DAT", Const, 4}, + {"R_AARCH64_GOT_LD_PREL19", Const, 4}, + {"R_AARCH64_IRELATIVE", Const, 4}, + {"R_AARCH64_JUMP26", Const, 4}, + {"R_AARCH64_JUMP_SLOT", Const, 4}, + {"R_AARCH64_LD64_GOTOFF_LO15", Const, 10}, + {"R_AARCH64_LD64_GOTPAGE_LO15", Const, 10}, + {"R_AARCH64_LD64_GOT_LO12_NC", Const, 4}, + {"R_AARCH64_LDST128_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LDST16_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LDST32_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LDST64_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LDST8_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LD_PREL_LO19", Const, 4}, + {"R_AARCH64_MOVW_SABS_G0", Const, 4}, + {"R_AARCH64_MOVW_SABS_G1", Const, 4}, + {"R_AARCH64_MOVW_SABS_G2", Const, 4}, + {"R_AARCH64_MOVW_UABS_G0", Const, 4}, + {"R_AARCH64_MOVW_UABS_G0_NC", Const, 4}, + {"R_AARCH64_MOVW_UABS_G1", Const, 4}, + {"R_AARCH64_MOVW_UABS_G1_NC", Const, 4}, + {"R_AARCH64_MOVW_UABS_G2", Const, 4}, + {"R_AARCH64_MOVW_UABS_G2_NC", Const, 4}, + {"R_AARCH64_MOVW_UABS_G3", Const, 4}, + {"R_AARCH64_NONE", Const, 4}, + {"R_AARCH64_NULL", Const, 4}, + {"R_AARCH64_P32_ABS16", Const, 4}, + {"R_AARCH64_P32_ABS32", Const, 4}, + {"R_AARCH64_P32_ADD_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_ADR_GOT_PAGE", Const, 4}, + {"R_AARCH64_P32_ADR_PREL_LO21", Const, 4}, + {"R_AARCH64_P32_ADR_PREL_PG_HI21", Const, 4}, + {"R_AARCH64_P32_CALL26", Const, 4}, + {"R_AARCH64_P32_CONDBR19", Const, 4}, + {"R_AARCH64_P32_COPY", Const, 4}, + {"R_AARCH64_P32_GLOB_DAT", Const, 4}, + {"R_AARCH64_P32_GOT_LD_PREL19", Const, 4}, + {"R_AARCH64_P32_IRELATIVE", Const, 4}, + {"R_AARCH64_P32_JUMP26", Const, 4}, + {"R_AARCH64_P32_JUMP_SLOT", Const, 4}, + {"R_AARCH64_P32_LD32_GOT_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST128_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST16_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST32_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST64_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST8_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LD_PREL_LO19", Const, 4}, + {"R_AARCH64_P32_MOVW_SABS_G0", Const, 4}, + {"R_AARCH64_P32_MOVW_UABS_G0", Const, 4}, + {"R_AARCH64_P32_MOVW_UABS_G0_NC", Const, 4}, + {"R_AARCH64_P32_MOVW_UABS_G1", Const, 4}, + {"R_AARCH64_P32_PREL16", Const, 4}, + {"R_AARCH64_P32_PREL32", Const, 4}, + {"R_AARCH64_P32_RELATIVE", Const, 4}, + {"R_AARCH64_P32_TLSDESC", Const, 4}, + {"R_AARCH64_P32_TLSDESC_ADD_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSDESC_ADR_PAGE21", Const, 4}, + {"R_AARCH64_P32_TLSDESC_ADR_PREL21", Const, 4}, + {"R_AARCH64_P32_TLSDESC_CALL", Const, 4}, + {"R_AARCH64_P32_TLSDESC_LD32_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSDESC_LD_PREL19", Const, 4}, + {"R_AARCH64_P32_TLSGD_ADD_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSGD_ADR_PAGE21", Const, 4}, + {"R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4}, + {"R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19", Const, 4}, + {"R_AARCH64_P32_TLSLE_ADD_TPREL_HI12", Const, 4}, + {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12", Const, 4}, + {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0", Const, 4}, + {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC", Const, 4}, + {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G1", Const, 4}, + {"R_AARCH64_P32_TLS_DTPMOD", Const, 4}, + {"R_AARCH64_P32_TLS_DTPREL", Const, 4}, + {"R_AARCH64_P32_TLS_TPREL", Const, 4}, + {"R_AARCH64_P32_TSTBR14", Const, 4}, + {"R_AARCH64_PREL16", Const, 4}, + {"R_AARCH64_PREL32", Const, 4}, + {"R_AARCH64_PREL64", Const, 4}, + {"R_AARCH64_RELATIVE", Const, 4}, + {"R_AARCH64_TLSDESC", Const, 4}, + {"R_AARCH64_TLSDESC_ADD", Const, 4}, + {"R_AARCH64_TLSDESC_ADD_LO12_NC", Const, 4}, + {"R_AARCH64_TLSDESC_ADR_PAGE21", Const, 4}, + {"R_AARCH64_TLSDESC_ADR_PREL21", Const, 4}, + {"R_AARCH64_TLSDESC_CALL", Const, 4}, + {"R_AARCH64_TLSDESC_LD64_LO12_NC", Const, 4}, + {"R_AARCH64_TLSDESC_LDR", Const, 4}, + {"R_AARCH64_TLSDESC_LD_PREL19", Const, 4}, + {"R_AARCH64_TLSDESC_OFF_G0_NC", Const, 4}, + {"R_AARCH64_TLSDESC_OFF_G1", Const, 4}, + {"R_AARCH64_TLSGD_ADD_LO12_NC", Const, 4}, + {"R_AARCH64_TLSGD_ADR_PAGE21", Const, 4}, + {"R_AARCH64_TLSGD_ADR_PREL21", Const, 10}, + {"R_AARCH64_TLSGD_MOVW_G0_NC", Const, 10}, + {"R_AARCH64_TLSGD_MOVW_G1", Const, 10}, + {"R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4}, + {"R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC", Const, 4}, + {"R_AARCH64_TLSIE_LD_GOTTPREL_PREL19", Const, 4}, + {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC", Const, 4}, + {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G1", Const, 4}, + {"R_AARCH64_TLSLD_ADR_PAGE21", Const, 10}, + {"R_AARCH64_TLSLD_ADR_PREL21", Const, 10}, + {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12", Const, 10}, + {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC", Const, 10}, + {"R_AARCH64_TLSLE_ADD_TPREL_HI12", Const, 4}, + {"R_AARCH64_TLSLE_ADD_TPREL_LO12", Const, 4}, + {"R_AARCH64_TLSLE_ADD_TPREL_LO12_NC", Const, 4}, + {"R_AARCH64_TLSLE_LDST128_TPREL_LO12", Const, 10}, + {"R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC", Const, 10}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G0", Const, 4}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G0_NC", Const, 4}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G1", Const, 4}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G1_NC", Const, 4}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G2", Const, 4}, + {"R_AARCH64_TLS_DTPMOD64", Const, 4}, + {"R_AARCH64_TLS_DTPREL64", Const, 4}, + {"R_AARCH64_TLS_TPREL64", Const, 4}, + {"R_AARCH64_TSTBR14", Const, 4}, + {"R_ALPHA", Type, 0}, + {"R_ALPHA_BRADDR", Const, 0}, + {"R_ALPHA_COPY", Const, 0}, + {"R_ALPHA_GLOB_DAT", Const, 0}, + {"R_ALPHA_GPDISP", Const, 0}, + {"R_ALPHA_GPREL32", Const, 0}, + {"R_ALPHA_GPRELHIGH", Const, 0}, + {"R_ALPHA_GPRELLOW", Const, 0}, + {"R_ALPHA_GPVALUE", Const, 0}, + {"R_ALPHA_HINT", Const, 0}, + {"R_ALPHA_IMMED_BR_HI32", Const, 0}, + {"R_ALPHA_IMMED_GP_16", Const, 0}, + {"R_ALPHA_IMMED_GP_HI32", Const, 0}, + {"R_ALPHA_IMMED_LO32", Const, 0}, + {"R_ALPHA_IMMED_SCN_HI32", Const, 0}, + {"R_ALPHA_JMP_SLOT", Const, 0}, + {"R_ALPHA_LITERAL", Const, 0}, + {"R_ALPHA_LITUSE", Const, 0}, + {"R_ALPHA_NONE", Const, 0}, + {"R_ALPHA_OP_PRSHIFT", Const, 0}, + {"R_ALPHA_OP_PSUB", Const, 0}, + {"R_ALPHA_OP_PUSH", Const, 0}, + {"R_ALPHA_OP_STORE", Const, 0}, + {"R_ALPHA_REFLONG", Const, 0}, + {"R_ALPHA_REFQUAD", Const, 0}, + {"R_ALPHA_RELATIVE", Const, 0}, + {"R_ALPHA_SREL16", Const, 0}, + {"R_ALPHA_SREL32", Const, 0}, + {"R_ALPHA_SREL64", Const, 0}, + {"R_ARM", Type, 0}, + {"R_ARM_ABS12", Const, 0}, + {"R_ARM_ABS16", Const, 0}, + {"R_ARM_ABS32", Const, 0}, + {"R_ARM_ABS32_NOI", Const, 10}, + {"R_ARM_ABS8", Const, 0}, + {"R_ARM_ALU_PCREL_15_8", Const, 10}, + {"R_ARM_ALU_PCREL_23_15", Const, 10}, + {"R_ARM_ALU_PCREL_7_0", Const, 10}, + {"R_ARM_ALU_PC_G0", Const, 10}, + {"R_ARM_ALU_PC_G0_NC", Const, 10}, + {"R_ARM_ALU_PC_G1", Const, 10}, + {"R_ARM_ALU_PC_G1_NC", Const, 10}, + {"R_ARM_ALU_PC_G2", Const, 10}, + {"R_ARM_ALU_SBREL_19_12_NC", Const, 10}, + {"R_ARM_ALU_SBREL_27_20_CK", Const, 10}, + {"R_ARM_ALU_SB_G0", Const, 10}, + {"R_ARM_ALU_SB_G0_NC", Const, 10}, + {"R_ARM_ALU_SB_G1", Const, 10}, + {"R_ARM_ALU_SB_G1_NC", Const, 10}, + {"R_ARM_ALU_SB_G2", Const, 10}, + {"R_ARM_AMP_VCALL9", Const, 0}, + {"R_ARM_BASE_ABS", Const, 10}, + {"R_ARM_CALL", Const, 10}, + {"R_ARM_COPY", Const, 0}, + {"R_ARM_GLOB_DAT", Const, 0}, + {"R_ARM_GNU_VTENTRY", Const, 0}, + {"R_ARM_GNU_VTINHERIT", Const, 0}, + {"R_ARM_GOT32", Const, 0}, + {"R_ARM_GOTOFF", Const, 0}, + {"R_ARM_GOTOFF12", Const, 10}, + {"R_ARM_GOTPC", Const, 0}, + {"R_ARM_GOTRELAX", Const, 10}, + {"R_ARM_GOT_ABS", Const, 10}, + {"R_ARM_GOT_BREL12", Const, 10}, + {"R_ARM_GOT_PREL", Const, 10}, + {"R_ARM_IRELATIVE", Const, 10}, + {"R_ARM_JUMP24", Const, 10}, + {"R_ARM_JUMP_SLOT", Const, 0}, + {"R_ARM_LDC_PC_G0", Const, 10}, + {"R_ARM_LDC_PC_G1", Const, 10}, + {"R_ARM_LDC_PC_G2", Const, 10}, + {"R_ARM_LDC_SB_G0", Const, 10}, + {"R_ARM_LDC_SB_G1", Const, 10}, + {"R_ARM_LDC_SB_G2", Const, 10}, + {"R_ARM_LDRS_PC_G0", Const, 10}, + {"R_ARM_LDRS_PC_G1", Const, 10}, + {"R_ARM_LDRS_PC_G2", Const, 10}, + {"R_ARM_LDRS_SB_G0", Const, 10}, + {"R_ARM_LDRS_SB_G1", Const, 10}, + {"R_ARM_LDRS_SB_G2", Const, 10}, + {"R_ARM_LDR_PC_G1", Const, 10}, + {"R_ARM_LDR_PC_G2", Const, 10}, + {"R_ARM_LDR_SBREL_11_10_NC", Const, 10}, + {"R_ARM_LDR_SB_G0", Const, 10}, + {"R_ARM_LDR_SB_G1", Const, 10}, + {"R_ARM_LDR_SB_G2", Const, 10}, + {"R_ARM_ME_TOO", Const, 10}, + {"R_ARM_MOVT_ABS", Const, 10}, + {"R_ARM_MOVT_BREL", Const, 10}, + {"R_ARM_MOVT_PREL", Const, 10}, + {"R_ARM_MOVW_ABS_NC", Const, 10}, + {"R_ARM_MOVW_BREL", Const, 10}, + {"R_ARM_MOVW_BREL_NC", Const, 10}, + {"R_ARM_MOVW_PREL_NC", Const, 10}, + {"R_ARM_NONE", Const, 0}, + {"R_ARM_PC13", Const, 0}, + {"R_ARM_PC24", Const, 0}, + {"R_ARM_PLT32", Const, 0}, + {"R_ARM_PLT32_ABS", Const, 10}, + {"R_ARM_PREL31", Const, 10}, + {"R_ARM_PRIVATE_0", Const, 10}, + {"R_ARM_PRIVATE_1", Const, 10}, + {"R_ARM_PRIVATE_10", Const, 10}, + {"R_ARM_PRIVATE_11", Const, 10}, + {"R_ARM_PRIVATE_12", Const, 10}, + {"R_ARM_PRIVATE_13", Const, 10}, + {"R_ARM_PRIVATE_14", Const, 10}, + {"R_ARM_PRIVATE_15", Const, 10}, + {"R_ARM_PRIVATE_2", Const, 10}, + {"R_ARM_PRIVATE_3", Const, 10}, + {"R_ARM_PRIVATE_4", Const, 10}, + {"R_ARM_PRIVATE_5", Const, 10}, + {"R_ARM_PRIVATE_6", Const, 10}, + {"R_ARM_PRIVATE_7", Const, 10}, + {"R_ARM_PRIVATE_8", Const, 10}, + {"R_ARM_PRIVATE_9", Const, 10}, + {"R_ARM_RABS32", Const, 0}, + {"R_ARM_RBASE", Const, 0}, + {"R_ARM_REL32", Const, 0}, + {"R_ARM_REL32_NOI", Const, 10}, + {"R_ARM_RELATIVE", Const, 0}, + {"R_ARM_RPC24", Const, 0}, + {"R_ARM_RREL32", Const, 0}, + {"R_ARM_RSBREL32", Const, 0}, + {"R_ARM_RXPC25", Const, 10}, + {"R_ARM_SBREL31", Const, 10}, + {"R_ARM_SBREL32", Const, 0}, + {"R_ARM_SWI24", Const, 0}, + {"R_ARM_TARGET1", Const, 10}, + {"R_ARM_TARGET2", Const, 10}, + {"R_ARM_THM_ABS5", Const, 0}, + {"R_ARM_THM_ALU_ABS_G0_NC", Const, 10}, + {"R_ARM_THM_ALU_ABS_G1_NC", Const, 10}, + {"R_ARM_THM_ALU_ABS_G2_NC", Const, 10}, + {"R_ARM_THM_ALU_ABS_G3", Const, 10}, + {"R_ARM_THM_ALU_PREL_11_0", Const, 10}, + {"R_ARM_THM_GOT_BREL12", Const, 10}, + {"R_ARM_THM_JUMP11", Const, 10}, + {"R_ARM_THM_JUMP19", Const, 10}, + {"R_ARM_THM_JUMP24", Const, 10}, + {"R_ARM_THM_JUMP6", Const, 10}, + {"R_ARM_THM_JUMP8", Const, 10}, + {"R_ARM_THM_MOVT_ABS", Const, 10}, + {"R_ARM_THM_MOVT_BREL", Const, 10}, + {"R_ARM_THM_MOVT_PREL", Const, 10}, + {"R_ARM_THM_MOVW_ABS_NC", Const, 10}, + {"R_ARM_THM_MOVW_BREL", Const, 10}, + {"R_ARM_THM_MOVW_BREL_NC", Const, 10}, + {"R_ARM_THM_MOVW_PREL_NC", Const, 10}, + {"R_ARM_THM_PC12", Const, 10}, + {"R_ARM_THM_PC22", Const, 0}, + {"R_ARM_THM_PC8", Const, 0}, + {"R_ARM_THM_RPC22", Const, 0}, + {"R_ARM_THM_SWI8", Const, 0}, + {"R_ARM_THM_TLS_CALL", Const, 10}, + {"R_ARM_THM_TLS_DESCSEQ16", Const, 10}, + {"R_ARM_THM_TLS_DESCSEQ32", Const, 10}, + {"R_ARM_THM_XPC22", Const, 0}, + {"R_ARM_TLS_CALL", Const, 10}, + {"R_ARM_TLS_DESCSEQ", Const, 10}, + {"R_ARM_TLS_DTPMOD32", Const, 10}, + {"R_ARM_TLS_DTPOFF32", Const, 10}, + {"R_ARM_TLS_GD32", Const, 10}, + {"R_ARM_TLS_GOTDESC", Const, 10}, + {"R_ARM_TLS_IE12GP", Const, 10}, + {"R_ARM_TLS_IE32", Const, 10}, + {"R_ARM_TLS_LDM32", Const, 10}, + {"R_ARM_TLS_LDO12", Const, 10}, + {"R_ARM_TLS_LDO32", Const, 10}, + {"R_ARM_TLS_LE12", Const, 10}, + {"R_ARM_TLS_LE32", Const, 10}, + {"R_ARM_TLS_TPOFF32", Const, 10}, + {"R_ARM_V4BX", Const, 10}, + {"R_ARM_XPC25", Const, 0}, + {"R_INFO", Func, 0}, + {"R_INFO32", Func, 0}, + {"R_LARCH", Type, 19}, + {"R_LARCH_32", Const, 19}, + {"R_LARCH_32_PCREL", Const, 20}, + {"R_LARCH_64", Const, 19}, + {"R_LARCH_64_PCREL", Const, 22}, + {"R_LARCH_ABS64_HI12", Const, 20}, + {"R_LARCH_ABS64_LO20", Const, 20}, + {"R_LARCH_ABS_HI20", Const, 20}, + {"R_LARCH_ABS_LO12", Const, 20}, + {"R_LARCH_ADD16", Const, 19}, + {"R_LARCH_ADD24", Const, 19}, + {"R_LARCH_ADD32", Const, 19}, + {"R_LARCH_ADD6", Const, 22}, + {"R_LARCH_ADD64", Const, 19}, + {"R_LARCH_ADD8", Const, 19}, + {"R_LARCH_ADD_ULEB128", Const, 22}, + {"R_LARCH_ALIGN", Const, 22}, + {"R_LARCH_B16", Const, 20}, + {"R_LARCH_B21", Const, 20}, + {"R_LARCH_B26", Const, 20}, + {"R_LARCH_CFA", Const, 22}, + {"R_LARCH_COPY", Const, 19}, + {"R_LARCH_DELETE", Const, 22}, + {"R_LARCH_GNU_VTENTRY", Const, 20}, + {"R_LARCH_GNU_VTINHERIT", Const, 20}, + {"R_LARCH_GOT64_HI12", Const, 20}, + {"R_LARCH_GOT64_LO20", Const, 20}, + {"R_LARCH_GOT64_PC_HI12", Const, 20}, + {"R_LARCH_GOT64_PC_LO20", Const, 20}, + {"R_LARCH_GOT_HI20", Const, 20}, + {"R_LARCH_GOT_LO12", Const, 20}, + {"R_LARCH_GOT_PC_HI20", Const, 20}, + {"R_LARCH_GOT_PC_LO12", Const, 20}, + {"R_LARCH_IRELATIVE", Const, 19}, + {"R_LARCH_JUMP_SLOT", Const, 19}, + {"R_LARCH_MARK_LA", Const, 19}, + {"R_LARCH_MARK_PCREL", Const, 19}, + {"R_LARCH_NONE", Const, 19}, + {"R_LARCH_PCALA64_HI12", Const, 20}, + {"R_LARCH_PCALA64_LO20", Const, 20}, + {"R_LARCH_PCALA_HI20", Const, 20}, + {"R_LARCH_PCALA_LO12", Const, 20}, + {"R_LARCH_PCREL20_S2", Const, 22}, + {"R_LARCH_RELATIVE", Const, 19}, + {"R_LARCH_RELAX", Const, 20}, + {"R_LARCH_SOP_ADD", Const, 19}, + {"R_LARCH_SOP_AND", Const, 19}, + {"R_LARCH_SOP_ASSERT", Const, 19}, + {"R_LARCH_SOP_IF_ELSE", Const, 19}, + {"R_LARCH_SOP_NOT", Const, 19}, + {"R_LARCH_SOP_POP_32_S_0_10_10_16_S2", Const, 19}, + {"R_LARCH_SOP_POP_32_S_0_5_10_16_S2", Const, 19}, + {"R_LARCH_SOP_POP_32_S_10_12", Const, 19}, + {"R_LARCH_SOP_POP_32_S_10_16", Const, 19}, + {"R_LARCH_SOP_POP_32_S_10_16_S2", Const, 19}, + {"R_LARCH_SOP_POP_32_S_10_5", Const, 19}, + {"R_LARCH_SOP_POP_32_S_5_20", Const, 19}, + {"R_LARCH_SOP_POP_32_U", Const, 19}, + {"R_LARCH_SOP_POP_32_U_10_12", Const, 19}, + {"R_LARCH_SOP_PUSH_ABSOLUTE", Const, 19}, + {"R_LARCH_SOP_PUSH_DUP", Const, 19}, + {"R_LARCH_SOP_PUSH_GPREL", Const, 19}, + {"R_LARCH_SOP_PUSH_PCREL", Const, 19}, + {"R_LARCH_SOP_PUSH_PLT_PCREL", Const, 19}, + {"R_LARCH_SOP_PUSH_TLS_GD", Const, 19}, + {"R_LARCH_SOP_PUSH_TLS_GOT", Const, 19}, + {"R_LARCH_SOP_PUSH_TLS_TPREL", Const, 19}, + {"R_LARCH_SOP_SL", Const, 19}, + {"R_LARCH_SOP_SR", Const, 19}, + {"R_LARCH_SOP_SUB", Const, 19}, + {"R_LARCH_SUB16", Const, 19}, + {"R_LARCH_SUB24", Const, 19}, + {"R_LARCH_SUB32", Const, 19}, + {"R_LARCH_SUB6", Const, 22}, + {"R_LARCH_SUB64", Const, 19}, + {"R_LARCH_SUB8", Const, 19}, + {"R_LARCH_SUB_ULEB128", Const, 22}, + {"R_LARCH_TLS_DTPMOD32", Const, 19}, + {"R_LARCH_TLS_DTPMOD64", Const, 19}, + {"R_LARCH_TLS_DTPREL32", Const, 19}, + {"R_LARCH_TLS_DTPREL64", Const, 19}, + {"R_LARCH_TLS_GD_HI20", Const, 20}, + {"R_LARCH_TLS_GD_PC_HI20", Const, 20}, + {"R_LARCH_TLS_IE64_HI12", Const, 20}, + {"R_LARCH_TLS_IE64_LO20", Const, 20}, + {"R_LARCH_TLS_IE64_PC_HI12", Const, 20}, + {"R_LARCH_TLS_IE64_PC_LO20", Const, 20}, + {"R_LARCH_TLS_IE_HI20", Const, 20}, + {"R_LARCH_TLS_IE_LO12", Const, 20}, + {"R_LARCH_TLS_IE_PC_HI20", Const, 20}, + {"R_LARCH_TLS_IE_PC_LO12", Const, 20}, + {"R_LARCH_TLS_LD_HI20", Const, 20}, + {"R_LARCH_TLS_LD_PC_HI20", Const, 20}, + {"R_LARCH_TLS_LE64_HI12", Const, 20}, + {"R_LARCH_TLS_LE64_LO20", Const, 20}, + {"R_LARCH_TLS_LE_HI20", Const, 20}, + {"R_LARCH_TLS_LE_LO12", Const, 20}, + {"R_LARCH_TLS_TPREL32", Const, 19}, + {"R_LARCH_TLS_TPREL64", Const, 19}, + {"R_MIPS", Type, 6}, + {"R_MIPS_16", Const, 6}, + {"R_MIPS_26", Const, 6}, + {"R_MIPS_32", Const, 6}, + {"R_MIPS_64", Const, 6}, + {"R_MIPS_ADD_IMMEDIATE", Const, 6}, + {"R_MIPS_CALL16", Const, 6}, + {"R_MIPS_CALL_HI16", Const, 6}, + {"R_MIPS_CALL_LO16", Const, 6}, + {"R_MIPS_DELETE", Const, 6}, + {"R_MIPS_GOT16", Const, 6}, + {"R_MIPS_GOT_DISP", Const, 6}, + {"R_MIPS_GOT_HI16", Const, 6}, + {"R_MIPS_GOT_LO16", Const, 6}, + {"R_MIPS_GOT_OFST", Const, 6}, + {"R_MIPS_GOT_PAGE", Const, 6}, + {"R_MIPS_GPREL16", Const, 6}, + {"R_MIPS_GPREL32", Const, 6}, + {"R_MIPS_HI16", Const, 6}, + {"R_MIPS_HIGHER", Const, 6}, + {"R_MIPS_HIGHEST", Const, 6}, + {"R_MIPS_INSERT_A", Const, 6}, + {"R_MIPS_INSERT_B", Const, 6}, + {"R_MIPS_JALR", Const, 6}, + {"R_MIPS_LITERAL", Const, 6}, + {"R_MIPS_LO16", Const, 6}, + {"R_MIPS_NONE", Const, 6}, + {"R_MIPS_PC16", Const, 6}, + {"R_MIPS_PC32", Const, 22}, + {"R_MIPS_PJUMP", Const, 6}, + {"R_MIPS_REL16", Const, 6}, + {"R_MIPS_REL32", Const, 6}, + {"R_MIPS_RELGOT", Const, 6}, + {"R_MIPS_SCN_DISP", Const, 6}, + {"R_MIPS_SHIFT5", Const, 6}, + {"R_MIPS_SHIFT6", Const, 6}, + {"R_MIPS_SUB", Const, 6}, + {"R_MIPS_TLS_DTPMOD32", Const, 6}, + {"R_MIPS_TLS_DTPMOD64", Const, 6}, + {"R_MIPS_TLS_DTPREL32", Const, 6}, + {"R_MIPS_TLS_DTPREL64", Const, 6}, + {"R_MIPS_TLS_DTPREL_HI16", Const, 6}, + {"R_MIPS_TLS_DTPREL_LO16", Const, 6}, + {"R_MIPS_TLS_GD", Const, 6}, + {"R_MIPS_TLS_GOTTPREL", Const, 6}, + {"R_MIPS_TLS_LDM", Const, 6}, + {"R_MIPS_TLS_TPREL32", Const, 6}, + {"R_MIPS_TLS_TPREL64", Const, 6}, + {"R_MIPS_TLS_TPREL_HI16", Const, 6}, + {"R_MIPS_TLS_TPREL_LO16", Const, 6}, + {"R_PPC", Type, 0}, + {"R_PPC64", Type, 5}, + {"R_PPC64_ADDR14", Const, 5}, + {"R_PPC64_ADDR14_BRNTAKEN", Const, 5}, + {"R_PPC64_ADDR14_BRTAKEN", Const, 5}, + {"R_PPC64_ADDR16", Const, 5}, + {"R_PPC64_ADDR16_DS", Const, 5}, + {"R_PPC64_ADDR16_HA", Const, 5}, + {"R_PPC64_ADDR16_HI", Const, 5}, + {"R_PPC64_ADDR16_HIGH", Const, 10}, + {"R_PPC64_ADDR16_HIGHA", Const, 10}, + {"R_PPC64_ADDR16_HIGHER", Const, 5}, + {"R_PPC64_ADDR16_HIGHER34", Const, 20}, + {"R_PPC64_ADDR16_HIGHERA", Const, 5}, + {"R_PPC64_ADDR16_HIGHERA34", Const, 20}, + {"R_PPC64_ADDR16_HIGHEST", Const, 5}, + {"R_PPC64_ADDR16_HIGHEST34", Const, 20}, + {"R_PPC64_ADDR16_HIGHESTA", Const, 5}, + {"R_PPC64_ADDR16_HIGHESTA34", Const, 20}, + {"R_PPC64_ADDR16_LO", Const, 5}, + {"R_PPC64_ADDR16_LO_DS", Const, 5}, + {"R_PPC64_ADDR24", Const, 5}, + {"R_PPC64_ADDR32", Const, 5}, + {"R_PPC64_ADDR64", Const, 5}, + {"R_PPC64_ADDR64_LOCAL", Const, 10}, + {"R_PPC64_COPY", Const, 20}, + {"R_PPC64_D28", Const, 20}, + {"R_PPC64_D34", Const, 20}, + {"R_PPC64_D34_HA30", Const, 20}, + {"R_PPC64_D34_HI30", Const, 20}, + {"R_PPC64_D34_LO", Const, 20}, + {"R_PPC64_DTPMOD64", Const, 5}, + {"R_PPC64_DTPREL16", Const, 5}, + {"R_PPC64_DTPREL16_DS", Const, 5}, + {"R_PPC64_DTPREL16_HA", Const, 5}, + {"R_PPC64_DTPREL16_HI", Const, 5}, + {"R_PPC64_DTPREL16_HIGH", Const, 10}, + {"R_PPC64_DTPREL16_HIGHA", Const, 10}, + {"R_PPC64_DTPREL16_HIGHER", Const, 5}, + {"R_PPC64_DTPREL16_HIGHERA", Const, 5}, + {"R_PPC64_DTPREL16_HIGHEST", Const, 5}, + {"R_PPC64_DTPREL16_HIGHESTA", Const, 5}, + {"R_PPC64_DTPREL16_LO", Const, 5}, + {"R_PPC64_DTPREL16_LO_DS", Const, 5}, + {"R_PPC64_DTPREL34", Const, 20}, + {"R_PPC64_DTPREL64", Const, 5}, + {"R_PPC64_ENTRY", Const, 10}, + {"R_PPC64_GLOB_DAT", Const, 20}, + {"R_PPC64_GNU_VTENTRY", Const, 20}, + {"R_PPC64_GNU_VTINHERIT", Const, 20}, + {"R_PPC64_GOT16", Const, 5}, + {"R_PPC64_GOT16_DS", Const, 5}, + {"R_PPC64_GOT16_HA", Const, 5}, + {"R_PPC64_GOT16_HI", Const, 5}, + {"R_PPC64_GOT16_LO", Const, 5}, + {"R_PPC64_GOT16_LO_DS", Const, 5}, + {"R_PPC64_GOT_DTPREL16_DS", Const, 5}, + {"R_PPC64_GOT_DTPREL16_HA", Const, 5}, + {"R_PPC64_GOT_DTPREL16_HI", Const, 5}, + {"R_PPC64_GOT_DTPREL16_LO_DS", Const, 5}, + {"R_PPC64_GOT_DTPREL_PCREL34", Const, 20}, + {"R_PPC64_GOT_PCREL34", Const, 20}, + {"R_PPC64_GOT_TLSGD16", Const, 5}, + {"R_PPC64_GOT_TLSGD16_HA", Const, 5}, + {"R_PPC64_GOT_TLSGD16_HI", Const, 5}, + {"R_PPC64_GOT_TLSGD16_LO", Const, 5}, + {"R_PPC64_GOT_TLSGD_PCREL34", Const, 20}, + {"R_PPC64_GOT_TLSLD16", Const, 5}, + {"R_PPC64_GOT_TLSLD16_HA", Const, 5}, + {"R_PPC64_GOT_TLSLD16_HI", Const, 5}, + {"R_PPC64_GOT_TLSLD16_LO", Const, 5}, + {"R_PPC64_GOT_TLSLD_PCREL34", Const, 20}, + {"R_PPC64_GOT_TPREL16_DS", Const, 5}, + {"R_PPC64_GOT_TPREL16_HA", Const, 5}, + {"R_PPC64_GOT_TPREL16_HI", Const, 5}, + {"R_PPC64_GOT_TPREL16_LO_DS", Const, 5}, + {"R_PPC64_GOT_TPREL_PCREL34", Const, 20}, + {"R_PPC64_IRELATIVE", Const, 10}, + {"R_PPC64_JMP_IREL", Const, 10}, + {"R_PPC64_JMP_SLOT", Const, 5}, + {"R_PPC64_NONE", Const, 5}, + {"R_PPC64_PCREL28", Const, 20}, + {"R_PPC64_PCREL34", Const, 20}, + {"R_PPC64_PCREL_OPT", Const, 20}, + {"R_PPC64_PLT16_HA", Const, 20}, + {"R_PPC64_PLT16_HI", Const, 20}, + {"R_PPC64_PLT16_LO", Const, 20}, + {"R_PPC64_PLT16_LO_DS", Const, 10}, + {"R_PPC64_PLT32", Const, 20}, + {"R_PPC64_PLT64", Const, 20}, + {"R_PPC64_PLTCALL", Const, 20}, + {"R_PPC64_PLTCALL_NOTOC", Const, 20}, + {"R_PPC64_PLTGOT16", Const, 10}, + {"R_PPC64_PLTGOT16_DS", Const, 10}, + {"R_PPC64_PLTGOT16_HA", Const, 10}, + {"R_PPC64_PLTGOT16_HI", Const, 10}, + {"R_PPC64_PLTGOT16_LO", Const, 10}, + {"R_PPC64_PLTGOT_LO_DS", Const, 10}, + {"R_PPC64_PLTREL32", Const, 20}, + {"R_PPC64_PLTREL64", Const, 20}, + {"R_PPC64_PLTSEQ", Const, 20}, + {"R_PPC64_PLTSEQ_NOTOC", Const, 20}, + {"R_PPC64_PLT_PCREL34", Const, 20}, + {"R_PPC64_PLT_PCREL34_NOTOC", Const, 20}, + {"R_PPC64_REL14", Const, 5}, + {"R_PPC64_REL14_BRNTAKEN", Const, 5}, + {"R_PPC64_REL14_BRTAKEN", Const, 5}, + {"R_PPC64_REL16", Const, 5}, + {"R_PPC64_REL16DX_HA", Const, 10}, + {"R_PPC64_REL16_HA", Const, 5}, + {"R_PPC64_REL16_HI", Const, 5}, + {"R_PPC64_REL16_HIGH", Const, 20}, + {"R_PPC64_REL16_HIGHA", Const, 20}, + {"R_PPC64_REL16_HIGHER", Const, 20}, + {"R_PPC64_REL16_HIGHER34", Const, 20}, + {"R_PPC64_REL16_HIGHERA", Const, 20}, + {"R_PPC64_REL16_HIGHERA34", Const, 20}, + {"R_PPC64_REL16_HIGHEST", Const, 20}, + {"R_PPC64_REL16_HIGHEST34", Const, 20}, + {"R_PPC64_REL16_HIGHESTA", Const, 20}, + {"R_PPC64_REL16_HIGHESTA34", Const, 20}, + {"R_PPC64_REL16_LO", Const, 5}, + {"R_PPC64_REL24", Const, 5}, + {"R_PPC64_REL24_NOTOC", Const, 10}, + {"R_PPC64_REL24_P9NOTOC", Const, 21}, + {"R_PPC64_REL30", Const, 20}, + {"R_PPC64_REL32", Const, 5}, + {"R_PPC64_REL64", Const, 5}, + {"R_PPC64_RELATIVE", Const, 18}, + {"R_PPC64_SECTOFF", Const, 20}, + {"R_PPC64_SECTOFF_DS", Const, 10}, + {"R_PPC64_SECTOFF_HA", Const, 20}, + {"R_PPC64_SECTOFF_HI", Const, 20}, + {"R_PPC64_SECTOFF_LO", Const, 20}, + {"R_PPC64_SECTOFF_LO_DS", Const, 10}, + {"R_PPC64_TLS", Const, 5}, + {"R_PPC64_TLSGD", Const, 5}, + {"R_PPC64_TLSLD", Const, 5}, + {"R_PPC64_TOC", Const, 5}, + {"R_PPC64_TOC16", Const, 5}, + {"R_PPC64_TOC16_DS", Const, 5}, + {"R_PPC64_TOC16_HA", Const, 5}, + {"R_PPC64_TOC16_HI", Const, 5}, + {"R_PPC64_TOC16_LO", Const, 5}, + {"R_PPC64_TOC16_LO_DS", Const, 5}, + {"R_PPC64_TOCSAVE", Const, 10}, + {"R_PPC64_TPREL16", Const, 5}, + {"R_PPC64_TPREL16_DS", Const, 5}, + {"R_PPC64_TPREL16_HA", Const, 5}, + {"R_PPC64_TPREL16_HI", Const, 5}, + {"R_PPC64_TPREL16_HIGH", Const, 10}, + {"R_PPC64_TPREL16_HIGHA", Const, 10}, + {"R_PPC64_TPREL16_HIGHER", Const, 5}, + {"R_PPC64_TPREL16_HIGHERA", Const, 5}, + {"R_PPC64_TPREL16_HIGHEST", Const, 5}, + {"R_PPC64_TPREL16_HIGHESTA", Const, 5}, + {"R_PPC64_TPREL16_LO", Const, 5}, + {"R_PPC64_TPREL16_LO_DS", Const, 5}, + {"R_PPC64_TPREL34", Const, 20}, + {"R_PPC64_TPREL64", Const, 5}, + {"R_PPC64_UADDR16", Const, 20}, + {"R_PPC64_UADDR32", Const, 20}, + {"R_PPC64_UADDR64", Const, 20}, + {"R_PPC_ADDR14", Const, 0}, + {"R_PPC_ADDR14_BRNTAKEN", Const, 0}, + {"R_PPC_ADDR14_BRTAKEN", Const, 0}, + {"R_PPC_ADDR16", Const, 0}, + {"R_PPC_ADDR16_HA", Const, 0}, + {"R_PPC_ADDR16_HI", Const, 0}, + {"R_PPC_ADDR16_LO", Const, 0}, + {"R_PPC_ADDR24", Const, 0}, + {"R_PPC_ADDR32", Const, 0}, + {"R_PPC_COPY", Const, 0}, + {"R_PPC_DTPMOD32", Const, 0}, + {"R_PPC_DTPREL16", Const, 0}, + {"R_PPC_DTPREL16_HA", Const, 0}, + {"R_PPC_DTPREL16_HI", Const, 0}, + {"R_PPC_DTPREL16_LO", Const, 0}, + {"R_PPC_DTPREL32", Const, 0}, + {"R_PPC_EMB_BIT_FLD", Const, 0}, + {"R_PPC_EMB_MRKREF", Const, 0}, + {"R_PPC_EMB_NADDR16", Const, 0}, + {"R_PPC_EMB_NADDR16_HA", Const, 0}, + {"R_PPC_EMB_NADDR16_HI", Const, 0}, + {"R_PPC_EMB_NADDR16_LO", Const, 0}, + {"R_PPC_EMB_NADDR32", Const, 0}, + {"R_PPC_EMB_RELSDA", Const, 0}, + {"R_PPC_EMB_RELSEC16", Const, 0}, + {"R_PPC_EMB_RELST_HA", Const, 0}, + {"R_PPC_EMB_RELST_HI", Const, 0}, + {"R_PPC_EMB_RELST_LO", Const, 0}, + {"R_PPC_EMB_SDA21", Const, 0}, + {"R_PPC_EMB_SDA2I16", Const, 0}, + {"R_PPC_EMB_SDA2REL", Const, 0}, + {"R_PPC_EMB_SDAI16", Const, 0}, + {"R_PPC_GLOB_DAT", Const, 0}, + {"R_PPC_GOT16", Const, 0}, + {"R_PPC_GOT16_HA", Const, 0}, + {"R_PPC_GOT16_HI", Const, 0}, + {"R_PPC_GOT16_LO", Const, 0}, + {"R_PPC_GOT_TLSGD16", Const, 0}, + {"R_PPC_GOT_TLSGD16_HA", Const, 0}, + {"R_PPC_GOT_TLSGD16_HI", Const, 0}, + {"R_PPC_GOT_TLSGD16_LO", Const, 0}, + {"R_PPC_GOT_TLSLD16", Const, 0}, + {"R_PPC_GOT_TLSLD16_HA", Const, 0}, + {"R_PPC_GOT_TLSLD16_HI", Const, 0}, + {"R_PPC_GOT_TLSLD16_LO", Const, 0}, + {"R_PPC_GOT_TPREL16", Const, 0}, + {"R_PPC_GOT_TPREL16_HA", Const, 0}, + {"R_PPC_GOT_TPREL16_HI", Const, 0}, + {"R_PPC_GOT_TPREL16_LO", Const, 0}, + {"R_PPC_JMP_SLOT", Const, 0}, + {"R_PPC_LOCAL24PC", Const, 0}, + {"R_PPC_NONE", Const, 0}, + {"R_PPC_PLT16_HA", Const, 0}, + {"R_PPC_PLT16_HI", Const, 0}, + {"R_PPC_PLT16_LO", Const, 0}, + {"R_PPC_PLT32", Const, 0}, + {"R_PPC_PLTREL24", Const, 0}, + {"R_PPC_PLTREL32", Const, 0}, + {"R_PPC_REL14", Const, 0}, + {"R_PPC_REL14_BRNTAKEN", Const, 0}, + {"R_PPC_REL14_BRTAKEN", Const, 0}, + {"R_PPC_REL24", Const, 0}, + {"R_PPC_REL32", Const, 0}, + {"R_PPC_RELATIVE", Const, 0}, + {"R_PPC_SDAREL16", Const, 0}, + {"R_PPC_SECTOFF", Const, 0}, + {"R_PPC_SECTOFF_HA", Const, 0}, + {"R_PPC_SECTOFF_HI", Const, 0}, + {"R_PPC_SECTOFF_LO", Const, 0}, + {"R_PPC_TLS", Const, 0}, + {"R_PPC_TPREL16", Const, 0}, + {"R_PPC_TPREL16_HA", Const, 0}, + {"R_PPC_TPREL16_HI", Const, 0}, + {"R_PPC_TPREL16_LO", Const, 0}, + {"R_PPC_TPREL32", Const, 0}, + {"R_PPC_UADDR16", Const, 0}, + {"R_PPC_UADDR32", Const, 0}, + {"R_RISCV", Type, 11}, + {"R_RISCV_32", Const, 11}, + {"R_RISCV_32_PCREL", Const, 12}, + {"R_RISCV_64", Const, 11}, + {"R_RISCV_ADD16", Const, 11}, + {"R_RISCV_ADD32", Const, 11}, + {"R_RISCV_ADD64", Const, 11}, + {"R_RISCV_ADD8", Const, 11}, + {"R_RISCV_ALIGN", Const, 11}, + {"R_RISCV_BRANCH", Const, 11}, + {"R_RISCV_CALL", Const, 11}, + {"R_RISCV_CALL_PLT", Const, 11}, + {"R_RISCV_COPY", Const, 11}, + {"R_RISCV_GNU_VTENTRY", Const, 11}, + {"R_RISCV_GNU_VTINHERIT", Const, 11}, + {"R_RISCV_GOT_HI20", Const, 11}, + {"R_RISCV_GPREL_I", Const, 11}, + {"R_RISCV_GPREL_S", Const, 11}, + {"R_RISCV_HI20", Const, 11}, + {"R_RISCV_JAL", Const, 11}, + {"R_RISCV_JUMP_SLOT", Const, 11}, + {"R_RISCV_LO12_I", Const, 11}, + {"R_RISCV_LO12_S", Const, 11}, + {"R_RISCV_NONE", Const, 11}, + {"R_RISCV_PCREL_HI20", Const, 11}, + {"R_RISCV_PCREL_LO12_I", Const, 11}, + {"R_RISCV_PCREL_LO12_S", Const, 11}, + {"R_RISCV_RELATIVE", Const, 11}, + {"R_RISCV_RELAX", Const, 11}, + {"R_RISCV_RVC_BRANCH", Const, 11}, + {"R_RISCV_RVC_JUMP", Const, 11}, + {"R_RISCV_RVC_LUI", Const, 11}, + {"R_RISCV_SET16", Const, 11}, + {"R_RISCV_SET32", Const, 11}, + {"R_RISCV_SET6", Const, 11}, + {"R_RISCV_SET8", Const, 11}, + {"R_RISCV_SUB16", Const, 11}, + {"R_RISCV_SUB32", Const, 11}, + {"R_RISCV_SUB6", Const, 11}, + {"R_RISCV_SUB64", Const, 11}, + {"R_RISCV_SUB8", Const, 11}, + {"R_RISCV_TLS_DTPMOD32", Const, 11}, + {"R_RISCV_TLS_DTPMOD64", Const, 11}, + {"R_RISCV_TLS_DTPREL32", Const, 11}, + {"R_RISCV_TLS_DTPREL64", Const, 11}, + {"R_RISCV_TLS_GD_HI20", Const, 11}, + {"R_RISCV_TLS_GOT_HI20", Const, 11}, + {"R_RISCV_TLS_TPREL32", Const, 11}, + {"R_RISCV_TLS_TPREL64", Const, 11}, + {"R_RISCV_TPREL_ADD", Const, 11}, + {"R_RISCV_TPREL_HI20", Const, 11}, + {"R_RISCV_TPREL_I", Const, 11}, + {"R_RISCV_TPREL_LO12_I", Const, 11}, + {"R_RISCV_TPREL_LO12_S", Const, 11}, + {"R_RISCV_TPREL_S", Const, 11}, + {"R_SPARC", Type, 0}, + {"R_SPARC_10", Const, 0}, + {"R_SPARC_11", Const, 0}, + {"R_SPARC_13", Const, 0}, + {"R_SPARC_16", Const, 0}, + {"R_SPARC_22", Const, 0}, + {"R_SPARC_32", Const, 0}, + {"R_SPARC_5", Const, 0}, + {"R_SPARC_6", Const, 0}, + {"R_SPARC_64", Const, 0}, + {"R_SPARC_7", Const, 0}, + {"R_SPARC_8", Const, 0}, + {"R_SPARC_COPY", Const, 0}, + {"R_SPARC_DISP16", Const, 0}, + {"R_SPARC_DISP32", Const, 0}, + {"R_SPARC_DISP64", Const, 0}, + {"R_SPARC_DISP8", Const, 0}, + {"R_SPARC_GLOB_DAT", Const, 0}, + {"R_SPARC_GLOB_JMP", Const, 0}, + {"R_SPARC_GOT10", Const, 0}, + {"R_SPARC_GOT13", Const, 0}, + {"R_SPARC_GOT22", Const, 0}, + {"R_SPARC_H44", Const, 0}, + {"R_SPARC_HH22", Const, 0}, + {"R_SPARC_HI22", Const, 0}, + {"R_SPARC_HIPLT22", Const, 0}, + {"R_SPARC_HIX22", Const, 0}, + {"R_SPARC_HM10", Const, 0}, + {"R_SPARC_JMP_SLOT", Const, 0}, + {"R_SPARC_L44", Const, 0}, + {"R_SPARC_LM22", Const, 0}, + {"R_SPARC_LO10", Const, 0}, + {"R_SPARC_LOPLT10", Const, 0}, + {"R_SPARC_LOX10", Const, 0}, + {"R_SPARC_M44", Const, 0}, + {"R_SPARC_NONE", Const, 0}, + {"R_SPARC_OLO10", Const, 0}, + {"R_SPARC_PC10", Const, 0}, + {"R_SPARC_PC22", Const, 0}, + {"R_SPARC_PCPLT10", Const, 0}, + {"R_SPARC_PCPLT22", Const, 0}, + {"R_SPARC_PCPLT32", Const, 0}, + {"R_SPARC_PC_HH22", Const, 0}, + {"R_SPARC_PC_HM10", Const, 0}, + {"R_SPARC_PC_LM22", Const, 0}, + {"R_SPARC_PLT32", Const, 0}, + {"R_SPARC_PLT64", Const, 0}, + {"R_SPARC_REGISTER", Const, 0}, + {"R_SPARC_RELATIVE", Const, 0}, + {"R_SPARC_UA16", Const, 0}, + {"R_SPARC_UA32", Const, 0}, + {"R_SPARC_UA64", Const, 0}, + {"R_SPARC_WDISP16", Const, 0}, + {"R_SPARC_WDISP19", Const, 0}, + {"R_SPARC_WDISP22", Const, 0}, + {"R_SPARC_WDISP30", Const, 0}, + {"R_SPARC_WPLT30", Const, 0}, + {"R_SYM32", Func, 0}, + {"R_SYM64", Func, 0}, + {"R_TYPE32", Func, 0}, + {"R_TYPE64", Func, 0}, + {"R_X86_64", Type, 0}, + {"R_X86_64_16", Const, 0}, + {"R_X86_64_32", Const, 0}, + {"R_X86_64_32S", Const, 0}, + {"R_X86_64_64", Const, 0}, + {"R_X86_64_8", Const, 0}, + {"R_X86_64_COPY", Const, 0}, + {"R_X86_64_DTPMOD64", Const, 0}, + {"R_X86_64_DTPOFF32", Const, 0}, + {"R_X86_64_DTPOFF64", Const, 0}, + {"R_X86_64_GLOB_DAT", Const, 0}, + {"R_X86_64_GOT32", Const, 0}, + {"R_X86_64_GOT64", Const, 10}, + {"R_X86_64_GOTOFF64", Const, 10}, + {"R_X86_64_GOTPC32", Const, 10}, + {"R_X86_64_GOTPC32_TLSDESC", Const, 10}, + {"R_X86_64_GOTPC64", Const, 10}, + {"R_X86_64_GOTPCREL", Const, 0}, + {"R_X86_64_GOTPCREL64", Const, 10}, + {"R_X86_64_GOTPCRELX", Const, 10}, + {"R_X86_64_GOTPLT64", Const, 10}, + {"R_X86_64_GOTTPOFF", Const, 0}, + {"R_X86_64_IRELATIVE", Const, 10}, + {"R_X86_64_JMP_SLOT", Const, 0}, + {"R_X86_64_NONE", Const, 0}, + {"R_X86_64_PC16", Const, 0}, + {"R_X86_64_PC32", Const, 0}, + {"R_X86_64_PC32_BND", Const, 10}, + {"R_X86_64_PC64", Const, 10}, + {"R_X86_64_PC8", Const, 0}, + {"R_X86_64_PLT32", Const, 0}, + {"R_X86_64_PLT32_BND", Const, 10}, + {"R_X86_64_PLTOFF64", Const, 10}, + {"R_X86_64_RELATIVE", Const, 0}, + {"R_X86_64_RELATIVE64", Const, 10}, + {"R_X86_64_REX_GOTPCRELX", Const, 10}, + {"R_X86_64_SIZE32", Const, 10}, + {"R_X86_64_SIZE64", Const, 10}, + {"R_X86_64_TLSDESC", Const, 10}, + {"R_X86_64_TLSDESC_CALL", Const, 10}, + {"R_X86_64_TLSGD", Const, 0}, + {"R_X86_64_TLSLD", Const, 0}, + {"R_X86_64_TPOFF32", Const, 0}, + {"R_X86_64_TPOFF64", Const, 0}, + {"Rel32", Type, 0}, + {"Rel32.Info", Field, 0}, + {"Rel32.Off", Field, 0}, + {"Rel64", Type, 0}, + {"Rel64.Info", Field, 0}, + {"Rel64.Off", Field, 0}, + {"Rela32", Type, 0}, + {"Rela32.Addend", Field, 0}, + {"Rela32.Info", Field, 0}, + {"Rela32.Off", Field, 0}, + {"Rela64", Type, 0}, + {"Rela64.Addend", Field, 0}, + {"Rela64.Info", Field, 0}, + {"Rela64.Off", Field, 0}, + {"SHF_ALLOC", Const, 0}, + {"SHF_COMPRESSED", Const, 6}, + {"SHF_EXECINSTR", Const, 0}, + {"SHF_GROUP", Const, 0}, + {"SHF_INFO_LINK", Const, 0}, + {"SHF_LINK_ORDER", Const, 0}, + {"SHF_MASKOS", Const, 0}, + {"SHF_MASKPROC", Const, 0}, + {"SHF_MERGE", Const, 0}, + {"SHF_OS_NONCONFORMING", Const, 0}, + {"SHF_STRINGS", Const, 0}, + {"SHF_TLS", Const, 0}, + {"SHF_WRITE", Const, 0}, + {"SHN_ABS", Const, 0}, + {"SHN_COMMON", Const, 0}, + {"SHN_HIOS", Const, 0}, + {"SHN_HIPROC", Const, 0}, + {"SHN_HIRESERVE", Const, 0}, + {"SHN_LOOS", Const, 0}, + {"SHN_LOPROC", Const, 0}, + {"SHN_LORESERVE", Const, 0}, + {"SHN_UNDEF", Const, 0}, + {"SHN_XINDEX", Const, 0}, + {"SHT_DYNAMIC", Const, 0}, + {"SHT_DYNSYM", Const, 0}, + {"SHT_FINI_ARRAY", Const, 0}, + {"SHT_GNU_ATTRIBUTES", Const, 0}, + {"SHT_GNU_HASH", Const, 0}, + {"SHT_GNU_LIBLIST", Const, 0}, + {"SHT_GNU_VERDEF", Const, 0}, + {"SHT_GNU_VERNEED", Const, 0}, + {"SHT_GNU_VERSYM", Const, 0}, + {"SHT_GROUP", Const, 0}, + {"SHT_HASH", Const, 0}, + {"SHT_HIOS", Const, 0}, + {"SHT_HIPROC", Const, 0}, + {"SHT_HIUSER", Const, 0}, + {"SHT_INIT_ARRAY", Const, 0}, + {"SHT_LOOS", Const, 0}, + {"SHT_LOPROC", Const, 0}, + {"SHT_LOUSER", Const, 0}, + {"SHT_MIPS_ABIFLAGS", Const, 17}, + {"SHT_NOBITS", Const, 0}, + {"SHT_NOTE", Const, 0}, + {"SHT_NULL", Const, 0}, + {"SHT_PREINIT_ARRAY", Const, 0}, + {"SHT_PROGBITS", Const, 0}, + {"SHT_REL", Const, 0}, + {"SHT_RELA", Const, 0}, + {"SHT_SHLIB", Const, 0}, + {"SHT_STRTAB", Const, 0}, + {"SHT_SYMTAB", Const, 0}, + {"SHT_SYMTAB_SHNDX", Const, 0}, + {"STB_GLOBAL", Const, 0}, + {"STB_HIOS", Const, 0}, + {"STB_HIPROC", Const, 0}, + {"STB_LOCAL", Const, 0}, + {"STB_LOOS", Const, 0}, + {"STB_LOPROC", Const, 0}, + {"STB_WEAK", Const, 0}, + {"STT_COMMON", Const, 0}, + {"STT_FILE", Const, 0}, + {"STT_FUNC", Const, 0}, + {"STT_GNU_IFUNC", Const, 23}, + {"STT_HIOS", Const, 0}, + {"STT_HIPROC", Const, 0}, + {"STT_LOOS", Const, 0}, + {"STT_LOPROC", Const, 0}, + {"STT_NOTYPE", Const, 0}, + {"STT_OBJECT", Const, 0}, + {"STT_RELC", Const, 23}, + {"STT_SECTION", Const, 0}, + {"STT_SRELC", Const, 23}, + {"STT_TLS", Const, 0}, + {"STV_DEFAULT", Const, 0}, + {"STV_HIDDEN", Const, 0}, + {"STV_INTERNAL", Const, 0}, + {"STV_PROTECTED", Const, 0}, + {"ST_BIND", Func, 0}, + {"ST_INFO", Func, 0}, + {"ST_TYPE", Func, 0}, + {"ST_VISIBILITY", Func, 0}, + {"Section", Type, 0}, + {"Section.ReaderAt", Field, 0}, + {"Section.SectionHeader", Field, 0}, + {"Section32", Type, 0}, + {"Section32.Addr", Field, 0}, + {"Section32.Addralign", Field, 0}, + {"Section32.Entsize", Field, 0}, + {"Section32.Flags", Field, 0}, + {"Section32.Info", Field, 0}, + {"Section32.Link", Field, 0}, + {"Section32.Name", Field, 0}, + {"Section32.Off", Field, 0}, + {"Section32.Size", Field, 0}, + {"Section32.Type", Field, 0}, + {"Section64", Type, 0}, + {"Section64.Addr", Field, 0}, + {"Section64.Addralign", Field, 0}, + {"Section64.Entsize", Field, 0}, + {"Section64.Flags", Field, 0}, + {"Section64.Info", Field, 0}, + {"Section64.Link", Field, 0}, + {"Section64.Name", Field, 0}, + {"Section64.Off", Field, 0}, + {"Section64.Size", Field, 0}, + {"Section64.Type", Field, 0}, + {"SectionFlag", Type, 0}, + {"SectionHeader", Type, 0}, + {"SectionHeader.Addr", Field, 0}, + {"SectionHeader.Addralign", Field, 0}, + {"SectionHeader.Entsize", Field, 0}, + {"SectionHeader.FileSize", Field, 6}, + {"SectionHeader.Flags", Field, 0}, + {"SectionHeader.Info", Field, 0}, + {"SectionHeader.Link", Field, 0}, + {"SectionHeader.Name", Field, 0}, + {"SectionHeader.Offset", Field, 0}, + {"SectionHeader.Size", Field, 0}, + {"SectionHeader.Type", Field, 0}, + {"SectionIndex", Type, 0}, + {"SectionType", Type, 0}, + {"Sym32", Type, 0}, + {"Sym32.Info", Field, 0}, + {"Sym32.Name", Field, 0}, + {"Sym32.Other", Field, 0}, + {"Sym32.Shndx", Field, 0}, + {"Sym32.Size", Field, 0}, + {"Sym32.Value", Field, 0}, + {"Sym32Size", Const, 0}, + {"Sym64", Type, 0}, + {"Sym64.Info", Field, 0}, + {"Sym64.Name", Field, 0}, + {"Sym64.Other", Field, 0}, + {"Sym64.Shndx", Field, 0}, + {"Sym64.Size", Field, 0}, + {"Sym64.Value", Field, 0}, + {"Sym64Size", Const, 0}, + {"SymBind", Type, 0}, + {"SymType", Type, 0}, + {"SymVis", Type, 0}, + {"Symbol", Type, 0}, + {"Symbol.Info", Field, 0}, + {"Symbol.Library", Field, 13}, + {"Symbol.Name", Field, 0}, + {"Symbol.Other", Field, 0}, + {"Symbol.Section", Field, 0}, + {"Symbol.Size", Field, 0}, + {"Symbol.Value", Field, 0}, + {"Symbol.Version", Field, 13}, + {"Type", Type, 0}, + {"Version", Type, 0}, + }, + "debug/gosym": { + {"(*DecodingError).Error", Method, 0}, + {"(*LineTable).LineToPC", Method, 0}, + {"(*LineTable).PCToLine", Method, 0}, + {"(*Sym).BaseName", Method, 0}, + {"(*Sym).PackageName", Method, 0}, + {"(*Sym).ReceiverName", Method, 0}, + {"(*Sym).Static", Method, 0}, + {"(*Table).LineToPC", Method, 0}, + {"(*Table).LookupFunc", Method, 0}, + {"(*Table).LookupSym", Method, 0}, + {"(*Table).PCToFunc", Method, 0}, + {"(*Table).PCToLine", Method, 0}, + {"(*Table).SymByAddr", Method, 0}, + {"(*UnknownLineError).Error", Method, 0}, + {"(Func).BaseName", Method, 0}, + {"(Func).PackageName", Method, 0}, + {"(Func).ReceiverName", Method, 0}, + {"(Func).Static", Method, 0}, + {"(UnknownFileError).Error", Method, 0}, + {"DecodingError", Type, 0}, + {"Func", Type, 0}, + {"Func.End", Field, 0}, + {"Func.Entry", Field, 0}, + {"Func.FrameSize", Field, 0}, + {"Func.LineTable", Field, 0}, + {"Func.Locals", Field, 0}, + {"Func.Obj", Field, 0}, + {"Func.Params", Field, 0}, + {"Func.Sym", Field, 0}, + {"LineTable", Type, 0}, + {"LineTable.Data", Field, 0}, + {"LineTable.Line", Field, 0}, + {"LineTable.PC", Field, 0}, + {"NewLineTable", Func, 0}, + {"NewTable", Func, 0}, + {"Obj", Type, 0}, + {"Obj.Funcs", Field, 0}, + {"Obj.Paths", Field, 0}, + {"Sym", Type, 0}, + {"Sym.Func", Field, 0}, + {"Sym.GoType", Field, 0}, + {"Sym.Name", Field, 0}, + {"Sym.Type", Field, 0}, + {"Sym.Value", Field, 0}, + {"Table", Type, 0}, + {"Table.Files", Field, 0}, + {"Table.Funcs", Field, 0}, + {"Table.Objs", Field, 0}, + {"Table.Syms", Field, 0}, + {"UnknownFileError", Type, 0}, + {"UnknownLineError", Type, 0}, + {"UnknownLineError.File", Field, 0}, + {"UnknownLineError.Line", Field, 0}, + }, + "debug/macho": { + {"(*FatFile).Close", Method, 3}, + {"(*File).Close", Method, 0}, + {"(*File).DWARF", Method, 0}, + {"(*File).ImportedLibraries", Method, 0}, + {"(*File).ImportedSymbols", Method, 0}, + {"(*File).Section", Method, 0}, + {"(*File).Segment", Method, 0}, + {"(*FormatError).Error", Method, 0}, + {"(*Section).Data", Method, 0}, + {"(*Section).Open", Method, 0}, + {"(*Segment).Data", Method, 0}, + {"(*Segment).Open", Method, 0}, + {"(Cpu).GoString", Method, 0}, + {"(Cpu).String", Method, 0}, + {"(Dylib).Raw", Method, 0}, + {"(Dysymtab).Raw", Method, 0}, + {"(FatArch).Close", Method, 3}, + {"(FatArch).DWARF", Method, 3}, + {"(FatArch).ImportedLibraries", Method, 3}, + {"(FatArch).ImportedSymbols", Method, 3}, + {"(FatArch).Section", Method, 3}, + {"(FatArch).Segment", Method, 3}, + {"(LoadBytes).Raw", Method, 0}, + {"(LoadCmd).GoString", Method, 0}, + {"(LoadCmd).String", Method, 0}, + {"(RelocTypeARM).GoString", Method, 10}, + {"(RelocTypeARM).String", Method, 10}, + {"(RelocTypeARM64).GoString", Method, 10}, + {"(RelocTypeARM64).String", Method, 10}, + {"(RelocTypeGeneric).GoString", Method, 10}, + {"(RelocTypeGeneric).String", Method, 10}, + {"(RelocTypeX86_64).GoString", Method, 10}, + {"(RelocTypeX86_64).String", Method, 10}, + {"(Rpath).Raw", Method, 10}, + {"(Section).ReadAt", Method, 0}, + {"(Segment).Raw", Method, 0}, + {"(Segment).ReadAt", Method, 0}, + {"(Symtab).Raw", Method, 0}, + {"(Type).GoString", Method, 10}, + {"(Type).String", Method, 10}, + {"ARM64_RELOC_ADDEND", Const, 10}, + {"ARM64_RELOC_BRANCH26", Const, 10}, + {"ARM64_RELOC_GOT_LOAD_PAGE21", Const, 10}, + {"ARM64_RELOC_GOT_LOAD_PAGEOFF12", Const, 10}, + {"ARM64_RELOC_PAGE21", Const, 10}, + {"ARM64_RELOC_PAGEOFF12", Const, 10}, + {"ARM64_RELOC_POINTER_TO_GOT", Const, 10}, + {"ARM64_RELOC_SUBTRACTOR", Const, 10}, + {"ARM64_RELOC_TLVP_LOAD_PAGE21", Const, 10}, + {"ARM64_RELOC_TLVP_LOAD_PAGEOFF12", Const, 10}, + {"ARM64_RELOC_UNSIGNED", Const, 10}, + {"ARM_RELOC_BR24", Const, 10}, + {"ARM_RELOC_HALF", Const, 10}, + {"ARM_RELOC_HALF_SECTDIFF", Const, 10}, + {"ARM_RELOC_LOCAL_SECTDIFF", Const, 10}, + {"ARM_RELOC_PAIR", Const, 10}, + {"ARM_RELOC_PB_LA_PTR", Const, 10}, + {"ARM_RELOC_SECTDIFF", Const, 10}, + {"ARM_RELOC_VANILLA", Const, 10}, + {"ARM_THUMB_32BIT_BRANCH", Const, 10}, + {"ARM_THUMB_RELOC_BR22", Const, 10}, + {"Cpu", Type, 0}, + {"Cpu386", Const, 0}, + {"CpuAmd64", Const, 0}, + {"CpuArm", Const, 3}, + {"CpuArm64", Const, 11}, + {"CpuPpc", Const, 3}, + {"CpuPpc64", Const, 3}, + {"Dylib", Type, 0}, + {"Dylib.CompatVersion", Field, 0}, + {"Dylib.CurrentVersion", Field, 0}, + {"Dylib.LoadBytes", Field, 0}, + {"Dylib.Name", Field, 0}, + {"Dylib.Time", Field, 0}, + {"DylibCmd", Type, 0}, + {"DylibCmd.Cmd", Field, 0}, + {"DylibCmd.CompatVersion", Field, 0}, + {"DylibCmd.CurrentVersion", Field, 0}, + {"DylibCmd.Len", Field, 0}, + {"DylibCmd.Name", Field, 0}, + {"DylibCmd.Time", Field, 0}, + {"Dysymtab", Type, 0}, + {"Dysymtab.DysymtabCmd", Field, 0}, + {"Dysymtab.IndirectSyms", Field, 0}, + {"Dysymtab.LoadBytes", Field, 0}, + {"DysymtabCmd", Type, 0}, + {"DysymtabCmd.Cmd", Field, 0}, + {"DysymtabCmd.Extrefsymoff", Field, 0}, + {"DysymtabCmd.Extreloff", Field, 0}, + {"DysymtabCmd.Iextdefsym", Field, 0}, + {"DysymtabCmd.Ilocalsym", Field, 0}, + {"DysymtabCmd.Indirectsymoff", Field, 0}, + {"DysymtabCmd.Iundefsym", Field, 0}, + {"DysymtabCmd.Len", Field, 0}, + {"DysymtabCmd.Locreloff", Field, 0}, + {"DysymtabCmd.Modtaboff", Field, 0}, + {"DysymtabCmd.Nextdefsym", Field, 0}, + {"DysymtabCmd.Nextrefsyms", Field, 0}, + {"DysymtabCmd.Nextrel", Field, 0}, + {"DysymtabCmd.Nindirectsyms", Field, 0}, + {"DysymtabCmd.Nlocalsym", Field, 0}, + {"DysymtabCmd.Nlocrel", Field, 0}, + {"DysymtabCmd.Nmodtab", Field, 0}, + {"DysymtabCmd.Ntoc", Field, 0}, + {"DysymtabCmd.Nundefsym", Field, 0}, + {"DysymtabCmd.Tocoffset", Field, 0}, + {"ErrNotFat", Var, 3}, + {"FatArch", Type, 3}, + {"FatArch.FatArchHeader", Field, 3}, + {"FatArch.File", Field, 3}, + {"FatArchHeader", Type, 3}, + {"FatArchHeader.Align", Field, 3}, + {"FatArchHeader.Cpu", Field, 3}, + {"FatArchHeader.Offset", Field, 3}, + {"FatArchHeader.Size", Field, 3}, + {"FatArchHeader.SubCpu", Field, 3}, + {"FatFile", Type, 3}, + {"FatFile.Arches", Field, 3}, + {"FatFile.Magic", Field, 3}, + {"File", Type, 0}, + {"File.ByteOrder", Field, 0}, + {"File.Dysymtab", Field, 0}, + {"File.FileHeader", Field, 0}, + {"File.Loads", Field, 0}, + {"File.Sections", Field, 0}, + {"File.Symtab", Field, 0}, + {"FileHeader", Type, 0}, + {"FileHeader.Cmdsz", Field, 0}, + {"FileHeader.Cpu", Field, 0}, + {"FileHeader.Flags", Field, 0}, + {"FileHeader.Magic", Field, 0}, + {"FileHeader.Ncmd", Field, 0}, + {"FileHeader.SubCpu", Field, 0}, + {"FileHeader.Type", Field, 0}, + {"FlagAllModsBound", Const, 10}, + {"FlagAllowStackExecution", Const, 10}, + {"FlagAppExtensionSafe", Const, 10}, + {"FlagBindAtLoad", Const, 10}, + {"FlagBindsToWeak", Const, 10}, + {"FlagCanonical", Const, 10}, + {"FlagDeadStrippableDylib", Const, 10}, + {"FlagDyldLink", Const, 10}, + {"FlagForceFlat", Const, 10}, + {"FlagHasTLVDescriptors", Const, 10}, + {"FlagIncrLink", Const, 10}, + {"FlagLazyInit", Const, 10}, + {"FlagNoFixPrebinding", Const, 10}, + {"FlagNoHeapExecution", Const, 10}, + {"FlagNoMultiDefs", Const, 10}, + {"FlagNoReexportedDylibs", Const, 10}, + {"FlagNoUndefs", Const, 10}, + {"FlagPIE", Const, 10}, + {"FlagPrebindable", Const, 10}, + {"FlagPrebound", Const, 10}, + {"FlagRootSafe", Const, 10}, + {"FlagSetuidSafe", Const, 10}, + {"FlagSplitSegs", Const, 10}, + {"FlagSubsectionsViaSymbols", Const, 10}, + {"FlagTwoLevel", Const, 10}, + {"FlagWeakDefines", Const, 10}, + {"FormatError", Type, 0}, + {"GENERIC_RELOC_LOCAL_SECTDIFF", Const, 10}, + {"GENERIC_RELOC_PAIR", Const, 10}, + {"GENERIC_RELOC_PB_LA_PTR", Const, 10}, + {"GENERIC_RELOC_SECTDIFF", Const, 10}, + {"GENERIC_RELOC_TLV", Const, 10}, + {"GENERIC_RELOC_VANILLA", Const, 10}, + {"Load", Type, 0}, + {"LoadBytes", Type, 0}, + {"LoadCmd", Type, 0}, + {"LoadCmdDylib", Const, 0}, + {"LoadCmdDylinker", Const, 0}, + {"LoadCmdDysymtab", Const, 0}, + {"LoadCmdRpath", Const, 10}, + {"LoadCmdSegment", Const, 0}, + {"LoadCmdSegment64", Const, 0}, + {"LoadCmdSymtab", Const, 0}, + {"LoadCmdThread", Const, 0}, + {"LoadCmdUnixThread", Const, 0}, + {"Magic32", Const, 0}, + {"Magic64", Const, 0}, + {"MagicFat", Const, 3}, + {"NewFatFile", Func, 3}, + {"NewFile", Func, 0}, + {"Nlist32", Type, 0}, + {"Nlist32.Desc", Field, 0}, + {"Nlist32.Name", Field, 0}, + {"Nlist32.Sect", Field, 0}, + {"Nlist32.Type", Field, 0}, + {"Nlist32.Value", Field, 0}, + {"Nlist64", Type, 0}, + {"Nlist64.Desc", Field, 0}, + {"Nlist64.Name", Field, 0}, + {"Nlist64.Sect", Field, 0}, + {"Nlist64.Type", Field, 0}, + {"Nlist64.Value", Field, 0}, + {"Open", Func, 0}, + {"OpenFat", Func, 3}, + {"Regs386", Type, 0}, + {"Regs386.AX", Field, 0}, + {"Regs386.BP", Field, 0}, + {"Regs386.BX", Field, 0}, + {"Regs386.CS", Field, 0}, + {"Regs386.CX", Field, 0}, + {"Regs386.DI", Field, 0}, + {"Regs386.DS", Field, 0}, + {"Regs386.DX", Field, 0}, + {"Regs386.ES", Field, 0}, + {"Regs386.FLAGS", Field, 0}, + {"Regs386.FS", Field, 0}, + {"Regs386.GS", Field, 0}, + {"Regs386.IP", Field, 0}, + {"Regs386.SI", Field, 0}, + {"Regs386.SP", Field, 0}, + {"Regs386.SS", Field, 0}, + {"RegsAMD64", Type, 0}, + {"RegsAMD64.AX", Field, 0}, + {"RegsAMD64.BP", Field, 0}, + {"RegsAMD64.BX", Field, 0}, + {"RegsAMD64.CS", Field, 0}, + {"RegsAMD64.CX", Field, 0}, + {"RegsAMD64.DI", Field, 0}, + {"RegsAMD64.DX", Field, 0}, + {"RegsAMD64.FLAGS", Field, 0}, + {"RegsAMD64.FS", Field, 0}, + {"RegsAMD64.GS", Field, 0}, + {"RegsAMD64.IP", Field, 0}, + {"RegsAMD64.R10", Field, 0}, + {"RegsAMD64.R11", Field, 0}, + {"RegsAMD64.R12", Field, 0}, + {"RegsAMD64.R13", Field, 0}, + {"RegsAMD64.R14", Field, 0}, + {"RegsAMD64.R15", Field, 0}, + {"RegsAMD64.R8", Field, 0}, + {"RegsAMD64.R9", Field, 0}, + {"RegsAMD64.SI", Field, 0}, + {"RegsAMD64.SP", Field, 0}, + {"Reloc", Type, 10}, + {"Reloc.Addr", Field, 10}, + {"Reloc.Extern", Field, 10}, + {"Reloc.Len", Field, 10}, + {"Reloc.Pcrel", Field, 10}, + {"Reloc.Scattered", Field, 10}, + {"Reloc.Type", Field, 10}, + {"Reloc.Value", Field, 10}, + {"RelocTypeARM", Type, 10}, + {"RelocTypeARM64", Type, 10}, + {"RelocTypeGeneric", Type, 10}, + {"RelocTypeX86_64", Type, 10}, + {"Rpath", Type, 10}, + {"Rpath.LoadBytes", Field, 10}, + {"Rpath.Path", Field, 10}, + {"RpathCmd", Type, 10}, + {"RpathCmd.Cmd", Field, 10}, + {"RpathCmd.Len", Field, 10}, + {"RpathCmd.Path", Field, 10}, + {"Section", Type, 0}, + {"Section.ReaderAt", Field, 0}, + {"Section.Relocs", Field, 10}, + {"Section.SectionHeader", Field, 0}, + {"Section32", Type, 0}, + {"Section32.Addr", Field, 0}, + {"Section32.Align", Field, 0}, + {"Section32.Flags", Field, 0}, + {"Section32.Name", Field, 0}, + {"Section32.Nreloc", Field, 0}, + {"Section32.Offset", Field, 0}, + {"Section32.Reloff", Field, 0}, + {"Section32.Reserve1", Field, 0}, + {"Section32.Reserve2", Field, 0}, + {"Section32.Seg", Field, 0}, + {"Section32.Size", Field, 0}, + {"Section64", Type, 0}, + {"Section64.Addr", Field, 0}, + {"Section64.Align", Field, 0}, + {"Section64.Flags", Field, 0}, + {"Section64.Name", Field, 0}, + {"Section64.Nreloc", Field, 0}, + {"Section64.Offset", Field, 0}, + {"Section64.Reloff", Field, 0}, + {"Section64.Reserve1", Field, 0}, + {"Section64.Reserve2", Field, 0}, + {"Section64.Reserve3", Field, 0}, + {"Section64.Seg", Field, 0}, + {"Section64.Size", Field, 0}, + {"SectionHeader", Type, 0}, + {"SectionHeader.Addr", Field, 0}, + {"SectionHeader.Align", Field, 0}, + {"SectionHeader.Flags", Field, 0}, + {"SectionHeader.Name", Field, 0}, + {"SectionHeader.Nreloc", Field, 0}, + {"SectionHeader.Offset", Field, 0}, + {"SectionHeader.Reloff", Field, 0}, + {"SectionHeader.Seg", Field, 0}, + {"SectionHeader.Size", Field, 0}, + {"Segment", Type, 0}, + {"Segment.LoadBytes", Field, 0}, + {"Segment.ReaderAt", Field, 0}, + {"Segment.SegmentHeader", Field, 0}, + {"Segment32", Type, 0}, + {"Segment32.Addr", Field, 0}, + {"Segment32.Cmd", Field, 0}, + {"Segment32.Filesz", Field, 0}, + {"Segment32.Flag", Field, 0}, + {"Segment32.Len", Field, 0}, + {"Segment32.Maxprot", Field, 0}, + {"Segment32.Memsz", Field, 0}, + {"Segment32.Name", Field, 0}, + {"Segment32.Nsect", Field, 0}, + {"Segment32.Offset", Field, 0}, + {"Segment32.Prot", Field, 0}, + {"Segment64", Type, 0}, + {"Segment64.Addr", Field, 0}, + {"Segment64.Cmd", Field, 0}, + {"Segment64.Filesz", Field, 0}, + {"Segment64.Flag", Field, 0}, + {"Segment64.Len", Field, 0}, + {"Segment64.Maxprot", Field, 0}, + {"Segment64.Memsz", Field, 0}, + {"Segment64.Name", Field, 0}, + {"Segment64.Nsect", Field, 0}, + {"Segment64.Offset", Field, 0}, + {"Segment64.Prot", Field, 0}, + {"SegmentHeader", Type, 0}, + {"SegmentHeader.Addr", Field, 0}, + {"SegmentHeader.Cmd", Field, 0}, + {"SegmentHeader.Filesz", Field, 0}, + {"SegmentHeader.Flag", Field, 0}, + {"SegmentHeader.Len", Field, 0}, + {"SegmentHeader.Maxprot", Field, 0}, + {"SegmentHeader.Memsz", Field, 0}, + {"SegmentHeader.Name", Field, 0}, + {"SegmentHeader.Nsect", Field, 0}, + {"SegmentHeader.Offset", Field, 0}, + {"SegmentHeader.Prot", Field, 0}, + {"Symbol", Type, 0}, + {"Symbol.Desc", Field, 0}, + {"Symbol.Name", Field, 0}, + {"Symbol.Sect", Field, 0}, + {"Symbol.Type", Field, 0}, + {"Symbol.Value", Field, 0}, + {"Symtab", Type, 0}, + {"Symtab.LoadBytes", Field, 0}, + {"Symtab.Syms", Field, 0}, + {"Symtab.SymtabCmd", Field, 0}, + {"SymtabCmd", Type, 0}, + {"SymtabCmd.Cmd", Field, 0}, + {"SymtabCmd.Len", Field, 0}, + {"SymtabCmd.Nsyms", Field, 0}, + {"SymtabCmd.Stroff", Field, 0}, + {"SymtabCmd.Strsize", Field, 0}, + {"SymtabCmd.Symoff", Field, 0}, + {"Thread", Type, 0}, + {"Thread.Cmd", Field, 0}, + {"Thread.Data", Field, 0}, + {"Thread.Len", Field, 0}, + {"Thread.Type", Field, 0}, + {"Type", Type, 0}, + {"TypeBundle", Const, 3}, + {"TypeDylib", Const, 3}, + {"TypeExec", Const, 0}, + {"TypeObj", Const, 0}, + {"X86_64_RELOC_BRANCH", Const, 10}, + {"X86_64_RELOC_GOT", Const, 10}, + {"X86_64_RELOC_GOT_LOAD", Const, 10}, + {"X86_64_RELOC_SIGNED", Const, 10}, + {"X86_64_RELOC_SIGNED_1", Const, 10}, + {"X86_64_RELOC_SIGNED_2", Const, 10}, + {"X86_64_RELOC_SIGNED_4", Const, 10}, + {"X86_64_RELOC_SUBTRACTOR", Const, 10}, + {"X86_64_RELOC_TLV", Const, 10}, + {"X86_64_RELOC_UNSIGNED", Const, 10}, + }, + "debug/pe": { + {"(*COFFSymbol).FullName", Method, 8}, + {"(*File).COFFSymbolReadSectionDefAux", Method, 19}, + {"(*File).Close", Method, 0}, + {"(*File).DWARF", Method, 0}, + {"(*File).ImportedLibraries", Method, 0}, + {"(*File).ImportedSymbols", Method, 0}, + {"(*File).Section", Method, 0}, + {"(*FormatError).Error", Method, 0}, + {"(*Section).Data", Method, 0}, + {"(*Section).Open", Method, 0}, + {"(Section).ReadAt", Method, 0}, + {"(StringTable).String", Method, 8}, + {"COFFSymbol", Type, 1}, + {"COFFSymbol.Name", Field, 1}, + {"COFFSymbol.NumberOfAuxSymbols", Field, 1}, + {"COFFSymbol.SectionNumber", Field, 1}, + {"COFFSymbol.StorageClass", Field, 1}, + {"COFFSymbol.Type", Field, 1}, + {"COFFSymbol.Value", Field, 1}, + {"COFFSymbolAuxFormat5", Type, 19}, + {"COFFSymbolAuxFormat5.Checksum", Field, 19}, + {"COFFSymbolAuxFormat5.NumLineNumbers", Field, 19}, + {"COFFSymbolAuxFormat5.NumRelocs", Field, 19}, + {"COFFSymbolAuxFormat5.SecNum", Field, 19}, + {"COFFSymbolAuxFormat5.Selection", Field, 19}, + {"COFFSymbolAuxFormat5.Size", Field, 19}, + {"COFFSymbolSize", Const, 1}, + {"DataDirectory", Type, 3}, + {"DataDirectory.Size", Field, 3}, + {"DataDirectory.VirtualAddress", Field, 3}, + {"File", Type, 0}, + {"File.COFFSymbols", Field, 8}, + {"File.FileHeader", Field, 0}, + {"File.OptionalHeader", Field, 3}, + {"File.Sections", Field, 0}, + {"File.StringTable", Field, 8}, + {"File.Symbols", Field, 1}, + {"FileHeader", Type, 0}, + {"FileHeader.Characteristics", Field, 0}, + {"FileHeader.Machine", Field, 0}, + {"FileHeader.NumberOfSections", Field, 0}, + {"FileHeader.NumberOfSymbols", Field, 0}, + {"FileHeader.PointerToSymbolTable", Field, 0}, + {"FileHeader.SizeOfOptionalHeader", Field, 0}, + {"FileHeader.TimeDateStamp", Field, 0}, + {"FormatError", Type, 0}, + {"IMAGE_COMDAT_SELECT_ANY", Const, 19}, + {"IMAGE_COMDAT_SELECT_ASSOCIATIVE", Const, 19}, + {"IMAGE_COMDAT_SELECT_EXACT_MATCH", Const, 19}, + {"IMAGE_COMDAT_SELECT_LARGEST", Const, 19}, + {"IMAGE_COMDAT_SELECT_NODUPLICATES", Const, 19}, + {"IMAGE_COMDAT_SELECT_SAME_SIZE", Const, 19}, + {"IMAGE_DIRECTORY_ENTRY_ARCHITECTURE", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_BASERELOC", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_DEBUG", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_EXCEPTION", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_EXPORT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_GLOBALPTR", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_IAT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_IMPORT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_RESOURCE", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_SECURITY", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_TLS", Const, 11}, + {"IMAGE_DLLCHARACTERISTICS_APPCONTAINER", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_GUARD_CF", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_NO_BIND", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_NO_ISOLATION", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_NO_SEH", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_NX_COMPAT", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_WDM_DRIVER", Const, 15}, + {"IMAGE_FILE_32BIT_MACHINE", Const, 15}, + {"IMAGE_FILE_AGGRESIVE_WS_TRIM", Const, 15}, + {"IMAGE_FILE_BYTES_REVERSED_HI", Const, 15}, + {"IMAGE_FILE_BYTES_REVERSED_LO", Const, 15}, + {"IMAGE_FILE_DEBUG_STRIPPED", Const, 15}, + {"IMAGE_FILE_DLL", Const, 15}, + {"IMAGE_FILE_EXECUTABLE_IMAGE", Const, 15}, + {"IMAGE_FILE_LARGE_ADDRESS_AWARE", Const, 15}, + {"IMAGE_FILE_LINE_NUMS_STRIPPED", Const, 15}, + {"IMAGE_FILE_LOCAL_SYMS_STRIPPED", Const, 15}, + {"IMAGE_FILE_MACHINE_AM33", Const, 0}, + {"IMAGE_FILE_MACHINE_AMD64", Const, 0}, + {"IMAGE_FILE_MACHINE_ARM", Const, 0}, + {"IMAGE_FILE_MACHINE_ARM64", Const, 11}, + {"IMAGE_FILE_MACHINE_ARMNT", Const, 12}, + {"IMAGE_FILE_MACHINE_EBC", Const, 0}, + {"IMAGE_FILE_MACHINE_I386", Const, 0}, + {"IMAGE_FILE_MACHINE_IA64", Const, 0}, + {"IMAGE_FILE_MACHINE_LOONGARCH32", Const, 19}, + {"IMAGE_FILE_MACHINE_LOONGARCH64", Const, 19}, + {"IMAGE_FILE_MACHINE_M32R", Const, 0}, + {"IMAGE_FILE_MACHINE_MIPS16", Const, 0}, + {"IMAGE_FILE_MACHINE_MIPSFPU", Const, 0}, + {"IMAGE_FILE_MACHINE_MIPSFPU16", Const, 0}, + {"IMAGE_FILE_MACHINE_POWERPC", Const, 0}, + {"IMAGE_FILE_MACHINE_POWERPCFP", Const, 0}, + {"IMAGE_FILE_MACHINE_R4000", Const, 0}, + {"IMAGE_FILE_MACHINE_RISCV128", Const, 20}, + {"IMAGE_FILE_MACHINE_RISCV32", Const, 20}, + {"IMAGE_FILE_MACHINE_RISCV64", Const, 20}, + {"IMAGE_FILE_MACHINE_SH3", Const, 0}, + {"IMAGE_FILE_MACHINE_SH3DSP", Const, 0}, + {"IMAGE_FILE_MACHINE_SH4", Const, 0}, + {"IMAGE_FILE_MACHINE_SH5", Const, 0}, + {"IMAGE_FILE_MACHINE_THUMB", Const, 0}, + {"IMAGE_FILE_MACHINE_UNKNOWN", Const, 0}, + {"IMAGE_FILE_MACHINE_WCEMIPSV2", Const, 0}, + {"IMAGE_FILE_NET_RUN_FROM_SWAP", Const, 15}, + {"IMAGE_FILE_RELOCS_STRIPPED", Const, 15}, + {"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP", Const, 15}, + {"IMAGE_FILE_SYSTEM", Const, 15}, + {"IMAGE_FILE_UP_SYSTEM_ONLY", Const, 15}, + {"IMAGE_SCN_CNT_CODE", Const, 19}, + {"IMAGE_SCN_CNT_INITIALIZED_DATA", Const, 19}, + {"IMAGE_SCN_CNT_UNINITIALIZED_DATA", Const, 19}, + {"IMAGE_SCN_LNK_COMDAT", Const, 19}, + {"IMAGE_SCN_MEM_DISCARDABLE", Const, 19}, + {"IMAGE_SCN_MEM_EXECUTE", Const, 19}, + {"IMAGE_SCN_MEM_READ", Const, 19}, + {"IMAGE_SCN_MEM_WRITE", Const, 19}, + {"IMAGE_SUBSYSTEM_EFI_APPLICATION", Const, 15}, + {"IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER", Const, 15}, + {"IMAGE_SUBSYSTEM_EFI_ROM", Const, 15}, + {"IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER", Const, 15}, + {"IMAGE_SUBSYSTEM_NATIVE", Const, 15}, + {"IMAGE_SUBSYSTEM_NATIVE_WINDOWS", Const, 15}, + {"IMAGE_SUBSYSTEM_OS2_CUI", Const, 15}, + {"IMAGE_SUBSYSTEM_POSIX_CUI", Const, 15}, + {"IMAGE_SUBSYSTEM_UNKNOWN", Const, 15}, + {"IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION", Const, 15}, + {"IMAGE_SUBSYSTEM_WINDOWS_CE_GUI", Const, 15}, + {"IMAGE_SUBSYSTEM_WINDOWS_CUI", Const, 15}, + {"IMAGE_SUBSYSTEM_WINDOWS_GUI", Const, 15}, + {"IMAGE_SUBSYSTEM_XBOX", Const, 15}, + {"ImportDirectory", Type, 0}, + {"ImportDirectory.FirstThunk", Field, 0}, + {"ImportDirectory.ForwarderChain", Field, 0}, + {"ImportDirectory.Name", Field, 0}, + {"ImportDirectory.OriginalFirstThunk", Field, 0}, + {"ImportDirectory.TimeDateStamp", Field, 0}, + {"NewFile", Func, 0}, + {"Open", Func, 0}, + {"OptionalHeader32", Type, 3}, + {"OptionalHeader32.AddressOfEntryPoint", Field, 3}, + {"OptionalHeader32.BaseOfCode", Field, 3}, + {"OptionalHeader32.BaseOfData", Field, 3}, + {"OptionalHeader32.CheckSum", Field, 3}, + {"OptionalHeader32.DataDirectory", Field, 3}, + {"OptionalHeader32.DllCharacteristics", Field, 3}, + {"OptionalHeader32.FileAlignment", Field, 3}, + {"OptionalHeader32.ImageBase", Field, 3}, + {"OptionalHeader32.LoaderFlags", Field, 3}, + {"OptionalHeader32.Magic", Field, 3}, + {"OptionalHeader32.MajorImageVersion", Field, 3}, + {"OptionalHeader32.MajorLinkerVersion", Field, 3}, + {"OptionalHeader32.MajorOperatingSystemVersion", Field, 3}, + {"OptionalHeader32.MajorSubsystemVersion", Field, 3}, + {"OptionalHeader32.MinorImageVersion", Field, 3}, + {"OptionalHeader32.MinorLinkerVersion", Field, 3}, + {"OptionalHeader32.MinorOperatingSystemVersion", Field, 3}, + {"OptionalHeader32.MinorSubsystemVersion", Field, 3}, + {"OptionalHeader32.NumberOfRvaAndSizes", Field, 3}, + {"OptionalHeader32.SectionAlignment", Field, 3}, + {"OptionalHeader32.SizeOfCode", Field, 3}, + {"OptionalHeader32.SizeOfHeaders", Field, 3}, + {"OptionalHeader32.SizeOfHeapCommit", Field, 3}, + {"OptionalHeader32.SizeOfHeapReserve", Field, 3}, + {"OptionalHeader32.SizeOfImage", Field, 3}, + {"OptionalHeader32.SizeOfInitializedData", Field, 3}, + {"OptionalHeader32.SizeOfStackCommit", Field, 3}, + {"OptionalHeader32.SizeOfStackReserve", Field, 3}, + {"OptionalHeader32.SizeOfUninitializedData", Field, 3}, + {"OptionalHeader32.Subsystem", Field, 3}, + {"OptionalHeader32.Win32VersionValue", Field, 3}, + {"OptionalHeader64", Type, 3}, + {"OptionalHeader64.AddressOfEntryPoint", Field, 3}, + {"OptionalHeader64.BaseOfCode", Field, 3}, + {"OptionalHeader64.CheckSum", Field, 3}, + {"OptionalHeader64.DataDirectory", Field, 3}, + {"OptionalHeader64.DllCharacteristics", Field, 3}, + {"OptionalHeader64.FileAlignment", Field, 3}, + {"OptionalHeader64.ImageBase", Field, 3}, + {"OptionalHeader64.LoaderFlags", Field, 3}, + {"OptionalHeader64.Magic", Field, 3}, + {"OptionalHeader64.MajorImageVersion", Field, 3}, + {"OptionalHeader64.MajorLinkerVersion", Field, 3}, + {"OptionalHeader64.MajorOperatingSystemVersion", Field, 3}, + {"OptionalHeader64.MajorSubsystemVersion", Field, 3}, + {"OptionalHeader64.MinorImageVersion", Field, 3}, + {"OptionalHeader64.MinorLinkerVersion", Field, 3}, + {"OptionalHeader64.MinorOperatingSystemVersion", Field, 3}, + {"OptionalHeader64.MinorSubsystemVersion", Field, 3}, + {"OptionalHeader64.NumberOfRvaAndSizes", Field, 3}, + {"OptionalHeader64.SectionAlignment", Field, 3}, + {"OptionalHeader64.SizeOfCode", Field, 3}, + {"OptionalHeader64.SizeOfHeaders", Field, 3}, + {"OptionalHeader64.SizeOfHeapCommit", Field, 3}, + {"OptionalHeader64.SizeOfHeapReserve", Field, 3}, + {"OptionalHeader64.SizeOfImage", Field, 3}, + {"OptionalHeader64.SizeOfInitializedData", Field, 3}, + {"OptionalHeader64.SizeOfStackCommit", Field, 3}, + {"OptionalHeader64.SizeOfStackReserve", Field, 3}, + {"OptionalHeader64.SizeOfUninitializedData", Field, 3}, + {"OptionalHeader64.Subsystem", Field, 3}, + {"OptionalHeader64.Win32VersionValue", Field, 3}, + {"Reloc", Type, 8}, + {"Reloc.SymbolTableIndex", Field, 8}, + {"Reloc.Type", Field, 8}, + {"Reloc.VirtualAddress", Field, 8}, + {"Section", Type, 0}, + {"Section.ReaderAt", Field, 0}, + {"Section.Relocs", Field, 8}, + {"Section.SectionHeader", Field, 0}, + {"SectionHeader", Type, 0}, + {"SectionHeader.Characteristics", Field, 0}, + {"SectionHeader.Name", Field, 0}, + {"SectionHeader.NumberOfLineNumbers", Field, 0}, + {"SectionHeader.NumberOfRelocations", Field, 0}, + {"SectionHeader.Offset", Field, 0}, + {"SectionHeader.PointerToLineNumbers", Field, 0}, + {"SectionHeader.PointerToRelocations", Field, 0}, + {"SectionHeader.Size", Field, 0}, + {"SectionHeader.VirtualAddress", Field, 0}, + {"SectionHeader.VirtualSize", Field, 0}, + {"SectionHeader32", Type, 0}, + {"SectionHeader32.Characteristics", Field, 0}, + {"SectionHeader32.Name", Field, 0}, + {"SectionHeader32.NumberOfLineNumbers", Field, 0}, + {"SectionHeader32.NumberOfRelocations", Field, 0}, + {"SectionHeader32.PointerToLineNumbers", Field, 0}, + {"SectionHeader32.PointerToRawData", Field, 0}, + {"SectionHeader32.PointerToRelocations", Field, 0}, + {"SectionHeader32.SizeOfRawData", Field, 0}, + {"SectionHeader32.VirtualAddress", Field, 0}, + {"SectionHeader32.VirtualSize", Field, 0}, + {"StringTable", Type, 8}, + {"Symbol", Type, 1}, + {"Symbol.Name", Field, 1}, + {"Symbol.SectionNumber", Field, 1}, + {"Symbol.StorageClass", Field, 1}, + {"Symbol.Type", Field, 1}, + {"Symbol.Value", Field, 1}, + }, + "debug/plan9obj": { + {"(*File).Close", Method, 3}, + {"(*File).Section", Method, 3}, + {"(*File).Symbols", Method, 3}, + {"(*Section).Data", Method, 3}, + {"(*Section).Open", Method, 3}, + {"(Section).ReadAt", Method, 3}, + {"ErrNoSymbols", Var, 18}, + {"File", Type, 3}, + {"File.FileHeader", Field, 3}, + {"File.Sections", Field, 3}, + {"FileHeader", Type, 3}, + {"FileHeader.Bss", Field, 3}, + {"FileHeader.Entry", Field, 3}, + {"FileHeader.HdrSize", Field, 4}, + {"FileHeader.LoadAddress", Field, 4}, + {"FileHeader.Magic", Field, 3}, + {"FileHeader.PtrSize", Field, 3}, + {"Magic386", Const, 3}, + {"Magic64", Const, 3}, + {"MagicAMD64", Const, 3}, + {"MagicARM", Const, 3}, + {"NewFile", Func, 3}, + {"Open", Func, 3}, + {"Section", Type, 3}, + {"Section.ReaderAt", Field, 3}, + {"Section.SectionHeader", Field, 3}, + {"SectionHeader", Type, 3}, + {"SectionHeader.Name", Field, 3}, + {"SectionHeader.Offset", Field, 3}, + {"SectionHeader.Size", Field, 3}, + {"Sym", Type, 3}, + {"Sym.Name", Field, 3}, + {"Sym.Type", Field, 3}, + {"Sym.Value", Field, 3}, + }, + "embed": { + {"(FS).Open", Method, 16}, + {"(FS).ReadDir", Method, 16}, + {"(FS).ReadFile", Method, 16}, + {"FS", Type, 16}, + }, + "encoding": { + {"BinaryMarshaler", Type, 2}, + {"BinaryUnmarshaler", Type, 2}, + {"TextMarshaler", Type, 2}, + {"TextUnmarshaler", Type, 2}, + }, + "encoding/ascii85": { + {"(CorruptInputError).Error", Method, 0}, + {"CorruptInputError", Type, 0}, + {"Decode", Func, 0}, + {"Encode", Func, 0}, + {"MaxEncodedLen", Func, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + }, + "encoding/asn1": { + {"(BitString).At", Method, 0}, + {"(BitString).RightAlign", Method, 0}, + {"(ObjectIdentifier).Equal", Method, 0}, + {"(ObjectIdentifier).String", Method, 3}, + {"(StructuralError).Error", Method, 0}, + {"(SyntaxError).Error", Method, 0}, + {"BitString", Type, 0}, + {"BitString.BitLength", Field, 0}, + {"BitString.Bytes", Field, 0}, + {"ClassApplication", Const, 6}, + {"ClassContextSpecific", Const, 6}, + {"ClassPrivate", Const, 6}, + {"ClassUniversal", Const, 6}, + {"Enumerated", Type, 0}, + {"Flag", Type, 0}, + {"Marshal", Func, 0}, + {"MarshalWithParams", Func, 10}, + {"NullBytes", Var, 9}, + {"NullRawValue", Var, 9}, + {"ObjectIdentifier", Type, 0}, + {"RawContent", Type, 0}, + {"RawValue", Type, 0}, + {"RawValue.Bytes", Field, 0}, + {"RawValue.Class", Field, 0}, + {"RawValue.FullBytes", Field, 0}, + {"RawValue.IsCompound", Field, 0}, + {"RawValue.Tag", Field, 0}, + {"StructuralError", Type, 0}, + {"StructuralError.Msg", Field, 0}, + {"SyntaxError", Type, 0}, + {"SyntaxError.Msg", Field, 0}, + {"TagBMPString", Const, 14}, + {"TagBitString", Const, 6}, + {"TagBoolean", Const, 6}, + {"TagEnum", Const, 6}, + {"TagGeneralString", Const, 6}, + {"TagGeneralizedTime", Const, 6}, + {"TagIA5String", Const, 6}, + {"TagInteger", Const, 6}, + {"TagNull", Const, 9}, + {"TagNumericString", Const, 10}, + {"TagOID", Const, 6}, + {"TagOctetString", Const, 6}, + {"TagPrintableString", Const, 6}, + {"TagSequence", Const, 6}, + {"TagSet", Const, 6}, + {"TagT61String", Const, 6}, + {"TagUTCTime", Const, 6}, + {"TagUTF8String", Const, 6}, + {"Unmarshal", Func, 0}, + {"UnmarshalWithParams", Func, 0}, + }, + "encoding/base32": { + {"(*Encoding).AppendDecode", Method, 22}, + {"(*Encoding).AppendEncode", Method, 22}, + {"(*Encoding).Decode", Method, 0}, + {"(*Encoding).DecodeString", Method, 0}, + {"(*Encoding).DecodedLen", Method, 0}, + {"(*Encoding).Encode", Method, 0}, + {"(*Encoding).EncodeToString", Method, 0}, + {"(*Encoding).EncodedLen", Method, 0}, + {"(CorruptInputError).Error", Method, 0}, + {"(Encoding).WithPadding", Method, 9}, + {"CorruptInputError", Type, 0}, + {"Encoding", Type, 0}, + {"HexEncoding", Var, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"NewEncoding", Func, 0}, + {"NoPadding", Const, 9}, + {"StdEncoding", Var, 0}, + {"StdPadding", Const, 9}, + }, + "encoding/base64": { + {"(*Encoding).AppendDecode", Method, 22}, + {"(*Encoding).AppendEncode", Method, 22}, + {"(*Encoding).Decode", Method, 0}, + {"(*Encoding).DecodeString", Method, 0}, + {"(*Encoding).DecodedLen", Method, 0}, + {"(*Encoding).Encode", Method, 0}, + {"(*Encoding).EncodeToString", Method, 0}, + {"(*Encoding).EncodedLen", Method, 0}, + {"(CorruptInputError).Error", Method, 0}, + {"(Encoding).Strict", Method, 8}, + {"(Encoding).WithPadding", Method, 5}, + {"CorruptInputError", Type, 0}, + {"Encoding", Type, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"NewEncoding", Func, 0}, + {"NoPadding", Const, 5}, + {"RawStdEncoding", Var, 5}, + {"RawURLEncoding", Var, 5}, + {"StdEncoding", Var, 0}, + {"StdPadding", Const, 5}, + {"URLEncoding", Var, 0}, + }, + "encoding/binary": { + {"Append", Func, 23}, + {"AppendByteOrder", Type, 19}, + {"AppendUvarint", Func, 19}, + {"AppendVarint", Func, 19}, + {"BigEndian", Var, 0}, + {"ByteOrder", Type, 0}, + {"Decode", Func, 23}, + {"Encode", Func, 23}, + {"LittleEndian", Var, 0}, + {"MaxVarintLen16", Const, 0}, + {"MaxVarintLen32", Const, 0}, + {"MaxVarintLen64", Const, 0}, + {"NativeEndian", Var, 21}, + {"PutUvarint", Func, 0}, + {"PutVarint", Func, 0}, + {"Read", Func, 0}, + {"ReadUvarint", Func, 0}, + {"ReadVarint", Func, 0}, + {"Size", Func, 0}, + {"Uvarint", Func, 0}, + {"Varint", Func, 0}, + {"Write", Func, 0}, + }, + "encoding/csv": { + {"(*ParseError).Error", Method, 0}, + {"(*ParseError).Unwrap", Method, 13}, + {"(*Reader).FieldPos", Method, 17}, + {"(*Reader).InputOffset", Method, 19}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).ReadAll", Method, 0}, + {"(*Writer).Error", Method, 1}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Write", Method, 0}, + {"(*Writer).WriteAll", Method, 0}, + {"ErrBareQuote", Var, 0}, + {"ErrFieldCount", Var, 0}, + {"ErrQuote", Var, 0}, + {"ErrTrailingComma", Var, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"ParseError", Type, 0}, + {"ParseError.Column", Field, 0}, + {"ParseError.Err", Field, 0}, + {"ParseError.Line", Field, 0}, + {"ParseError.StartLine", Field, 10}, + {"Reader", Type, 0}, + {"Reader.Comma", Field, 0}, + {"Reader.Comment", Field, 0}, + {"Reader.FieldsPerRecord", Field, 0}, + {"Reader.LazyQuotes", Field, 0}, + {"Reader.ReuseRecord", Field, 9}, + {"Reader.TrailingComma", Field, 0}, + {"Reader.TrimLeadingSpace", Field, 0}, + {"Writer", Type, 0}, + {"Writer.Comma", Field, 0}, + {"Writer.UseCRLF", Field, 0}, + }, + "encoding/gob": { + {"(*Decoder).Decode", Method, 0}, + {"(*Decoder).DecodeValue", Method, 0}, + {"(*Encoder).Encode", Method, 0}, + {"(*Encoder).EncodeValue", Method, 0}, + {"CommonType", Type, 0}, + {"CommonType.Id", Field, 0}, + {"CommonType.Name", Field, 0}, + {"Decoder", Type, 0}, + {"Encoder", Type, 0}, + {"GobDecoder", Type, 0}, + {"GobEncoder", Type, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"Register", Func, 0}, + {"RegisterName", Func, 0}, + }, + "encoding/hex": { + {"(InvalidByteError).Error", Method, 0}, + {"AppendDecode", Func, 22}, + {"AppendEncode", Func, 22}, + {"Decode", Func, 0}, + {"DecodeString", Func, 0}, + {"DecodedLen", Func, 0}, + {"Dump", Func, 0}, + {"Dumper", Func, 0}, + {"Encode", Func, 0}, + {"EncodeToString", Func, 0}, + {"EncodedLen", Func, 0}, + {"ErrLength", Var, 0}, + {"InvalidByteError", Type, 0}, + {"NewDecoder", Func, 10}, + {"NewEncoder", Func, 10}, + }, + "encoding/json": { + {"(*Decoder).Buffered", Method, 1}, + {"(*Decoder).Decode", Method, 0}, + {"(*Decoder).DisallowUnknownFields", Method, 10}, + {"(*Decoder).InputOffset", Method, 14}, + {"(*Decoder).More", Method, 5}, + {"(*Decoder).Token", Method, 5}, + {"(*Decoder).UseNumber", Method, 1}, + {"(*Encoder).Encode", Method, 0}, + {"(*Encoder).SetEscapeHTML", Method, 7}, + {"(*Encoder).SetIndent", Method, 7}, + {"(*InvalidUTF8Error).Error", Method, 0}, + {"(*InvalidUnmarshalError).Error", Method, 0}, + {"(*MarshalerError).Error", Method, 0}, + {"(*MarshalerError).Unwrap", Method, 13}, + {"(*RawMessage).MarshalJSON", Method, 0}, + {"(*RawMessage).UnmarshalJSON", Method, 0}, + {"(*SyntaxError).Error", Method, 0}, + {"(*UnmarshalFieldError).Error", Method, 0}, + {"(*UnmarshalTypeError).Error", Method, 0}, + {"(*UnsupportedTypeError).Error", Method, 0}, + {"(*UnsupportedValueError).Error", Method, 0}, + {"(Delim).String", Method, 5}, + {"(Number).Float64", Method, 1}, + {"(Number).Int64", Method, 1}, + {"(Number).String", Method, 1}, + {"(RawMessage).MarshalJSON", Method, 8}, + {"Compact", Func, 0}, + {"Decoder", Type, 0}, + {"Delim", Type, 5}, + {"Encoder", Type, 0}, + {"HTMLEscape", Func, 0}, + {"Indent", Func, 0}, + {"InvalidUTF8Error", Type, 0}, + {"InvalidUTF8Error.S", Field, 0}, + {"InvalidUnmarshalError", Type, 0}, + {"InvalidUnmarshalError.Type", Field, 0}, + {"Marshal", Func, 0}, + {"MarshalIndent", Func, 0}, + {"Marshaler", Type, 0}, + {"MarshalerError", Type, 0}, + {"MarshalerError.Err", Field, 0}, + {"MarshalerError.Type", Field, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"Number", Type, 1}, + {"RawMessage", Type, 0}, + {"SyntaxError", Type, 0}, + {"SyntaxError.Offset", Field, 0}, + {"Token", Type, 5}, + {"Unmarshal", Func, 0}, + {"UnmarshalFieldError", Type, 0}, + {"UnmarshalFieldError.Field", Field, 0}, + {"UnmarshalFieldError.Key", Field, 0}, + {"UnmarshalFieldError.Type", Field, 0}, + {"UnmarshalTypeError", Type, 0}, + {"UnmarshalTypeError.Field", Field, 8}, + {"UnmarshalTypeError.Offset", Field, 5}, + {"UnmarshalTypeError.Struct", Field, 8}, + {"UnmarshalTypeError.Type", Field, 0}, + {"UnmarshalTypeError.Value", Field, 0}, + {"Unmarshaler", Type, 0}, + {"UnsupportedTypeError", Type, 0}, + {"UnsupportedTypeError.Type", Field, 0}, + {"UnsupportedValueError", Type, 0}, + {"UnsupportedValueError.Str", Field, 0}, + {"UnsupportedValueError.Value", Field, 0}, + {"Valid", Func, 9}, + }, + "encoding/pem": { + {"Block", Type, 0}, + {"Block.Bytes", Field, 0}, + {"Block.Headers", Field, 0}, + {"Block.Type", Field, 0}, + {"Decode", Func, 0}, + {"Encode", Func, 0}, + {"EncodeToMemory", Func, 0}, + }, + "encoding/xml": { + {"(*Decoder).Decode", Method, 0}, + {"(*Decoder).DecodeElement", Method, 0}, + {"(*Decoder).InputOffset", Method, 4}, + {"(*Decoder).InputPos", Method, 19}, + {"(*Decoder).RawToken", Method, 0}, + {"(*Decoder).Skip", Method, 0}, + {"(*Decoder).Token", Method, 0}, + {"(*Encoder).Close", Method, 20}, + {"(*Encoder).Encode", Method, 0}, + {"(*Encoder).EncodeElement", Method, 2}, + {"(*Encoder).EncodeToken", Method, 2}, + {"(*Encoder).Flush", Method, 2}, + {"(*Encoder).Indent", Method, 1}, + {"(*SyntaxError).Error", Method, 0}, + {"(*TagPathError).Error", Method, 0}, + {"(*UnsupportedTypeError).Error", Method, 0}, + {"(CharData).Copy", Method, 0}, + {"(Comment).Copy", Method, 0}, + {"(Directive).Copy", Method, 0}, + {"(ProcInst).Copy", Method, 0}, + {"(StartElement).Copy", Method, 0}, + {"(StartElement).End", Method, 2}, + {"(UnmarshalError).Error", Method, 0}, + {"Attr", Type, 0}, + {"Attr.Name", Field, 0}, + {"Attr.Value", Field, 0}, + {"CharData", Type, 0}, + {"Comment", Type, 0}, + {"CopyToken", Func, 0}, + {"Decoder", Type, 0}, + {"Decoder.AutoClose", Field, 0}, + {"Decoder.CharsetReader", Field, 0}, + {"Decoder.DefaultSpace", Field, 1}, + {"Decoder.Entity", Field, 0}, + {"Decoder.Strict", Field, 0}, + {"Directive", Type, 0}, + {"Encoder", Type, 0}, + {"EndElement", Type, 0}, + {"EndElement.Name", Field, 0}, + {"Escape", Func, 0}, + {"EscapeText", Func, 1}, + {"HTMLAutoClose", Var, 0}, + {"HTMLEntity", Var, 0}, + {"Header", Const, 0}, + {"Marshal", Func, 0}, + {"MarshalIndent", Func, 0}, + {"Marshaler", Type, 2}, + {"MarshalerAttr", Type, 2}, + {"Name", Type, 0}, + {"Name.Local", Field, 0}, + {"Name.Space", Field, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"NewTokenDecoder", Func, 10}, + {"ProcInst", Type, 0}, + {"ProcInst.Inst", Field, 0}, + {"ProcInst.Target", Field, 0}, + {"StartElement", Type, 0}, + {"StartElement.Attr", Field, 0}, + {"StartElement.Name", Field, 0}, + {"SyntaxError", Type, 0}, + {"SyntaxError.Line", Field, 0}, + {"SyntaxError.Msg", Field, 0}, + {"TagPathError", Type, 0}, + {"TagPathError.Field1", Field, 0}, + {"TagPathError.Field2", Field, 0}, + {"TagPathError.Struct", Field, 0}, + {"TagPathError.Tag1", Field, 0}, + {"TagPathError.Tag2", Field, 0}, + {"Token", Type, 0}, + {"TokenReader", Type, 10}, + {"Unmarshal", Func, 0}, + {"UnmarshalError", Type, 0}, + {"Unmarshaler", Type, 2}, + {"UnmarshalerAttr", Type, 2}, + {"UnsupportedTypeError", Type, 0}, + {"UnsupportedTypeError.Type", Field, 0}, + }, + "errors": { + {"As", Func, 13}, + {"ErrUnsupported", Var, 21}, + {"Is", Func, 13}, + {"Join", Func, 20}, + {"New", Func, 0}, + {"Unwrap", Func, 13}, + }, + "expvar": { + {"(*Float).Add", Method, 0}, + {"(*Float).Set", Method, 0}, + {"(*Float).String", Method, 0}, + {"(*Float).Value", Method, 8}, + {"(*Int).Add", Method, 0}, + {"(*Int).Set", Method, 0}, + {"(*Int).String", Method, 0}, + {"(*Int).Value", Method, 8}, + {"(*Map).Add", Method, 0}, + {"(*Map).AddFloat", Method, 0}, + {"(*Map).Delete", Method, 12}, + {"(*Map).Do", Method, 0}, + {"(*Map).Get", Method, 0}, + {"(*Map).Init", Method, 0}, + {"(*Map).Set", Method, 0}, + {"(*Map).String", Method, 0}, + {"(*String).Set", Method, 0}, + {"(*String).String", Method, 0}, + {"(*String).Value", Method, 8}, + {"(Func).String", Method, 0}, + {"(Func).Value", Method, 8}, + {"Do", Func, 0}, + {"Float", Type, 0}, + {"Func", Type, 0}, + {"Get", Func, 0}, + {"Handler", Func, 8}, + {"Int", Type, 0}, + {"KeyValue", Type, 0}, + {"KeyValue.Key", Field, 0}, + {"KeyValue.Value", Field, 0}, + {"Map", Type, 0}, + {"NewFloat", Func, 0}, + {"NewInt", Func, 0}, + {"NewMap", Func, 0}, + {"NewString", Func, 0}, + {"Publish", Func, 0}, + {"String", Type, 0}, + {"Var", Type, 0}, + }, + "flag": { + {"(*FlagSet).Arg", Method, 0}, + {"(*FlagSet).Args", Method, 0}, + {"(*FlagSet).Bool", Method, 0}, + {"(*FlagSet).BoolFunc", Method, 21}, + {"(*FlagSet).BoolVar", Method, 0}, + {"(*FlagSet).Duration", Method, 0}, + {"(*FlagSet).DurationVar", Method, 0}, + {"(*FlagSet).ErrorHandling", Method, 10}, + {"(*FlagSet).Float64", Method, 0}, + {"(*FlagSet).Float64Var", Method, 0}, + {"(*FlagSet).Func", Method, 16}, + {"(*FlagSet).Init", Method, 0}, + {"(*FlagSet).Int", Method, 0}, + {"(*FlagSet).Int64", Method, 0}, + {"(*FlagSet).Int64Var", Method, 0}, + {"(*FlagSet).IntVar", Method, 0}, + {"(*FlagSet).Lookup", Method, 0}, + {"(*FlagSet).NArg", Method, 0}, + {"(*FlagSet).NFlag", Method, 0}, + {"(*FlagSet).Name", Method, 10}, + {"(*FlagSet).Output", Method, 10}, + {"(*FlagSet).Parse", Method, 0}, + {"(*FlagSet).Parsed", Method, 0}, + {"(*FlagSet).PrintDefaults", Method, 0}, + {"(*FlagSet).Set", Method, 0}, + {"(*FlagSet).SetOutput", Method, 0}, + {"(*FlagSet).String", Method, 0}, + {"(*FlagSet).StringVar", Method, 0}, + {"(*FlagSet).TextVar", Method, 19}, + {"(*FlagSet).Uint", Method, 0}, + {"(*FlagSet).Uint64", Method, 0}, + {"(*FlagSet).Uint64Var", Method, 0}, + {"(*FlagSet).UintVar", Method, 0}, + {"(*FlagSet).Var", Method, 0}, + {"(*FlagSet).Visit", Method, 0}, + {"(*FlagSet).VisitAll", Method, 0}, + {"Arg", Func, 0}, + {"Args", Func, 0}, + {"Bool", Func, 0}, + {"BoolFunc", Func, 21}, + {"BoolVar", Func, 0}, + {"CommandLine", Var, 2}, + {"ContinueOnError", Const, 0}, + {"Duration", Func, 0}, + {"DurationVar", Func, 0}, + {"ErrHelp", Var, 0}, + {"ErrorHandling", Type, 0}, + {"ExitOnError", Const, 0}, + {"Flag", Type, 0}, + {"Flag.DefValue", Field, 0}, + {"Flag.Name", Field, 0}, + {"Flag.Usage", Field, 0}, + {"Flag.Value", Field, 0}, + {"FlagSet", Type, 0}, + {"FlagSet.Usage", Field, 0}, + {"Float64", Func, 0}, + {"Float64Var", Func, 0}, + {"Func", Func, 16}, + {"Getter", Type, 2}, + {"Int", Func, 0}, + {"Int64", Func, 0}, + {"Int64Var", Func, 0}, + {"IntVar", Func, 0}, + {"Lookup", Func, 0}, + {"NArg", Func, 0}, + {"NFlag", Func, 0}, + {"NewFlagSet", Func, 0}, + {"PanicOnError", Const, 0}, + {"Parse", Func, 0}, + {"Parsed", Func, 0}, + {"PrintDefaults", Func, 0}, + {"Set", Func, 0}, + {"String", Func, 0}, + {"StringVar", Func, 0}, + {"TextVar", Func, 19}, + {"Uint", Func, 0}, + {"Uint64", Func, 0}, + {"Uint64Var", Func, 0}, + {"UintVar", Func, 0}, + {"UnquoteUsage", Func, 5}, + {"Usage", Var, 0}, + {"Value", Type, 0}, + {"Var", Func, 0}, + {"Visit", Func, 0}, + {"VisitAll", Func, 0}, + }, + "fmt": { + {"Append", Func, 19}, + {"Appendf", Func, 19}, + {"Appendln", Func, 19}, + {"Errorf", Func, 0}, + {"FormatString", Func, 20}, + {"Formatter", Type, 0}, + {"Fprint", Func, 0}, + {"Fprintf", Func, 0}, + {"Fprintln", Func, 0}, + {"Fscan", Func, 0}, + {"Fscanf", Func, 0}, + {"Fscanln", Func, 0}, + {"GoStringer", Type, 0}, + {"Print", Func, 0}, + {"Printf", Func, 0}, + {"Println", Func, 0}, + {"Scan", Func, 0}, + {"ScanState", Type, 0}, + {"Scanf", Func, 0}, + {"Scanln", Func, 0}, + {"Scanner", Type, 0}, + {"Sprint", Func, 0}, + {"Sprintf", Func, 0}, + {"Sprintln", Func, 0}, + {"Sscan", Func, 0}, + {"Sscanf", Func, 0}, + {"Sscanln", Func, 0}, + {"State", Type, 0}, + {"Stringer", Type, 0}, + }, + "go/ast": { + {"(*ArrayType).End", Method, 0}, + {"(*ArrayType).Pos", Method, 0}, + {"(*AssignStmt).End", Method, 0}, + {"(*AssignStmt).Pos", Method, 0}, + {"(*BadDecl).End", Method, 0}, + {"(*BadDecl).Pos", Method, 0}, + {"(*BadExpr).End", Method, 0}, + {"(*BadExpr).Pos", Method, 0}, + {"(*BadStmt).End", Method, 0}, + {"(*BadStmt).Pos", Method, 0}, + {"(*BasicLit).End", Method, 0}, + {"(*BasicLit).Pos", Method, 0}, + {"(*BinaryExpr).End", Method, 0}, + {"(*BinaryExpr).Pos", Method, 0}, + {"(*BlockStmt).End", Method, 0}, + {"(*BlockStmt).Pos", Method, 0}, + {"(*BranchStmt).End", Method, 0}, + {"(*BranchStmt).Pos", Method, 0}, + {"(*CallExpr).End", Method, 0}, + {"(*CallExpr).Pos", Method, 0}, + {"(*CaseClause).End", Method, 0}, + {"(*CaseClause).Pos", Method, 0}, + {"(*ChanType).End", Method, 0}, + {"(*ChanType).Pos", Method, 0}, + {"(*CommClause).End", Method, 0}, + {"(*CommClause).Pos", Method, 0}, + {"(*Comment).End", Method, 0}, + {"(*Comment).Pos", Method, 0}, + {"(*CommentGroup).End", Method, 0}, + {"(*CommentGroup).Pos", Method, 0}, + {"(*CommentGroup).Text", Method, 0}, + {"(*CompositeLit).End", Method, 0}, + {"(*CompositeLit).Pos", Method, 0}, + {"(*DeclStmt).End", Method, 0}, + {"(*DeclStmt).Pos", Method, 0}, + {"(*DeferStmt).End", Method, 0}, + {"(*DeferStmt).Pos", Method, 0}, + {"(*Ellipsis).End", Method, 0}, + {"(*Ellipsis).Pos", Method, 0}, + {"(*EmptyStmt).End", Method, 0}, + {"(*EmptyStmt).Pos", Method, 0}, + {"(*ExprStmt).End", Method, 0}, + {"(*ExprStmt).Pos", Method, 0}, + {"(*Field).End", Method, 0}, + {"(*Field).Pos", Method, 0}, + {"(*FieldList).End", Method, 0}, + {"(*FieldList).NumFields", Method, 0}, + {"(*FieldList).Pos", Method, 0}, + {"(*File).End", Method, 0}, + {"(*File).Pos", Method, 0}, + {"(*ForStmt).End", Method, 0}, + {"(*ForStmt).Pos", Method, 0}, + {"(*FuncDecl).End", Method, 0}, + {"(*FuncDecl).Pos", Method, 0}, + {"(*FuncLit).End", Method, 0}, + {"(*FuncLit).Pos", Method, 0}, + {"(*FuncType).End", Method, 0}, + {"(*FuncType).Pos", Method, 0}, + {"(*GenDecl).End", Method, 0}, + {"(*GenDecl).Pos", Method, 0}, + {"(*GoStmt).End", Method, 0}, + {"(*GoStmt).Pos", Method, 0}, + {"(*Ident).End", Method, 0}, + {"(*Ident).IsExported", Method, 0}, + {"(*Ident).Pos", Method, 0}, + {"(*Ident).String", Method, 0}, + {"(*IfStmt).End", Method, 0}, + {"(*IfStmt).Pos", Method, 0}, + {"(*ImportSpec).End", Method, 0}, + {"(*ImportSpec).Pos", Method, 0}, + {"(*IncDecStmt).End", Method, 0}, + {"(*IncDecStmt).Pos", Method, 0}, + {"(*IndexExpr).End", Method, 0}, + {"(*IndexExpr).Pos", Method, 0}, + {"(*IndexListExpr).End", Method, 18}, + {"(*IndexListExpr).Pos", Method, 18}, + {"(*InterfaceType).End", Method, 0}, + {"(*InterfaceType).Pos", Method, 0}, + {"(*KeyValueExpr).End", Method, 0}, + {"(*KeyValueExpr).Pos", Method, 0}, + {"(*LabeledStmt).End", Method, 0}, + {"(*LabeledStmt).Pos", Method, 0}, + {"(*MapType).End", Method, 0}, + {"(*MapType).Pos", Method, 0}, + {"(*Object).Pos", Method, 0}, + {"(*Package).End", Method, 0}, + {"(*Package).Pos", Method, 0}, + {"(*ParenExpr).End", Method, 0}, + {"(*ParenExpr).Pos", Method, 0}, + {"(*RangeStmt).End", Method, 0}, + {"(*RangeStmt).Pos", Method, 0}, + {"(*ReturnStmt).End", Method, 0}, + {"(*ReturnStmt).Pos", Method, 0}, + {"(*Scope).Insert", Method, 0}, + {"(*Scope).Lookup", Method, 0}, + {"(*Scope).String", Method, 0}, + {"(*SelectStmt).End", Method, 0}, + {"(*SelectStmt).Pos", Method, 0}, + {"(*SelectorExpr).End", Method, 0}, + {"(*SelectorExpr).Pos", Method, 0}, + {"(*SendStmt).End", Method, 0}, + {"(*SendStmt).Pos", Method, 0}, + {"(*SliceExpr).End", Method, 0}, + {"(*SliceExpr).Pos", Method, 0}, + {"(*StarExpr).End", Method, 0}, + {"(*StarExpr).Pos", Method, 0}, + {"(*StructType).End", Method, 0}, + {"(*StructType).Pos", Method, 0}, + {"(*SwitchStmt).End", Method, 0}, + {"(*SwitchStmt).Pos", Method, 0}, + {"(*TypeAssertExpr).End", Method, 0}, + {"(*TypeAssertExpr).Pos", Method, 0}, + {"(*TypeSpec).End", Method, 0}, + {"(*TypeSpec).Pos", Method, 0}, + {"(*TypeSwitchStmt).End", Method, 0}, + {"(*TypeSwitchStmt).Pos", Method, 0}, + {"(*UnaryExpr).End", Method, 0}, + {"(*UnaryExpr).Pos", Method, 0}, + {"(*ValueSpec).End", Method, 0}, + {"(*ValueSpec).Pos", Method, 0}, + {"(CommentMap).Comments", Method, 1}, + {"(CommentMap).Filter", Method, 1}, + {"(CommentMap).String", Method, 1}, + {"(CommentMap).Update", Method, 1}, + {"(ObjKind).String", Method, 0}, + {"ArrayType", Type, 0}, + {"ArrayType.Elt", Field, 0}, + {"ArrayType.Lbrack", Field, 0}, + {"ArrayType.Len", Field, 0}, + {"AssignStmt", Type, 0}, + {"AssignStmt.Lhs", Field, 0}, + {"AssignStmt.Rhs", Field, 0}, + {"AssignStmt.Tok", Field, 0}, + {"AssignStmt.TokPos", Field, 0}, + {"Bad", Const, 0}, + {"BadDecl", Type, 0}, + {"BadDecl.From", Field, 0}, + {"BadDecl.To", Field, 0}, + {"BadExpr", Type, 0}, + {"BadExpr.From", Field, 0}, + {"BadExpr.To", Field, 0}, + {"BadStmt", Type, 0}, + {"BadStmt.From", Field, 0}, + {"BadStmt.To", Field, 0}, + {"BasicLit", Type, 0}, + {"BasicLit.Kind", Field, 0}, + {"BasicLit.Value", Field, 0}, + {"BasicLit.ValuePos", Field, 0}, + {"BinaryExpr", Type, 0}, + {"BinaryExpr.Op", Field, 0}, + {"BinaryExpr.OpPos", Field, 0}, + {"BinaryExpr.X", Field, 0}, + {"BinaryExpr.Y", Field, 0}, + {"BlockStmt", Type, 0}, + {"BlockStmt.Lbrace", Field, 0}, + {"BlockStmt.List", Field, 0}, + {"BlockStmt.Rbrace", Field, 0}, + {"BranchStmt", Type, 0}, + {"BranchStmt.Label", Field, 0}, + {"BranchStmt.Tok", Field, 0}, + {"BranchStmt.TokPos", Field, 0}, + {"CallExpr", Type, 0}, + {"CallExpr.Args", Field, 0}, + {"CallExpr.Ellipsis", Field, 0}, + {"CallExpr.Fun", Field, 0}, + {"CallExpr.Lparen", Field, 0}, + {"CallExpr.Rparen", Field, 0}, + {"CaseClause", Type, 0}, + {"CaseClause.Body", Field, 0}, + {"CaseClause.Case", Field, 0}, + {"CaseClause.Colon", Field, 0}, + {"CaseClause.List", Field, 0}, + {"ChanDir", Type, 0}, + {"ChanType", Type, 0}, + {"ChanType.Arrow", Field, 1}, + {"ChanType.Begin", Field, 0}, + {"ChanType.Dir", Field, 0}, + {"ChanType.Value", Field, 0}, + {"CommClause", Type, 0}, + {"CommClause.Body", Field, 0}, + {"CommClause.Case", Field, 0}, + {"CommClause.Colon", Field, 0}, + {"CommClause.Comm", Field, 0}, + {"Comment", Type, 0}, + {"Comment.Slash", Field, 0}, + {"Comment.Text", Field, 0}, + {"CommentGroup", Type, 0}, + {"CommentGroup.List", Field, 0}, + {"CommentMap", Type, 1}, + {"CompositeLit", Type, 0}, + {"CompositeLit.Elts", Field, 0}, + {"CompositeLit.Incomplete", Field, 11}, + {"CompositeLit.Lbrace", Field, 0}, + {"CompositeLit.Rbrace", Field, 0}, + {"CompositeLit.Type", Field, 0}, + {"Con", Const, 0}, + {"Decl", Type, 0}, + {"DeclStmt", Type, 0}, + {"DeclStmt.Decl", Field, 0}, + {"DeferStmt", Type, 0}, + {"DeferStmt.Call", Field, 0}, + {"DeferStmt.Defer", Field, 0}, + {"Ellipsis", Type, 0}, + {"Ellipsis.Ellipsis", Field, 0}, + {"Ellipsis.Elt", Field, 0}, + {"EmptyStmt", Type, 0}, + {"EmptyStmt.Implicit", Field, 5}, + {"EmptyStmt.Semicolon", Field, 0}, + {"Expr", Type, 0}, + {"ExprStmt", Type, 0}, + {"ExprStmt.X", Field, 0}, + {"Field", Type, 0}, + {"Field.Comment", Field, 0}, + {"Field.Doc", Field, 0}, + {"Field.Names", Field, 0}, + {"Field.Tag", Field, 0}, + {"Field.Type", Field, 0}, + {"FieldFilter", Type, 0}, + {"FieldList", Type, 0}, + {"FieldList.Closing", Field, 0}, + {"FieldList.List", Field, 0}, + {"FieldList.Opening", Field, 0}, + {"File", Type, 0}, + {"File.Comments", Field, 0}, + {"File.Decls", Field, 0}, + {"File.Doc", Field, 0}, + {"File.FileEnd", Field, 20}, + {"File.FileStart", Field, 20}, + {"File.GoVersion", Field, 21}, + {"File.Imports", Field, 0}, + {"File.Name", Field, 0}, + {"File.Package", Field, 0}, + {"File.Scope", Field, 0}, + {"File.Unresolved", Field, 0}, + {"FileExports", Func, 0}, + {"Filter", Type, 0}, + {"FilterDecl", Func, 0}, + {"FilterFile", Func, 0}, + {"FilterFuncDuplicates", Const, 0}, + {"FilterImportDuplicates", Const, 0}, + {"FilterPackage", Func, 0}, + {"FilterUnassociatedComments", Const, 0}, + {"ForStmt", Type, 0}, + {"ForStmt.Body", Field, 0}, + {"ForStmt.Cond", Field, 0}, + {"ForStmt.For", Field, 0}, + {"ForStmt.Init", Field, 0}, + {"ForStmt.Post", Field, 0}, + {"Fprint", Func, 0}, + {"Fun", Const, 0}, + {"FuncDecl", Type, 0}, + {"FuncDecl.Body", Field, 0}, + {"FuncDecl.Doc", Field, 0}, + {"FuncDecl.Name", Field, 0}, + {"FuncDecl.Recv", Field, 0}, + {"FuncDecl.Type", Field, 0}, + {"FuncLit", Type, 0}, + {"FuncLit.Body", Field, 0}, + {"FuncLit.Type", Field, 0}, + {"FuncType", Type, 0}, + {"FuncType.Func", Field, 0}, + {"FuncType.Params", Field, 0}, + {"FuncType.Results", Field, 0}, + {"FuncType.TypeParams", Field, 18}, + {"GenDecl", Type, 0}, + {"GenDecl.Doc", Field, 0}, + {"GenDecl.Lparen", Field, 0}, + {"GenDecl.Rparen", Field, 0}, + {"GenDecl.Specs", Field, 0}, + {"GenDecl.Tok", Field, 0}, + {"GenDecl.TokPos", Field, 0}, + {"GoStmt", Type, 0}, + {"GoStmt.Call", Field, 0}, + {"GoStmt.Go", Field, 0}, + {"Ident", Type, 0}, + {"Ident.Name", Field, 0}, + {"Ident.NamePos", Field, 0}, + {"Ident.Obj", Field, 0}, + {"IfStmt", Type, 0}, + {"IfStmt.Body", Field, 0}, + {"IfStmt.Cond", Field, 0}, + {"IfStmt.Else", Field, 0}, + {"IfStmt.If", Field, 0}, + {"IfStmt.Init", Field, 0}, + {"ImportSpec", Type, 0}, + {"ImportSpec.Comment", Field, 0}, + {"ImportSpec.Doc", Field, 0}, + {"ImportSpec.EndPos", Field, 0}, + {"ImportSpec.Name", Field, 0}, + {"ImportSpec.Path", Field, 0}, + {"Importer", Type, 0}, + {"IncDecStmt", Type, 0}, + {"IncDecStmt.Tok", Field, 0}, + {"IncDecStmt.TokPos", Field, 0}, + {"IncDecStmt.X", Field, 0}, + {"IndexExpr", Type, 0}, + {"IndexExpr.Index", Field, 0}, + {"IndexExpr.Lbrack", Field, 0}, + {"IndexExpr.Rbrack", Field, 0}, + {"IndexExpr.X", Field, 0}, + {"IndexListExpr", Type, 18}, + {"IndexListExpr.Indices", Field, 18}, + {"IndexListExpr.Lbrack", Field, 18}, + {"IndexListExpr.Rbrack", Field, 18}, + {"IndexListExpr.X", Field, 18}, + {"Inspect", Func, 0}, + {"InterfaceType", Type, 0}, + {"InterfaceType.Incomplete", Field, 0}, + {"InterfaceType.Interface", Field, 0}, + {"InterfaceType.Methods", Field, 0}, + {"IsExported", Func, 0}, + {"IsGenerated", Func, 21}, + {"KeyValueExpr", Type, 0}, + {"KeyValueExpr.Colon", Field, 0}, + {"KeyValueExpr.Key", Field, 0}, + {"KeyValueExpr.Value", Field, 0}, + {"LabeledStmt", Type, 0}, + {"LabeledStmt.Colon", Field, 0}, + {"LabeledStmt.Label", Field, 0}, + {"LabeledStmt.Stmt", Field, 0}, + {"Lbl", Const, 0}, + {"MapType", Type, 0}, + {"MapType.Key", Field, 0}, + {"MapType.Map", Field, 0}, + {"MapType.Value", Field, 0}, + {"MergeMode", Type, 0}, + {"MergePackageFiles", Func, 0}, + {"NewCommentMap", Func, 1}, + {"NewIdent", Func, 0}, + {"NewObj", Func, 0}, + {"NewPackage", Func, 0}, + {"NewScope", Func, 0}, + {"Node", Type, 0}, + {"NotNilFilter", Func, 0}, + {"ObjKind", Type, 0}, + {"Object", Type, 0}, + {"Object.Data", Field, 0}, + {"Object.Decl", Field, 0}, + {"Object.Kind", Field, 0}, + {"Object.Name", Field, 0}, + {"Object.Type", Field, 0}, + {"Package", Type, 0}, + {"Package.Files", Field, 0}, + {"Package.Imports", Field, 0}, + {"Package.Name", Field, 0}, + {"Package.Scope", Field, 0}, + {"PackageExports", Func, 0}, + {"ParenExpr", Type, 0}, + {"ParenExpr.Lparen", Field, 0}, + {"ParenExpr.Rparen", Field, 0}, + {"ParenExpr.X", Field, 0}, + {"Pkg", Const, 0}, + {"Preorder", Func, 23}, + {"Print", Func, 0}, + {"RECV", Const, 0}, + {"RangeStmt", Type, 0}, + {"RangeStmt.Body", Field, 0}, + {"RangeStmt.For", Field, 0}, + {"RangeStmt.Key", Field, 0}, + {"RangeStmt.Range", Field, 20}, + {"RangeStmt.Tok", Field, 0}, + {"RangeStmt.TokPos", Field, 0}, + {"RangeStmt.Value", Field, 0}, + {"RangeStmt.X", Field, 0}, + {"ReturnStmt", Type, 0}, + {"ReturnStmt.Results", Field, 0}, + {"ReturnStmt.Return", Field, 0}, + {"SEND", Const, 0}, + {"Scope", Type, 0}, + {"Scope.Objects", Field, 0}, + {"Scope.Outer", Field, 0}, + {"SelectStmt", Type, 0}, + {"SelectStmt.Body", Field, 0}, + {"SelectStmt.Select", Field, 0}, + {"SelectorExpr", Type, 0}, + {"SelectorExpr.Sel", Field, 0}, + {"SelectorExpr.X", Field, 0}, + {"SendStmt", Type, 0}, + {"SendStmt.Arrow", Field, 0}, + {"SendStmt.Chan", Field, 0}, + {"SendStmt.Value", Field, 0}, + {"SliceExpr", Type, 0}, + {"SliceExpr.High", Field, 0}, + {"SliceExpr.Lbrack", Field, 0}, + {"SliceExpr.Low", Field, 0}, + {"SliceExpr.Max", Field, 2}, + {"SliceExpr.Rbrack", Field, 0}, + {"SliceExpr.Slice3", Field, 2}, + {"SliceExpr.X", Field, 0}, + {"SortImports", Func, 0}, + {"Spec", Type, 0}, + {"StarExpr", Type, 0}, + {"StarExpr.Star", Field, 0}, + {"StarExpr.X", Field, 0}, + {"Stmt", Type, 0}, + {"StructType", Type, 0}, + {"StructType.Fields", Field, 0}, + {"StructType.Incomplete", Field, 0}, + {"StructType.Struct", Field, 0}, + {"SwitchStmt", Type, 0}, + {"SwitchStmt.Body", Field, 0}, + {"SwitchStmt.Init", Field, 0}, + {"SwitchStmt.Switch", Field, 0}, + {"SwitchStmt.Tag", Field, 0}, + {"Typ", Const, 0}, + {"TypeAssertExpr", Type, 0}, + {"TypeAssertExpr.Lparen", Field, 2}, + {"TypeAssertExpr.Rparen", Field, 2}, + {"TypeAssertExpr.Type", Field, 0}, + {"TypeAssertExpr.X", Field, 0}, + {"TypeSpec", Type, 0}, + {"TypeSpec.Assign", Field, 9}, + {"TypeSpec.Comment", Field, 0}, + {"TypeSpec.Doc", Field, 0}, + {"TypeSpec.Name", Field, 0}, + {"TypeSpec.Type", Field, 0}, + {"TypeSpec.TypeParams", Field, 18}, + {"TypeSwitchStmt", Type, 0}, + {"TypeSwitchStmt.Assign", Field, 0}, + {"TypeSwitchStmt.Body", Field, 0}, + {"TypeSwitchStmt.Init", Field, 0}, + {"TypeSwitchStmt.Switch", Field, 0}, + {"UnaryExpr", Type, 0}, + {"UnaryExpr.Op", Field, 0}, + {"UnaryExpr.OpPos", Field, 0}, + {"UnaryExpr.X", Field, 0}, + {"Unparen", Func, 22}, + {"ValueSpec", Type, 0}, + {"ValueSpec.Comment", Field, 0}, + {"ValueSpec.Doc", Field, 0}, + {"ValueSpec.Names", Field, 0}, + {"ValueSpec.Type", Field, 0}, + {"ValueSpec.Values", Field, 0}, + {"Var", Const, 0}, + {"Visitor", Type, 0}, + {"Walk", Func, 0}, + }, + "go/build": { + {"(*Context).Import", Method, 0}, + {"(*Context).ImportDir", Method, 0}, + {"(*Context).MatchFile", Method, 2}, + {"(*Context).SrcDirs", Method, 0}, + {"(*MultiplePackageError).Error", Method, 4}, + {"(*NoGoError).Error", Method, 0}, + {"(*Package).IsCommand", Method, 0}, + {"AllowBinary", Const, 0}, + {"ArchChar", Func, 0}, + {"Context", Type, 0}, + {"Context.BuildTags", Field, 0}, + {"Context.CgoEnabled", Field, 0}, + {"Context.Compiler", Field, 0}, + {"Context.Dir", Field, 14}, + {"Context.GOARCH", Field, 0}, + {"Context.GOOS", Field, 0}, + {"Context.GOPATH", Field, 0}, + {"Context.GOROOT", Field, 0}, + {"Context.HasSubdir", Field, 0}, + {"Context.InstallSuffix", Field, 1}, + {"Context.IsAbsPath", Field, 0}, + {"Context.IsDir", Field, 0}, + {"Context.JoinPath", Field, 0}, + {"Context.OpenFile", Field, 0}, + {"Context.ReadDir", Field, 0}, + {"Context.ReleaseTags", Field, 1}, + {"Context.SplitPathList", Field, 0}, + {"Context.ToolTags", Field, 17}, + {"Context.UseAllFiles", Field, 0}, + {"Default", Var, 0}, + {"Directive", Type, 21}, + {"Directive.Pos", Field, 21}, + {"Directive.Text", Field, 21}, + {"FindOnly", Const, 0}, + {"IgnoreVendor", Const, 6}, + {"Import", Func, 0}, + {"ImportComment", Const, 4}, + {"ImportDir", Func, 0}, + {"ImportMode", Type, 0}, + {"IsLocalImport", Func, 0}, + {"MultiplePackageError", Type, 4}, + {"MultiplePackageError.Dir", Field, 4}, + {"MultiplePackageError.Files", Field, 4}, + {"MultiplePackageError.Packages", Field, 4}, + {"NoGoError", Type, 0}, + {"NoGoError.Dir", Field, 0}, + {"Package", Type, 0}, + {"Package.AllTags", Field, 2}, + {"Package.BinDir", Field, 0}, + {"Package.BinaryOnly", Field, 7}, + {"Package.CFiles", Field, 0}, + {"Package.CXXFiles", Field, 2}, + {"Package.CgoCFLAGS", Field, 0}, + {"Package.CgoCPPFLAGS", Field, 2}, + {"Package.CgoCXXFLAGS", Field, 2}, + {"Package.CgoFFLAGS", Field, 7}, + {"Package.CgoFiles", Field, 0}, + {"Package.CgoLDFLAGS", Field, 0}, + {"Package.CgoPkgConfig", Field, 0}, + {"Package.ConflictDir", Field, 2}, + {"Package.Dir", Field, 0}, + {"Package.Directives", Field, 21}, + {"Package.Doc", Field, 0}, + {"Package.EmbedPatternPos", Field, 16}, + {"Package.EmbedPatterns", Field, 16}, + {"Package.FFiles", Field, 7}, + {"Package.GoFiles", Field, 0}, + {"Package.Goroot", Field, 0}, + {"Package.HFiles", Field, 0}, + {"Package.IgnoredGoFiles", Field, 1}, + {"Package.IgnoredOtherFiles", Field, 16}, + {"Package.ImportComment", Field, 4}, + {"Package.ImportPath", Field, 0}, + {"Package.ImportPos", Field, 0}, + {"Package.Imports", Field, 0}, + {"Package.InvalidGoFiles", Field, 6}, + {"Package.MFiles", Field, 3}, + {"Package.Name", Field, 0}, + {"Package.PkgObj", Field, 0}, + {"Package.PkgRoot", Field, 0}, + {"Package.PkgTargetRoot", Field, 5}, + {"Package.Root", Field, 0}, + {"Package.SFiles", Field, 0}, + {"Package.SrcRoot", Field, 0}, + {"Package.SwigCXXFiles", Field, 1}, + {"Package.SwigFiles", Field, 1}, + {"Package.SysoFiles", Field, 0}, + {"Package.TestDirectives", Field, 21}, + {"Package.TestEmbedPatternPos", Field, 16}, + {"Package.TestEmbedPatterns", Field, 16}, + {"Package.TestGoFiles", Field, 0}, + {"Package.TestImportPos", Field, 0}, + {"Package.TestImports", Field, 0}, + {"Package.XTestDirectives", Field, 21}, + {"Package.XTestEmbedPatternPos", Field, 16}, + {"Package.XTestEmbedPatterns", Field, 16}, + {"Package.XTestGoFiles", Field, 0}, + {"Package.XTestImportPos", Field, 0}, + {"Package.XTestImports", Field, 0}, + {"ToolDir", Var, 0}, + }, + "go/build/constraint": { + {"(*AndExpr).Eval", Method, 16}, + {"(*AndExpr).String", Method, 16}, + {"(*NotExpr).Eval", Method, 16}, + {"(*NotExpr).String", Method, 16}, + {"(*OrExpr).Eval", Method, 16}, + {"(*OrExpr).String", Method, 16}, + {"(*SyntaxError).Error", Method, 16}, + {"(*TagExpr).Eval", Method, 16}, + {"(*TagExpr).String", Method, 16}, + {"AndExpr", Type, 16}, + {"AndExpr.X", Field, 16}, + {"AndExpr.Y", Field, 16}, + {"Expr", Type, 16}, + {"GoVersion", Func, 21}, + {"IsGoBuild", Func, 16}, + {"IsPlusBuild", Func, 16}, + {"NotExpr", Type, 16}, + {"NotExpr.X", Field, 16}, + {"OrExpr", Type, 16}, + {"OrExpr.X", Field, 16}, + {"OrExpr.Y", Field, 16}, + {"Parse", Func, 16}, + {"PlusBuildLines", Func, 16}, + {"SyntaxError", Type, 16}, + {"SyntaxError.Err", Field, 16}, + {"SyntaxError.Offset", Field, 16}, + {"TagExpr", Type, 16}, + {"TagExpr.Tag", Field, 16}, + }, + "go/constant": { + {"(Kind).String", Method, 18}, + {"BinaryOp", Func, 5}, + {"BitLen", Func, 5}, + {"Bool", Const, 5}, + {"BoolVal", Func, 5}, + {"Bytes", Func, 5}, + {"Compare", Func, 5}, + {"Complex", Const, 5}, + {"Denom", Func, 5}, + {"Float", Const, 5}, + {"Float32Val", Func, 5}, + {"Float64Val", Func, 5}, + {"Imag", Func, 5}, + {"Int", Const, 5}, + {"Int64Val", Func, 5}, + {"Kind", Type, 5}, + {"Make", Func, 13}, + {"MakeBool", Func, 5}, + {"MakeFloat64", Func, 5}, + {"MakeFromBytes", Func, 5}, + {"MakeFromLiteral", Func, 5}, + {"MakeImag", Func, 5}, + {"MakeInt64", Func, 5}, + {"MakeString", Func, 5}, + {"MakeUint64", Func, 5}, + {"MakeUnknown", Func, 5}, + {"Num", Func, 5}, + {"Real", Func, 5}, + {"Shift", Func, 5}, + {"Sign", Func, 5}, + {"String", Const, 5}, + {"StringVal", Func, 5}, + {"ToComplex", Func, 6}, + {"ToFloat", Func, 6}, + {"ToInt", Func, 6}, + {"Uint64Val", Func, 5}, + {"UnaryOp", Func, 5}, + {"Unknown", Const, 5}, + {"Val", Func, 13}, + {"Value", Type, 5}, + }, + "go/doc": { + {"(*Package).Filter", Method, 0}, + {"(*Package).HTML", Method, 19}, + {"(*Package).Markdown", Method, 19}, + {"(*Package).Parser", Method, 19}, + {"(*Package).Printer", Method, 19}, + {"(*Package).Synopsis", Method, 19}, + {"(*Package).Text", Method, 19}, + {"AllDecls", Const, 0}, + {"AllMethods", Const, 0}, + {"Example", Type, 0}, + {"Example.Code", Field, 0}, + {"Example.Comments", Field, 0}, + {"Example.Doc", Field, 0}, + {"Example.EmptyOutput", Field, 1}, + {"Example.Name", Field, 0}, + {"Example.Order", Field, 1}, + {"Example.Output", Field, 0}, + {"Example.Play", Field, 1}, + {"Example.Suffix", Field, 14}, + {"Example.Unordered", Field, 7}, + {"Examples", Func, 0}, + {"Filter", Type, 0}, + {"Func", Type, 0}, + {"Func.Decl", Field, 0}, + {"Func.Doc", Field, 0}, + {"Func.Examples", Field, 14}, + {"Func.Level", Field, 0}, + {"Func.Name", Field, 0}, + {"Func.Orig", Field, 0}, + {"Func.Recv", Field, 0}, + {"IllegalPrefixes", Var, 1}, + {"IsPredeclared", Func, 8}, + {"Mode", Type, 0}, + {"New", Func, 0}, + {"NewFromFiles", Func, 14}, + {"Note", Type, 1}, + {"Note.Body", Field, 1}, + {"Note.End", Field, 1}, + {"Note.Pos", Field, 1}, + {"Note.UID", Field, 1}, + {"Package", Type, 0}, + {"Package.Bugs", Field, 0}, + {"Package.Consts", Field, 0}, + {"Package.Doc", Field, 0}, + {"Package.Examples", Field, 14}, + {"Package.Filenames", Field, 0}, + {"Package.Funcs", Field, 0}, + {"Package.ImportPath", Field, 0}, + {"Package.Imports", Field, 0}, + {"Package.Name", Field, 0}, + {"Package.Notes", Field, 1}, + {"Package.Types", Field, 0}, + {"Package.Vars", Field, 0}, + {"PreserveAST", Const, 12}, + {"Synopsis", Func, 0}, + {"ToHTML", Func, 0}, + {"ToText", Func, 0}, + {"Type", Type, 0}, + {"Type.Consts", Field, 0}, + {"Type.Decl", Field, 0}, + {"Type.Doc", Field, 0}, + {"Type.Examples", Field, 14}, + {"Type.Funcs", Field, 0}, + {"Type.Methods", Field, 0}, + {"Type.Name", Field, 0}, + {"Type.Vars", Field, 0}, + {"Value", Type, 0}, + {"Value.Decl", Field, 0}, + {"Value.Doc", Field, 0}, + {"Value.Names", Field, 0}, + }, + "go/doc/comment": { + {"(*DocLink).DefaultURL", Method, 19}, + {"(*Heading).DefaultID", Method, 19}, + {"(*List).BlankBefore", Method, 19}, + {"(*List).BlankBetween", Method, 19}, + {"(*Parser).Parse", Method, 19}, + {"(*Printer).Comment", Method, 19}, + {"(*Printer).HTML", Method, 19}, + {"(*Printer).Markdown", Method, 19}, + {"(*Printer).Text", Method, 19}, + {"Block", Type, 19}, + {"Code", Type, 19}, + {"Code.Text", Field, 19}, + {"DefaultLookupPackage", Func, 19}, + {"Doc", Type, 19}, + {"Doc.Content", Field, 19}, + {"Doc.Links", Field, 19}, + {"DocLink", Type, 19}, + {"DocLink.ImportPath", Field, 19}, + {"DocLink.Name", Field, 19}, + {"DocLink.Recv", Field, 19}, + {"DocLink.Text", Field, 19}, + {"Heading", Type, 19}, + {"Heading.Text", Field, 19}, + {"Italic", Type, 19}, + {"Link", Type, 19}, + {"Link.Auto", Field, 19}, + {"Link.Text", Field, 19}, + {"Link.URL", Field, 19}, + {"LinkDef", Type, 19}, + {"LinkDef.Text", Field, 19}, + {"LinkDef.URL", Field, 19}, + {"LinkDef.Used", Field, 19}, + {"List", Type, 19}, + {"List.ForceBlankBefore", Field, 19}, + {"List.ForceBlankBetween", Field, 19}, + {"List.Items", Field, 19}, + {"ListItem", Type, 19}, + {"ListItem.Content", Field, 19}, + {"ListItem.Number", Field, 19}, + {"Paragraph", Type, 19}, + {"Paragraph.Text", Field, 19}, + {"Parser", Type, 19}, + {"Parser.LookupPackage", Field, 19}, + {"Parser.LookupSym", Field, 19}, + {"Parser.Words", Field, 19}, + {"Plain", Type, 19}, + {"Printer", Type, 19}, + {"Printer.DocLinkBaseURL", Field, 19}, + {"Printer.DocLinkURL", Field, 19}, + {"Printer.HeadingID", Field, 19}, + {"Printer.HeadingLevel", Field, 19}, + {"Printer.TextCodePrefix", Field, 19}, + {"Printer.TextPrefix", Field, 19}, + {"Printer.TextWidth", Field, 19}, + {"Text", Type, 19}, + }, + "go/format": { + {"Node", Func, 1}, + {"Source", Func, 1}, + }, + "go/importer": { + {"Default", Func, 5}, + {"For", Func, 5}, + {"ForCompiler", Func, 12}, + {"Lookup", Type, 5}, + }, + "go/parser": { + {"AllErrors", Const, 1}, + {"DeclarationErrors", Const, 0}, + {"ImportsOnly", Const, 0}, + {"Mode", Type, 0}, + {"PackageClauseOnly", Const, 0}, + {"ParseComments", Const, 0}, + {"ParseDir", Func, 0}, + {"ParseExpr", Func, 0}, + {"ParseExprFrom", Func, 5}, + {"ParseFile", Func, 0}, + {"SkipObjectResolution", Const, 17}, + {"SpuriousErrors", Const, 0}, + {"Trace", Const, 0}, + }, + "go/printer": { + {"(*Config).Fprint", Method, 0}, + {"CommentedNode", Type, 0}, + {"CommentedNode.Comments", Field, 0}, + {"CommentedNode.Node", Field, 0}, + {"Config", Type, 0}, + {"Config.Indent", Field, 1}, + {"Config.Mode", Field, 0}, + {"Config.Tabwidth", Field, 0}, + {"Fprint", Func, 0}, + {"Mode", Type, 0}, + {"RawFormat", Const, 0}, + {"SourcePos", Const, 0}, + {"TabIndent", Const, 0}, + {"UseSpaces", Const, 0}, + }, + "go/scanner": { + {"(*ErrorList).Add", Method, 0}, + {"(*ErrorList).RemoveMultiples", Method, 0}, + {"(*ErrorList).Reset", Method, 0}, + {"(*Scanner).Init", Method, 0}, + {"(*Scanner).Scan", Method, 0}, + {"(Error).Error", Method, 0}, + {"(ErrorList).Err", Method, 0}, + {"(ErrorList).Error", Method, 0}, + {"(ErrorList).Len", Method, 0}, + {"(ErrorList).Less", Method, 0}, + {"(ErrorList).Sort", Method, 0}, + {"(ErrorList).Swap", Method, 0}, + {"Error", Type, 0}, + {"Error.Msg", Field, 0}, + {"Error.Pos", Field, 0}, + {"ErrorHandler", Type, 0}, + {"ErrorList", Type, 0}, + {"Mode", Type, 0}, + {"PrintError", Func, 0}, + {"ScanComments", Const, 0}, + {"Scanner", Type, 0}, + {"Scanner.ErrorCount", Field, 0}, + }, + "go/token": { + {"(*File).AddLine", Method, 0}, + {"(*File).AddLineColumnInfo", Method, 11}, + {"(*File).AddLineInfo", Method, 0}, + {"(*File).Base", Method, 0}, + {"(*File).Line", Method, 0}, + {"(*File).LineCount", Method, 0}, + {"(*File).LineStart", Method, 12}, + {"(*File).Lines", Method, 21}, + {"(*File).MergeLine", Method, 2}, + {"(*File).Name", Method, 0}, + {"(*File).Offset", Method, 0}, + {"(*File).Pos", Method, 0}, + {"(*File).Position", Method, 0}, + {"(*File).PositionFor", Method, 4}, + {"(*File).SetLines", Method, 0}, + {"(*File).SetLinesForContent", Method, 0}, + {"(*File).Size", Method, 0}, + {"(*FileSet).AddFile", Method, 0}, + {"(*FileSet).Base", Method, 0}, + {"(*FileSet).File", Method, 0}, + {"(*FileSet).Iterate", Method, 0}, + {"(*FileSet).Position", Method, 0}, + {"(*FileSet).PositionFor", Method, 4}, + {"(*FileSet).Read", Method, 0}, + {"(*FileSet).RemoveFile", Method, 20}, + {"(*FileSet).Write", Method, 0}, + {"(*Position).IsValid", Method, 0}, + {"(Pos).IsValid", Method, 0}, + {"(Position).String", Method, 0}, + {"(Token).IsKeyword", Method, 0}, + {"(Token).IsLiteral", Method, 0}, + {"(Token).IsOperator", Method, 0}, + {"(Token).Precedence", Method, 0}, + {"(Token).String", Method, 0}, + {"ADD", Const, 0}, + {"ADD_ASSIGN", Const, 0}, + {"AND", Const, 0}, + {"AND_ASSIGN", Const, 0}, + {"AND_NOT", Const, 0}, + {"AND_NOT_ASSIGN", Const, 0}, + {"ARROW", Const, 0}, + {"ASSIGN", Const, 0}, + {"BREAK", Const, 0}, + {"CASE", Const, 0}, + {"CHAN", Const, 0}, + {"CHAR", Const, 0}, + {"COLON", Const, 0}, + {"COMMA", Const, 0}, + {"COMMENT", Const, 0}, + {"CONST", Const, 0}, + {"CONTINUE", Const, 0}, + {"DEC", Const, 0}, + {"DEFAULT", Const, 0}, + {"DEFER", Const, 0}, + {"DEFINE", Const, 0}, + {"ELLIPSIS", Const, 0}, + {"ELSE", Const, 0}, + {"EOF", Const, 0}, + {"EQL", Const, 0}, + {"FALLTHROUGH", Const, 0}, + {"FLOAT", Const, 0}, + {"FOR", Const, 0}, + {"FUNC", Const, 0}, + {"File", Type, 0}, + {"FileSet", Type, 0}, + {"GEQ", Const, 0}, + {"GO", Const, 0}, + {"GOTO", Const, 0}, + {"GTR", Const, 0}, + {"HighestPrec", Const, 0}, + {"IDENT", Const, 0}, + {"IF", Const, 0}, + {"ILLEGAL", Const, 0}, + {"IMAG", Const, 0}, + {"IMPORT", Const, 0}, + {"INC", Const, 0}, + {"INT", Const, 0}, + {"INTERFACE", Const, 0}, + {"IsExported", Func, 13}, + {"IsIdentifier", Func, 13}, + {"IsKeyword", Func, 13}, + {"LAND", Const, 0}, + {"LBRACE", Const, 0}, + {"LBRACK", Const, 0}, + {"LEQ", Const, 0}, + {"LOR", Const, 0}, + {"LPAREN", Const, 0}, + {"LSS", Const, 0}, + {"Lookup", Func, 0}, + {"LowestPrec", Const, 0}, + {"MAP", Const, 0}, + {"MUL", Const, 0}, + {"MUL_ASSIGN", Const, 0}, + {"NEQ", Const, 0}, + {"NOT", Const, 0}, + {"NewFileSet", Func, 0}, + {"NoPos", Const, 0}, + {"OR", Const, 0}, + {"OR_ASSIGN", Const, 0}, + {"PACKAGE", Const, 0}, + {"PERIOD", Const, 0}, + {"Pos", Type, 0}, + {"Position", Type, 0}, + {"Position.Column", Field, 0}, + {"Position.Filename", Field, 0}, + {"Position.Line", Field, 0}, + {"Position.Offset", Field, 0}, + {"QUO", Const, 0}, + {"QUO_ASSIGN", Const, 0}, + {"RANGE", Const, 0}, + {"RBRACE", Const, 0}, + {"RBRACK", Const, 0}, + {"REM", Const, 0}, + {"REM_ASSIGN", Const, 0}, + {"RETURN", Const, 0}, + {"RPAREN", Const, 0}, + {"SELECT", Const, 0}, + {"SEMICOLON", Const, 0}, + {"SHL", Const, 0}, + {"SHL_ASSIGN", Const, 0}, + {"SHR", Const, 0}, + {"SHR_ASSIGN", Const, 0}, + {"STRING", Const, 0}, + {"STRUCT", Const, 0}, + {"SUB", Const, 0}, + {"SUB_ASSIGN", Const, 0}, + {"SWITCH", Const, 0}, + {"TILDE", Const, 18}, + {"TYPE", Const, 0}, + {"Token", Type, 0}, + {"UnaryPrec", Const, 0}, + {"VAR", Const, 0}, + {"XOR", Const, 0}, + {"XOR_ASSIGN", Const, 0}, + }, + "go/types": { + {"(*Alias).Obj", Method, 22}, + {"(*Alias).Origin", Method, 23}, + {"(*Alias).Rhs", Method, 23}, + {"(*Alias).SetTypeParams", Method, 23}, + {"(*Alias).String", Method, 22}, + {"(*Alias).TypeArgs", Method, 23}, + {"(*Alias).TypeParams", Method, 23}, + {"(*Alias).Underlying", Method, 22}, + {"(*ArgumentError).Error", Method, 18}, + {"(*ArgumentError).Unwrap", Method, 18}, + {"(*Array).Elem", Method, 5}, + {"(*Array).Len", Method, 5}, + {"(*Array).String", Method, 5}, + {"(*Array).Underlying", Method, 5}, + {"(*Basic).Info", Method, 5}, + {"(*Basic).Kind", Method, 5}, + {"(*Basic).Name", Method, 5}, + {"(*Basic).String", Method, 5}, + {"(*Basic).Underlying", Method, 5}, + {"(*Builtin).Exported", Method, 5}, + {"(*Builtin).Id", Method, 5}, + {"(*Builtin).Name", Method, 5}, + {"(*Builtin).Parent", Method, 5}, + {"(*Builtin).Pkg", Method, 5}, + {"(*Builtin).Pos", Method, 5}, + {"(*Builtin).String", Method, 5}, + {"(*Builtin).Type", Method, 5}, + {"(*Chan).Dir", Method, 5}, + {"(*Chan).Elem", Method, 5}, + {"(*Chan).String", Method, 5}, + {"(*Chan).Underlying", Method, 5}, + {"(*Checker).Files", Method, 5}, + {"(*Config).Check", Method, 5}, + {"(*Const).Exported", Method, 5}, + {"(*Const).Id", Method, 5}, + {"(*Const).Name", Method, 5}, + {"(*Const).Parent", Method, 5}, + {"(*Const).Pkg", Method, 5}, + {"(*Const).Pos", Method, 5}, + {"(*Const).String", Method, 5}, + {"(*Const).Type", Method, 5}, + {"(*Const).Val", Method, 5}, + {"(*Func).Exported", Method, 5}, + {"(*Func).FullName", Method, 5}, + {"(*Func).Id", Method, 5}, + {"(*Func).Name", Method, 5}, + {"(*Func).Origin", Method, 19}, + {"(*Func).Parent", Method, 5}, + {"(*Func).Pkg", Method, 5}, + {"(*Func).Pos", Method, 5}, + {"(*Func).Scope", Method, 5}, + {"(*Func).Signature", Method, 23}, + {"(*Func).String", Method, 5}, + {"(*Func).Type", Method, 5}, + {"(*Info).ObjectOf", Method, 5}, + {"(*Info).PkgNameOf", Method, 22}, + {"(*Info).TypeOf", Method, 5}, + {"(*Initializer).String", Method, 5}, + {"(*Interface).Complete", Method, 5}, + {"(*Interface).Embedded", Method, 5}, + {"(*Interface).EmbeddedType", Method, 11}, + {"(*Interface).Empty", Method, 5}, + {"(*Interface).ExplicitMethod", Method, 5}, + {"(*Interface).IsComparable", Method, 18}, + {"(*Interface).IsImplicit", Method, 18}, + {"(*Interface).IsMethodSet", Method, 18}, + {"(*Interface).MarkImplicit", Method, 18}, + {"(*Interface).Method", Method, 5}, + {"(*Interface).NumEmbeddeds", Method, 5}, + {"(*Interface).NumExplicitMethods", Method, 5}, + {"(*Interface).NumMethods", Method, 5}, + {"(*Interface).String", Method, 5}, + {"(*Interface).Underlying", Method, 5}, + {"(*Label).Exported", Method, 5}, + {"(*Label).Id", Method, 5}, + {"(*Label).Name", Method, 5}, + {"(*Label).Parent", Method, 5}, + {"(*Label).Pkg", Method, 5}, + {"(*Label).Pos", Method, 5}, + {"(*Label).String", Method, 5}, + {"(*Label).Type", Method, 5}, + {"(*Map).Elem", Method, 5}, + {"(*Map).Key", Method, 5}, + {"(*Map).String", Method, 5}, + {"(*Map).Underlying", Method, 5}, + {"(*MethodSet).At", Method, 5}, + {"(*MethodSet).Len", Method, 5}, + {"(*MethodSet).Lookup", Method, 5}, + {"(*MethodSet).String", Method, 5}, + {"(*Named).AddMethod", Method, 5}, + {"(*Named).Method", Method, 5}, + {"(*Named).NumMethods", Method, 5}, + {"(*Named).Obj", Method, 5}, + {"(*Named).Origin", Method, 18}, + {"(*Named).SetTypeParams", Method, 18}, + {"(*Named).SetUnderlying", Method, 5}, + {"(*Named).String", Method, 5}, + {"(*Named).TypeArgs", Method, 18}, + {"(*Named).TypeParams", Method, 18}, + {"(*Named).Underlying", Method, 5}, + {"(*Nil).Exported", Method, 5}, + {"(*Nil).Id", Method, 5}, + {"(*Nil).Name", Method, 5}, + {"(*Nil).Parent", Method, 5}, + {"(*Nil).Pkg", Method, 5}, + {"(*Nil).Pos", Method, 5}, + {"(*Nil).String", Method, 5}, + {"(*Nil).Type", Method, 5}, + {"(*Package).Complete", Method, 5}, + {"(*Package).GoVersion", Method, 21}, + {"(*Package).Imports", Method, 5}, + {"(*Package).MarkComplete", Method, 5}, + {"(*Package).Name", Method, 5}, + {"(*Package).Path", Method, 5}, + {"(*Package).Scope", Method, 5}, + {"(*Package).SetImports", Method, 5}, + {"(*Package).SetName", Method, 6}, + {"(*Package).String", Method, 5}, + {"(*PkgName).Exported", Method, 5}, + {"(*PkgName).Id", Method, 5}, + {"(*PkgName).Imported", Method, 5}, + {"(*PkgName).Name", Method, 5}, + {"(*PkgName).Parent", Method, 5}, + {"(*PkgName).Pkg", Method, 5}, + {"(*PkgName).Pos", Method, 5}, + {"(*PkgName).String", Method, 5}, + {"(*PkgName).Type", Method, 5}, + {"(*Pointer).Elem", Method, 5}, + {"(*Pointer).String", Method, 5}, + {"(*Pointer).Underlying", Method, 5}, + {"(*Scope).Child", Method, 5}, + {"(*Scope).Contains", Method, 5}, + {"(*Scope).End", Method, 5}, + {"(*Scope).Innermost", Method, 5}, + {"(*Scope).Insert", Method, 5}, + {"(*Scope).Len", Method, 5}, + {"(*Scope).Lookup", Method, 5}, + {"(*Scope).LookupParent", Method, 5}, + {"(*Scope).Names", Method, 5}, + {"(*Scope).NumChildren", Method, 5}, + {"(*Scope).Parent", Method, 5}, + {"(*Scope).Pos", Method, 5}, + {"(*Scope).String", Method, 5}, + {"(*Scope).WriteTo", Method, 5}, + {"(*Selection).Index", Method, 5}, + {"(*Selection).Indirect", Method, 5}, + {"(*Selection).Kind", Method, 5}, + {"(*Selection).Obj", Method, 5}, + {"(*Selection).Recv", Method, 5}, + {"(*Selection).String", Method, 5}, + {"(*Selection).Type", Method, 5}, + {"(*Signature).Params", Method, 5}, + {"(*Signature).Recv", Method, 5}, + {"(*Signature).RecvTypeParams", Method, 18}, + {"(*Signature).Results", Method, 5}, + {"(*Signature).String", Method, 5}, + {"(*Signature).TypeParams", Method, 18}, + {"(*Signature).Underlying", Method, 5}, + {"(*Signature).Variadic", Method, 5}, + {"(*Slice).Elem", Method, 5}, + {"(*Slice).String", Method, 5}, + {"(*Slice).Underlying", Method, 5}, + {"(*StdSizes).Alignof", Method, 5}, + {"(*StdSizes).Offsetsof", Method, 5}, + {"(*StdSizes).Sizeof", Method, 5}, + {"(*Struct).Field", Method, 5}, + {"(*Struct).NumFields", Method, 5}, + {"(*Struct).String", Method, 5}, + {"(*Struct).Tag", Method, 5}, + {"(*Struct).Underlying", Method, 5}, + {"(*Term).String", Method, 18}, + {"(*Term).Tilde", Method, 18}, + {"(*Term).Type", Method, 18}, + {"(*Tuple).At", Method, 5}, + {"(*Tuple).Len", Method, 5}, + {"(*Tuple).String", Method, 5}, + {"(*Tuple).Underlying", Method, 5}, + {"(*TypeList).At", Method, 18}, + {"(*TypeList).Len", Method, 18}, + {"(*TypeName).Exported", Method, 5}, + {"(*TypeName).Id", Method, 5}, + {"(*TypeName).IsAlias", Method, 9}, + {"(*TypeName).Name", Method, 5}, + {"(*TypeName).Parent", Method, 5}, + {"(*TypeName).Pkg", Method, 5}, + {"(*TypeName).Pos", Method, 5}, + {"(*TypeName).String", Method, 5}, + {"(*TypeName).Type", Method, 5}, + {"(*TypeParam).Constraint", Method, 18}, + {"(*TypeParam).Index", Method, 18}, + {"(*TypeParam).Obj", Method, 18}, + {"(*TypeParam).SetConstraint", Method, 18}, + {"(*TypeParam).String", Method, 18}, + {"(*TypeParam).Underlying", Method, 18}, + {"(*TypeParamList).At", Method, 18}, + {"(*TypeParamList).Len", Method, 18}, + {"(*Union).Len", Method, 18}, + {"(*Union).String", Method, 18}, + {"(*Union).Term", Method, 18}, + {"(*Union).Underlying", Method, 18}, + {"(*Var).Anonymous", Method, 5}, + {"(*Var).Embedded", Method, 11}, + {"(*Var).Exported", Method, 5}, + {"(*Var).Id", Method, 5}, + {"(*Var).IsField", Method, 5}, + {"(*Var).Name", Method, 5}, + {"(*Var).Origin", Method, 19}, + {"(*Var).Parent", Method, 5}, + {"(*Var).Pkg", Method, 5}, + {"(*Var).Pos", Method, 5}, + {"(*Var).String", Method, 5}, + {"(*Var).Type", Method, 5}, + {"(Checker).ObjectOf", Method, 5}, + {"(Checker).PkgNameOf", Method, 22}, + {"(Checker).TypeOf", Method, 5}, + {"(Error).Error", Method, 5}, + {"(TypeAndValue).Addressable", Method, 5}, + {"(TypeAndValue).Assignable", Method, 5}, + {"(TypeAndValue).HasOk", Method, 5}, + {"(TypeAndValue).IsBuiltin", Method, 5}, + {"(TypeAndValue).IsNil", Method, 5}, + {"(TypeAndValue).IsType", Method, 5}, + {"(TypeAndValue).IsValue", Method, 5}, + {"(TypeAndValue).IsVoid", Method, 5}, + {"Alias", Type, 22}, + {"ArgumentError", Type, 18}, + {"ArgumentError.Err", Field, 18}, + {"ArgumentError.Index", Field, 18}, + {"Array", Type, 5}, + {"AssertableTo", Func, 5}, + {"AssignableTo", Func, 5}, + {"Basic", Type, 5}, + {"BasicInfo", Type, 5}, + {"BasicKind", Type, 5}, + {"Bool", Const, 5}, + {"Builtin", Type, 5}, + {"Byte", Const, 5}, + {"Chan", Type, 5}, + {"ChanDir", Type, 5}, + {"CheckExpr", Func, 13}, + {"Checker", Type, 5}, + {"Checker.Info", Field, 5}, + {"Comparable", Func, 5}, + {"Complex128", Const, 5}, + {"Complex64", Const, 5}, + {"Config", Type, 5}, + {"Config.Context", Field, 18}, + {"Config.DisableUnusedImportCheck", Field, 5}, + {"Config.Error", Field, 5}, + {"Config.FakeImportC", Field, 5}, + {"Config.GoVersion", Field, 18}, + {"Config.IgnoreFuncBodies", Field, 5}, + {"Config.Importer", Field, 5}, + {"Config.Sizes", Field, 5}, + {"Const", Type, 5}, + {"Context", Type, 18}, + {"ConvertibleTo", Func, 5}, + {"DefPredeclaredTestFuncs", Func, 5}, + {"Default", Func, 8}, + {"Error", Type, 5}, + {"Error.Fset", Field, 5}, + {"Error.Msg", Field, 5}, + {"Error.Pos", Field, 5}, + {"Error.Soft", Field, 5}, + {"Eval", Func, 5}, + {"ExprString", Func, 5}, + {"FieldVal", Const, 5}, + {"Float32", Const, 5}, + {"Float64", Const, 5}, + {"Func", Type, 5}, + {"Id", Func, 5}, + {"Identical", Func, 5}, + {"IdenticalIgnoreTags", Func, 8}, + {"Implements", Func, 5}, + {"ImportMode", Type, 6}, + {"Importer", Type, 5}, + {"ImporterFrom", Type, 6}, + {"Info", Type, 5}, + {"Info.Defs", Field, 5}, + {"Info.FileVersions", Field, 22}, + {"Info.Implicits", Field, 5}, + {"Info.InitOrder", Field, 5}, + {"Info.Instances", Field, 18}, + {"Info.Scopes", Field, 5}, + {"Info.Selections", Field, 5}, + {"Info.Types", Field, 5}, + {"Info.Uses", Field, 5}, + {"Initializer", Type, 5}, + {"Initializer.Lhs", Field, 5}, + {"Initializer.Rhs", Field, 5}, + {"Instance", Type, 18}, + {"Instance.Type", Field, 18}, + {"Instance.TypeArgs", Field, 18}, + {"Instantiate", Func, 18}, + {"Int", Const, 5}, + {"Int16", Const, 5}, + {"Int32", Const, 5}, + {"Int64", Const, 5}, + {"Int8", Const, 5}, + {"Interface", Type, 5}, + {"Invalid", Const, 5}, + {"IsBoolean", Const, 5}, + {"IsComplex", Const, 5}, + {"IsConstType", Const, 5}, + {"IsFloat", Const, 5}, + {"IsInteger", Const, 5}, + {"IsInterface", Func, 5}, + {"IsNumeric", Const, 5}, + {"IsOrdered", Const, 5}, + {"IsString", Const, 5}, + {"IsUnsigned", Const, 5}, + {"IsUntyped", Const, 5}, + {"Label", Type, 5}, + {"LookupFieldOrMethod", Func, 5}, + {"Map", Type, 5}, + {"MethodExpr", Const, 5}, + {"MethodSet", Type, 5}, + {"MethodVal", Const, 5}, + {"MissingMethod", Func, 5}, + {"Named", Type, 5}, + {"NewAlias", Func, 22}, + {"NewArray", Func, 5}, + {"NewChan", Func, 5}, + {"NewChecker", Func, 5}, + {"NewConst", Func, 5}, + {"NewContext", Func, 18}, + {"NewField", Func, 5}, + {"NewFunc", Func, 5}, + {"NewInterface", Func, 5}, + {"NewInterfaceType", Func, 11}, + {"NewLabel", Func, 5}, + {"NewMap", Func, 5}, + {"NewMethodSet", Func, 5}, + {"NewNamed", Func, 5}, + {"NewPackage", Func, 5}, + {"NewParam", Func, 5}, + {"NewPkgName", Func, 5}, + {"NewPointer", Func, 5}, + {"NewScope", Func, 5}, + {"NewSignature", Func, 5}, + {"NewSignatureType", Func, 18}, + {"NewSlice", Func, 5}, + {"NewStruct", Func, 5}, + {"NewTerm", Func, 18}, + {"NewTuple", Func, 5}, + {"NewTypeName", Func, 5}, + {"NewTypeParam", Func, 18}, + {"NewUnion", Func, 18}, + {"NewVar", Func, 5}, + {"Nil", Type, 5}, + {"Object", Type, 5}, + {"ObjectString", Func, 5}, + {"Package", Type, 5}, + {"PkgName", Type, 5}, + {"Pointer", Type, 5}, + {"Qualifier", Type, 5}, + {"RecvOnly", Const, 5}, + {"RelativeTo", Func, 5}, + {"Rune", Const, 5}, + {"Satisfies", Func, 20}, + {"Scope", Type, 5}, + {"Selection", Type, 5}, + {"SelectionKind", Type, 5}, + {"SelectionString", Func, 5}, + {"SendOnly", Const, 5}, + {"SendRecv", Const, 5}, + {"Signature", Type, 5}, + {"Sizes", Type, 5}, + {"SizesFor", Func, 9}, + {"Slice", Type, 5}, + {"StdSizes", Type, 5}, + {"StdSizes.MaxAlign", Field, 5}, + {"StdSizes.WordSize", Field, 5}, + {"String", Const, 5}, + {"Struct", Type, 5}, + {"Term", Type, 18}, + {"Tuple", Type, 5}, + {"Typ", Var, 5}, + {"Type", Type, 5}, + {"TypeAndValue", Type, 5}, + {"TypeAndValue.Type", Field, 5}, + {"TypeAndValue.Value", Field, 5}, + {"TypeList", Type, 18}, + {"TypeName", Type, 5}, + {"TypeParam", Type, 18}, + {"TypeParamList", Type, 18}, + {"TypeString", Func, 5}, + {"Uint", Const, 5}, + {"Uint16", Const, 5}, + {"Uint32", Const, 5}, + {"Uint64", Const, 5}, + {"Uint8", Const, 5}, + {"Uintptr", Const, 5}, + {"Unalias", Func, 22}, + {"Union", Type, 18}, + {"Universe", Var, 5}, + {"Unsafe", Var, 5}, + {"UnsafePointer", Const, 5}, + {"UntypedBool", Const, 5}, + {"UntypedComplex", Const, 5}, + {"UntypedFloat", Const, 5}, + {"UntypedInt", Const, 5}, + {"UntypedNil", Const, 5}, + {"UntypedRune", Const, 5}, + {"UntypedString", Const, 5}, + {"Var", Type, 5}, + {"WriteExpr", Func, 5}, + {"WriteSignature", Func, 5}, + {"WriteType", Func, 5}, + }, + "go/version": { + {"Compare", Func, 22}, + {"IsValid", Func, 22}, + {"Lang", Func, 22}, + }, + "hash": { + {"Hash", Type, 0}, + {"Hash32", Type, 0}, + {"Hash64", Type, 0}, + }, + "hash/adler32": { + {"Checksum", Func, 0}, + {"New", Func, 0}, + {"Size", Const, 0}, + }, + "hash/crc32": { + {"Castagnoli", Const, 0}, + {"Checksum", Func, 0}, + {"ChecksumIEEE", Func, 0}, + {"IEEE", Const, 0}, + {"IEEETable", Var, 0}, + {"Koopman", Const, 0}, + {"MakeTable", Func, 0}, + {"New", Func, 0}, + {"NewIEEE", Func, 0}, + {"Size", Const, 0}, + {"Table", Type, 0}, + {"Update", Func, 0}, + }, + "hash/crc64": { + {"Checksum", Func, 0}, + {"ECMA", Const, 0}, + {"ISO", Const, 0}, + {"MakeTable", Func, 0}, + {"New", Func, 0}, + {"Size", Const, 0}, + {"Table", Type, 0}, + {"Update", Func, 0}, + }, + "hash/fnv": { + {"New128", Func, 9}, + {"New128a", Func, 9}, + {"New32", Func, 0}, + {"New32a", Func, 0}, + {"New64", Func, 0}, + {"New64a", Func, 0}, + }, + "hash/maphash": { + {"(*Hash).BlockSize", Method, 14}, + {"(*Hash).Reset", Method, 14}, + {"(*Hash).Seed", Method, 14}, + {"(*Hash).SetSeed", Method, 14}, + {"(*Hash).Size", Method, 14}, + {"(*Hash).Sum", Method, 14}, + {"(*Hash).Sum64", Method, 14}, + {"(*Hash).Write", Method, 14}, + {"(*Hash).WriteByte", Method, 14}, + {"(*Hash).WriteString", Method, 14}, + {"Bytes", Func, 19}, + {"Hash", Type, 14}, + {"MakeSeed", Func, 14}, + {"Seed", Type, 14}, + {"String", Func, 19}, + }, + "html": { + {"EscapeString", Func, 0}, + {"UnescapeString", Func, 0}, + }, + "html/template": { + {"(*Error).Error", Method, 0}, + {"(*Template).AddParseTree", Method, 0}, + {"(*Template).Clone", Method, 0}, + {"(*Template).DefinedTemplates", Method, 6}, + {"(*Template).Delims", Method, 0}, + {"(*Template).Execute", Method, 0}, + {"(*Template).ExecuteTemplate", Method, 0}, + {"(*Template).Funcs", Method, 0}, + {"(*Template).Lookup", Method, 0}, + {"(*Template).Name", Method, 0}, + {"(*Template).New", Method, 0}, + {"(*Template).Option", Method, 5}, + {"(*Template).Parse", Method, 0}, + {"(*Template).ParseFS", Method, 16}, + {"(*Template).ParseFiles", Method, 0}, + {"(*Template).ParseGlob", Method, 0}, + {"(*Template).Templates", Method, 0}, + {"CSS", Type, 0}, + {"ErrAmbigContext", Const, 0}, + {"ErrBadHTML", Const, 0}, + {"ErrBranchEnd", Const, 0}, + {"ErrEndContext", Const, 0}, + {"ErrJSTemplate", Const, 21}, + {"ErrNoSuchTemplate", Const, 0}, + {"ErrOutputContext", Const, 0}, + {"ErrPartialCharset", Const, 0}, + {"ErrPartialEscape", Const, 0}, + {"ErrPredefinedEscaper", Const, 9}, + {"ErrRangeLoopReentry", Const, 0}, + {"ErrSlashAmbig", Const, 0}, + {"Error", Type, 0}, + {"Error.Description", Field, 0}, + {"Error.ErrorCode", Field, 0}, + {"Error.Line", Field, 0}, + {"Error.Name", Field, 0}, + {"Error.Node", Field, 4}, + {"ErrorCode", Type, 0}, + {"FuncMap", Type, 0}, + {"HTML", Type, 0}, + {"HTMLAttr", Type, 0}, + {"HTMLEscape", Func, 0}, + {"HTMLEscapeString", Func, 0}, + {"HTMLEscaper", Func, 0}, + {"IsTrue", Func, 6}, + {"JS", Type, 0}, + {"JSEscape", Func, 0}, + {"JSEscapeString", Func, 0}, + {"JSEscaper", Func, 0}, + {"JSStr", Type, 0}, + {"Must", Func, 0}, + {"New", Func, 0}, + {"OK", Const, 0}, + {"ParseFS", Func, 16}, + {"ParseFiles", Func, 0}, + {"ParseGlob", Func, 0}, + {"Srcset", Type, 10}, + {"Template", Type, 0}, + {"Template.Tree", Field, 2}, + {"URL", Type, 0}, + {"URLQueryEscaper", Func, 0}, + }, + "image": { + {"(*Alpha).AlphaAt", Method, 4}, + {"(*Alpha).At", Method, 0}, + {"(*Alpha).Bounds", Method, 0}, + {"(*Alpha).ColorModel", Method, 0}, + {"(*Alpha).Opaque", Method, 0}, + {"(*Alpha).PixOffset", Method, 0}, + {"(*Alpha).RGBA64At", Method, 17}, + {"(*Alpha).Set", Method, 0}, + {"(*Alpha).SetAlpha", Method, 0}, + {"(*Alpha).SetRGBA64", Method, 17}, + {"(*Alpha).SubImage", Method, 0}, + {"(*Alpha16).Alpha16At", Method, 4}, + {"(*Alpha16).At", Method, 0}, + {"(*Alpha16).Bounds", Method, 0}, + {"(*Alpha16).ColorModel", Method, 0}, + {"(*Alpha16).Opaque", Method, 0}, + {"(*Alpha16).PixOffset", Method, 0}, + {"(*Alpha16).RGBA64At", Method, 17}, + {"(*Alpha16).Set", Method, 0}, + {"(*Alpha16).SetAlpha16", Method, 0}, + {"(*Alpha16).SetRGBA64", Method, 17}, + {"(*Alpha16).SubImage", Method, 0}, + {"(*CMYK).At", Method, 5}, + {"(*CMYK).Bounds", Method, 5}, + {"(*CMYK).CMYKAt", Method, 5}, + {"(*CMYK).ColorModel", Method, 5}, + {"(*CMYK).Opaque", Method, 5}, + {"(*CMYK).PixOffset", Method, 5}, + {"(*CMYK).RGBA64At", Method, 17}, + {"(*CMYK).Set", Method, 5}, + {"(*CMYK).SetCMYK", Method, 5}, + {"(*CMYK).SetRGBA64", Method, 17}, + {"(*CMYK).SubImage", Method, 5}, + {"(*Gray).At", Method, 0}, + {"(*Gray).Bounds", Method, 0}, + {"(*Gray).ColorModel", Method, 0}, + {"(*Gray).GrayAt", Method, 4}, + {"(*Gray).Opaque", Method, 0}, + {"(*Gray).PixOffset", Method, 0}, + {"(*Gray).RGBA64At", Method, 17}, + {"(*Gray).Set", Method, 0}, + {"(*Gray).SetGray", Method, 0}, + {"(*Gray).SetRGBA64", Method, 17}, + {"(*Gray).SubImage", Method, 0}, + {"(*Gray16).At", Method, 0}, + {"(*Gray16).Bounds", Method, 0}, + {"(*Gray16).ColorModel", Method, 0}, + {"(*Gray16).Gray16At", Method, 4}, + {"(*Gray16).Opaque", Method, 0}, + {"(*Gray16).PixOffset", Method, 0}, + {"(*Gray16).RGBA64At", Method, 17}, + {"(*Gray16).Set", Method, 0}, + {"(*Gray16).SetGray16", Method, 0}, + {"(*Gray16).SetRGBA64", Method, 17}, + {"(*Gray16).SubImage", Method, 0}, + {"(*NRGBA).At", Method, 0}, + {"(*NRGBA).Bounds", Method, 0}, + {"(*NRGBA).ColorModel", Method, 0}, + {"(*NRGBA).NRGBAAt", Method, 4}, + {"(*NRGBA).Opaque", Method, 0}, + {"(*NRGBA).PixOffset", Method, 0}, + {"(*NRGBA).RGBA64At", Method, 17}, + {"(*NRGBA).Set", Method, 0}, + {"(*NRGBA).SetNRGBA", Method, 0}, + {"(*NRGBA).SetRGBA64", Method, 17}, + {"(*NRGBA).SubImage", Method, 0}, + {"(*NRGBA64).At", Method, 0}, + {"(*NRGBA64).Bounds", Method, 0}, + {"(*NRGBA64).ColorModel", Method, 0}, + {"(*NRGBA64).NRGBA64At", Method, 4}, + {"(*NRGBA64).Opaque", Method, 0}, + {"(*NRGBA64).PixOffset", Method, 0}, + {"(*NRGBA64).RGBA64At", Method, 17}, + {"(*NRGBA64).Set", Method, 0}, + {"(*NRGBA64).SetNRGBA64", Method, 0}, + {"(*NRGBA64).SetRGBA64", Method, 17}, + {"(*NRGBA64).SubImage", Method, 0}, + {"(*NYCbCrA).AOffset", Method, 6}, + {"(*NYCbCrA).At", Method, 6}, + {"(*NYCbCrA).Bounds", Method, 6}, + {"(*NYCbCrA).COffset", Method, 6}, + {"(*NYCbCrA).ColorModel", Method, 6}, + {"(*NYCbCrA).NYCbCrAAt", Method, 6}, + {"(*NYCbCrA).Opaque", Method, 6}, + {"(*NYCbCrA).RGBA64At", Method, 17}, + {"(*NYCbCrA).SubImage", Method, 6}, + {"(*NYCbCrA).YCbCrAt", Method, 6}, + {"(*NYCbCrA).YOffset", Method, 6}, + {"(*Paletted).At", Method, 0}, + {"(*Paletted).Bounds", Method, 0}, + {"(*Paletted).ColorIndexAt", Method, 0}, + {"(*Paletted).ColorModel", Method, 0}, + {"(*Paletted).Opaque", Method, 0}, + {"(*Paletted).PixOffset", Method, 0}, + {"(*Paletted).RGBA64At", Method, 17}, + {"(*Paletted).Set", Method, 0}, + {"(*Paletted).SetColorIndex", Method, 0}, + {"(*Paletted).SetRGBA64", Method, 17}, + {"(*Paletted).SubImage", Method, 0}, + {"(*RGBA).At", Method, 0}, + {"(*RGBA).Bounds", Method, 0}, + {"(*RGBA).ColorModel", Method, 0}, + {"(*RGBA).Opaque", Method, 0}, + {"(*RGBA).PixOffset", Method, 0}, + {"(*RGBA).RGBA64At", Method, 17}, + {"(*RGBA).RGBAAt", Method, 4}, + {"(*RGBA).Set", Method, 0}, + {"(*RGBA).SetRGBA", Method, 0}, + {"(*RGBA).SetRGBA64", Method, 17}, + {"(*RGBA).SubImage", Method, 0}, + {"(*RGBA64).At", Method, 0}, + {"(*RGBA64).Bounds", Method, 0}, + {"(*RGBA64).ColorModel", Method, 0}, + {"(*RGBA64).Opaque", Method, 0}, + {"(*RGBA64).PixOffset", Method, 0}, + {"(*RGBA64).RGBA64At", Method, 4}, + {"(*RGBA64).Set", Method, 0}, + {"(*RGBA64).SetRGBA64", Method, 0}, + {"(*RGBA64).SubImage", Method, 0}, + {"(*Uniform).At", Method, 0}, + {"(*Uniform).Bounds", Method, 0}, + {"(*Uniform).ColorModel", Method, 0}, + {"(*Uniform).Convert", Method, 0}, + {"(*Uniform).Opaque", Method, 0}, + {"(*Uniform).RGBA", Method, 0}, + {"(*Uniform).RGBA64At", Method, 17}, + {"(*YCbCr).At", Method, 0}, + {"(*YCbCr).Bounds", Method, 0}, + {"(*YCbCr).COffset", Method, 0}, + {"(*YCbCr).ColorModel", Method, 0}, + {"(*YCbCr).Opaque", Method, 0}, + {"(*YCbCr).RGBA64At", Method, 17}, + {"(*YCbCr).SubImage", Method, 0}, + {"(*YCbCr).YCbCrAt", Method, 4}, + {"(*YCbCr).YOffset", Method, 0}, + {"(Point).Add", Method, 0}, + {"(Point).Div", Method, 0}, + {"(Point).Eq", Method, 0}, + {"(Point).In", Method, 0}, + {"(Point).Mod", Method, 0}, + {"(Point).Mul", Method, 0}, + {"(Point).String", Method, 0}, + {"(Point).Sub", Method, 0}, + {"(Rectangle).Add", Method, 0}, + {"(Rectangle).At", Method, 5}, + {"(Rectangle).Bounds", Method, 5}, + {"(Rectangle).Canon", Method, 0}, + {"(Rectangle).ColorModel", Method, 5}, + {"(Rectangle).Dx", Method, 0}, + {"(Rectangle).Dy", Method, 0}, + {"(Rectangle).Empty", Method, 0}, + {"(Rectangle).Eq", Method, 0}, + {"(Rectangle).In", Method, 0}, + {"(Rectangle).Inset", Method, 0}, + {"(Rectangle).Intersect", Method, 0}, + {"(Rectangle).Overlaps", Method, 0}, + {"(Rectangle).RGBA64At", Method, 17}, + {"(Rectangle).Size", Method, 0}, + {"(Rectangle).String", Method, 0}, + {"(Rectangle).Sub", Method, 0}, + {"(Rectangle).Union", Method, 0}, + {"(YCbCrSubsampleRatio).String", Method, 0}, + {"Alpha", Type, 0}, + {"Alpha.Pix", Field, 0}, + {"Alpha.Rect", Field, 0}, + {"Alpha.Stride", Field, 0}, + {"Alpha16", Type, 0}, + {"Alpha16.Pix", Field, 0}, + {"Alpha16.Rect", Field, 0}, + {"Alpha16.Stride", Field, 0}, + {"Black", Var, 0}, + {"CMYK", Type, 5}, + {"CMYK.Pix", Field, 5}, + {"CMYK.Rect", Field, 5}, + {"CMYK.Stride", Field, 5}, + {"Config", Type, 0}, + {"Config.ColorModel", Field, 0}, + {"Config.Height", Field, 0}, + {"Config.Width", Field, 0}, + {"Decode", Func, 0}, + {"DecodeConfig", Func, 0}, + {"ErrFormat", Var, 0}, + {"Gray", Type, 0}, + {"Gray.Pix", Field, 0}, + {"Gray.Rect", Field, 0}, + {"Gray.Stride", Field, 0}, + {"Gray16", Type, 0}, + {"Gray16.Pix", Field, 0}, + {"Gray16.Rect", Field, 0}, + {"Gray16.Stride", Field, 0}, + {"Image", Type, 0}, + {"NRGBA", Type, 0}, + {"NRGBA.Pix", Field, 0}, + {"NRGBA.Rect", Field, 0}, + {"NRGBA.Stride", Field, 0}, + {"NRGBA64", Type, 0}, + {"NRGBA64.Pix", Field, 0}, + {"NRGBA64.Rect", Field, 0}, + {"NRGBA64.Stride", Field, 0}, + {"NYCbCrA", Type, 6}, + {"NYCbCrA.A", Field, 6}, + {"NYCbCrA.AStride", Field, 6}, + {"NYCbCrA.YCbCr", Field, 6}, + {"NewAlpha", Func, 0}, + {"NewAlpha16", Func, 0}, + {"NewCMYK", Func, 5}, + {"NewGray", Func, 0}, + {"NewGray16", Func, 0}, + {"NewNRGBA", Func, 0}, + {"NewNRGBA64", Func, 0}, + {"NewNYCbCrA", Func, 6}, + {"NewPaletted", Func, 0}, + {"NewRGBA", Func, 0}, + {"NewRGBA64", Func, 0}, + {"NewUniform", Func, 0}, + {"NewYCbCr", Func, 0}, + {"Opaque", Var, 0}, + {"Paletted", Type, 0}, + {"Paletted.Palette", Field, 0}, + {"Paletted.Pix", Field, 0}, + {"Paletted.Rect", Field, 0}, + {"Paletted.Stride", Field, 0}, + {"PalettedImage", Type, 0}, + {"Point", Type, 0}, + {"Point.X", Field, 0}, + {"Point.Y", Field, 0}, + {"Pt", Func, 0}, + {"RGBA", Type, 0}, + {"RGBA.Pix", Field, 0}, + {"RGBA.Rect", Field, 0}, + {"RGBA.Stride", Field, 0}, + {"RGBA64", Type, 0}, + {"RGBA64.Pix", Field, 0}, + {"RGBA64.Rect", Field, 0}, + {"RGBA64.Stride", Field, 0}, + {"RGBA64Image", Type, 17}, + {"Rect", Func, 0}, + {"Rectangle", Type, 0}, + {"Rectangle.Max", Field, 0}, + {"Rectangle.Min", Field, 0}, + {"RegisterFormat", Func, 0}, + {"Transparent", Var, 0}, + {"Uniform", Type, 0}, + {"Uniform.C", Field, 0}, + {"White", Var, 0}, + {"YCbCr", Type, 0}, + {"YCbCr.CStride", Field, 0}, + {"YCbCr.Cb", Field, 0}, + {"YCbCr.Cr", Field, 0}, + {"YCbCr.Rect", Field, 0}, + {"YCbCr.SubsampleRatio", Field, 0}, + {"YCbCr.Y", Field, 0}, + {"YCbCr.YStride", Field, 0}, + {"YCbCrSubsampleRatio", Type, 0}, + {"YCbCrSubsampleRatio410", Const, 5}, + {"YCbCrSubsampleRatio411", Const, 5}, + {"YCbCrSubsampleRatio420", Const, 0}, + {"YCbCrSubsampleRatio422", Const, 0}, + {"YCbCrSubsampleRatio440", Const, 1}, + {"YCbCrSubsampleRatio444", Const, 0}, + {"ZP", Var, 0}, + {"ZR", Var, 0}, + }, + "image/color": { + {"(Alpha).RGBA", Method, 0}, + {"(Alpha16).RGBA", Method, 0}, + {"(CMYK).RGBA", Method, 5}, + {"(Gray).RGBA", Method, 0}, + {"(Gray16).RGBA", Method, 0}, + {"(NRGBA).RGBA", Method, 0}, + {"(NRGBA64).RGBA", Method, 0}, + {"(NYCbCrA).RGBA", Method, 6}, + {"(Palette).Convert", Method, 0}, + {"(Palette).Index", Method, 0}, + {"(RGBA).RGBA", Method, 0}, + {"(RGBA64).RGBA", Method, 0}, + {"(YCbCr).RGBA", Method, 0}, + {"Alpha", Type, 0}, + {"Alpha.A", Field, 0}, + {"Alpha16", Type, 0}, + {"Alpha16.A", Field, 0}, + {"Alpha16Model", Var, 0}, + {"AlphaModel", Var, 0}, + {"Black", Var, 0}, + {"CMYK", Type, 5}, + {"CMYK.C", Field, 5}, + {"CMYK.K", Field, 5}, + {"CMYK.M", Field, 5}, + {"CMYK.Y", Field, 5}, + {"CMYKModel", Var, 5}, + {"CMYKToRGB", Func, 5}, + {"Color", Type, 0}, + {"Gray", Type, 0}, + {"Gray.Y", Field, 0}, + {"Gray16", Type, 0}, + {"Gray16.Y", Field, 0}, + {"Gray16Model", Var, 0}, + {"GrayModel", Var, 0}, + {"Model", Type, 0}, + {"ModelFunc", Func, 0}, + {"NRGBA", Type, 0}, + {"NRGBA.A", Field, 0}, + {"NRGBA.B", Field, 0}, + {"NRGBA.G", Field, 0}, + {"NRGBA.R", Field, 0}, + {"NRGBA64", Type, 0}, + {"NRGBA64.A", Field, 0}, + {"NRGBA64.B", Field, 0}, + {"NRGBA64.G", Field, 0}, + {"NRGBA64.R", Field, 0}, + {"NRGBA64Model", Var, 0}, + {"NRGBAModel", Var, 0}, + {"NYCbCrA", Type, 6}, + {"NYCbCrA.A", Field, 6}, + {"NYCbCrA.YCbCr", Field, 6}, + {"NYCbCrAModel", Var, 6}, + {"Opaque", Var, 0}, + {"Palette", Type, 0}, + {"RGBA", Type, 0}, + {"RGBA.A", Field, 0}, + {"RGBA.B", Field, 0}, + {"RGBA.G", Field, 0}, + {"RGBA.R", Field, 0}, + {"RGBA64", Type, 0}, + {"RGBA64.A", Field, 0}, + {"RGBA64.B", Field, 0}, + {"RGBA64.G", Field, 0}, + {"RGBA64.R", Field, 0}, + {"RGBA64Model", Var, 0}, + {"RGBAModel", Var, 0}, + {"RGBToCMYK", Func, 5}, + {"RGBToYCbCr", Func, 0}, + {"Transparent", Var, 0}, + {"White", Var, 0}, + {"YCbCr", Type, 0}, + {"YCbCr.Cb", Field, 0}, + {"YCbCr.Cr", Field, 0}, + {"YCbCr.Y", Field, 0}, + {"YCbCrModel", Var, 0}, + {"YCbCrToRGB", Func, 0}, + }, + "image/color/palette": { + {"Plan9", Var, 2}, + {"WebSafe", Var, 2}, + }, + "image/draw": { + {"(Op).Draw", Method, 2}, + {"Draw", Func, 0}, + {"DrawMask", Func, 0}, + {"Drawer", Type, 2}, + {"FloydSteinberg", Var, 2}, + {"Image", Type, 0}, + {"Op", Type, 0}, + {"Over", Const, 0}, + {"Quantizer", Type, 2}, + {"RGBA64Image", Type, 17}, + {"Src", Const, 0}, + }, + "image/gif": { + {"Decode", Func, 0}, + {"DecodeAll", Func, 0}, + {"DecodeConfig", Func, 0}, + {"DisposalBackground", Const, 5}, + {"DisposalNone", Const, 5}, + {"DisposalPrevious", Const, 5}, + {"Encode", Func, 2}, + {"EncodeAll", Func, 2}, + {"GIF", Type, 0}, + {"GIF.BackgroundIndex", Field, 5}, + {"GIF.Config", Field, 5}, + {"GIF.Delay", Field, 0}, + {"GIF.Disposal", Field, 5}, + {"GIF.Image", Field, 0}, + {"GIF.LoopCount", Field, 0}, + {"Options", Type, 2}, + {"Options.Drawer", Field, 2}, + {"Options.NumColors", Field, 2}, + {"Options.Quantizer", Field, 2}, + }, + "image/jpeg": { + {"(FormatError).Error", Method, 0}, + {"(UnsupportedError).Error", Method, 0}, + {"Decode", Func, 0}, + {"DecodeConfig", Func, 0}, + {"DefaultQuality", Const, 0}, + {"Encode", Func, 0}, + {"FormatError", Type, 0}, + {"Options", Type, 0}, + {"Options.Quality", Field, 0}, + {"Reader", Type, 0}, + {"UnsupportedError", Type, 0}, + }, + "image/png": { + {"(*Encoder).Encode", Method, 4}, + {"(FormatError).Error", Method, 0}, + {"(UnsupportedError).Error", Method, 0}, + {"BestCompression", Const, 4}, + {"BestSpeed", Const, 4}, + {"CompressionLevel", Type, 4}, + {"Decode", Func, 0}, + {"DecodeConfig", Func, 0}, + {"DefaultCompression", Const, 4}, + {"Encode", Func, 0}, + {"Encoder", Type, 4}, + {"Encoder.BufferPool", Field, 9}, + {"Encoder.CompressionLevel", Field, 4}, + {"EncoderBuffer", Type, 9}, + {"EncoderBufferPool", Type, 9}, + {"FormatError", Type, 0}, + {"NoCompression", Const, 4}, + {"UnsupportedError", Type, 0}, + }, + "index/suffixarray": { + {"(*Index).Bytes", Method, 0}, + {"(*Index).FindAllIndex", Method, 0}, + {"(*Index).Lookup", Method, 0}, + {"(*Index).Read", Method, 0}, + {"(*Index).Write", Method, 0}, + {"Index", Type, 0}, + {"New", Func, 0}, + }, + "io": { + {"(*LimitedReader).Read", Method, 0}, + {"(*OffsetWriter).Seek", Method, 20}, + {"(*OffsetWriter).Write", Method, 20}, + {"(*OffsetWriter).WriteAt", Method, 20}, + {"(*PipeReader).Close", Method, 0}, + {"(*PipeReader).CloseWithError", Method, 0}, + {"(*PipeReader).Read", Method, 0}, + {"(*PipeWriter).Close", Method, 0}, + {"(*PipeWriter).CloseWithError", Method, 0}, + {"(*PipeWriter).Write", Method, 0}, + {"(*SectionReader).Outer", Method, 22}, + {"(*SectionReader).Read", Method, 0}, + {"(*SectionReader).ReadAt", Method, 0}, + {"(*SectionReader).Seek", Method, 0}, + {"(*SectionReader).Size", Method, 0}, + {"ByteReader", Type, 0}, + {"ByteScanner", Type, 0}, + {"ByteWriter", Type, 1}, + {"Closer", Type, 0}, + {"Copy", Func, 0}, + {"CopyBuffer", Func, 5}, + {"CopyN", Func, 0}, + {"Discard", Var, 16}, + {"EOF", Var, 0}, + {"ErrClosedPipe", Var, 0}, + {"ErrNoProgress", Var, 1}, + {"ErrShortBuffer", Var, 0}, + {"ErrShortWrite", Var, 0}, + {"ErrUnexpectedEOF", Var, 0}, + {"LimitReader", Func, 0}, + {"LimitedReader", Type, 0}, + {"LimitedReader.N", Field, 0}, + {"LimitedReader.R", Field, 0}, + {"MultiReader", Func, 0}, + {"MultiWriter", Func, 0}, + {"NewOffsetWriter", Func, 20}, + {"NewSectionReader", Func, 0}, + {"NopCloser", Func, 16}, + {"OffsetWriter", Type, 20}, + {"Pipe", Func, 0}, + {"PipeReader", Type, 0}, + {"PipeWriter", Type, 0}, + {"ReadAll", Func, 16}, + {"ReadAtLeast", Func, 0}, + {"ReadCloser", Type, 0}, + {"ReadFull", Func, 0}, + {"ReadSeekCloser", Type, 16}, + {"ReadSeeker", Type, 0}, + {"ReadWriteCloser", Type, 0}, + {"ReadWriteSeeker", Type, 0}, + {"ReadWriter", Type, 0}, + {"Reader", Type, 0}, + {"ReaderAt", Type, 0}, + {"ReaderFrom", Type, 0}, + {"RuneReader", Type, 0}, + {"RuneScanner", Type, 0}, + {"SectionReader", Type, 0}, + {"SeekCurrent", Const, 7}, + {"SeekEnd", Const, 7}, + {"SeekStart", Const, 7}, + {"Seeker", Type, 0}, + {"StringWriter", Type, 12}, + {"TeeReader", Func, 0}, + {"WriteCloser", Type, 0}, + {"WriteSeeker", Type, 0}, + {"WriteString", Func, 0}, + {"Writer", Type, 0}, + {"WriterAt", Type, 0}, + {"WriterTo", Type, 0}, + }, + "io/fs": { + {"(*PathError).Error", Method, 16}, + {"(*PathError).Timeout", Method, 16}, + {"(*PathError).Unwrap", Method, 16}, + {"(FileMode).IsDir", Method, 16}, + {"(FileMode).IsRegular", Method, 16}, + {"(FileMode).Perm", Method, 16}, + {"(FileMode).String", Method, 16}, + {"(FileMode).Type", Method, 16}, + {"DirEntry", Type, 16}, + {"ErrClosed", Var, 16}, + {"ErrExist", Var, 16}, + {"ErrInvalid", Var, 16}, + {"ErrNotExist", Var, 16}, + {"ErrPermission", Var, 16}, + {"FS", Type, 16}, + {"File", Type, 16}, + {"FileInfo", Type, 16}, + {"FileInfoToDirEntry", Func, 17}, + {"FileMode", Type, 16}, + {"FormatDirEntry", Func, 21}, + {"FormatFileInfo", Func, 21}, + {"Glob", Func, 16}, + {"GlobFS", Type, 16}, + {"ModeAppend", Const, 16}, + {"ModeCharDevice", Const, 16}, + {"ModeDevice", Const, 16}, + {"ModeDir", Const, 16}, + {"ModeExclusive", Const, 16}, + {"ModeIrregular", Const, 16}, + {"ModeNamedPipe", Const, 16}, + {"ModePerm", Const, 16}, + {"ModeSetgid", Const, 16}, + {"ModeSetuid", Const, 16}, + {"ModeSocket", Const, 16}, + {"ModeSticky", Const, 16}, + {"ModeSymlink", Const, 16}, + {"ModeTemporary", Const, 16}, + {"ModeType", Const, 16}, + {"PathError", Type, 16}, + {"PathError.Err", Field, 16}, + {"PathError.Op", Field, 16}, + {"PathError.Path", Field, 16}, + {"ReadDir", Func, 16}, + {"ReadDirFS", Type, 16}, + {"ReadDirFile", Type, 16}, + {"ReadFile", Func, 16}, + {"ReadFileFS", Type, 16}, + {"SkipAll", Var, 20}, + {"SkipDir", Var, 16}, + {"Stat", Func, 16}, + {"StatFS", Type, 16}, + {"Sub", Func, 16}, + {"SubFS", Type, 16}, + {"ValidPath", Func, 16}, + {"WalkDir", Func, 16}, + {"WalkDirFunc", Type, 16}, + }, + "io/ioutil": { + {"Discard", Var, 0}, + {"NopCloser", Func, 0}, + {"ReadAll", Func, 0}, + {"ReadDir", Func, 0}, + {"ReadFile", Func, 0}, + {"TempDir", Func, 0}, + {"TempFile", Func, 0}, + {"WriteFile", Func, 0}, + }, + "iter": { + {"Pull", Func, 23}, + {"Pull2", Func, 23}, + {"Seq", Type, 23}, + {"Seq2", Type, 23}, + }, + "log": { + {"(*Logger).Fatal", Method, 0}, + {"(*Logger).Fatalf", Method, 0}, + {"(*Logger).Fatalln", Method, 0}, + {"(*Logger).Flags", Method, 0}, + {"(*Logger).Output", Method, 0}, + {"(*Logger).Panic", Method, 0}, + {"(*Logger).Panicf", Method, 0}, + {"(*Logger).Panicln", Method, 0}, + {"(*Logger).Prefix", Method, 0}, + {"(*Logger).Print", Method, 0}, + {"(*Logger).Printf", Method, 0}, + {"(*Logger).Println", Method, 0}, + {"(*Logger).SetFlags", Method, 0}, + {"(*Logger).SetOutput", Method, 5}, + {"(*Logger).SetPrefix", Method, 0}, + {"(*Logger).Writer", Method, 12}, + {"Default", Func, 16}, + {"Fatal", Func, 0}, + {"Fatalf", Func, 0}, + {"Fatalln", Func, 0}, + {"Flags", Func, 0}, + {"LUTC", Const, 5}, + {"Ldate", Const, 0}, + {"Llongfile", Const, 0}, + {"Lmicroseconds", Const, 0}, + {"Lmsgprefix", Const, 14}, + {"Logger", Type, 0}, + {"Lshortfile", Const, 0}, + {"LstdFlags", Const, 0}, + {"Ltime", Const, 0}, + {"New", Func, 0}, + {"Output", Func, 5}, + {"Panic", Func, 0}, + {"Panicf", Func, 0}, + {"Panicln", Func, 0}, + {"Prefix", Func, 0}, + {"Print", Func, 0}, + {"Printf", Func, 0}, + {"Println", Func, 0}, + {"SetFlags", Func, 0}, + {"SetOutput", Func, 0}, + {"SetPrefix", Func, 0}, + {"Writer", Func, 13}, + }, + "log/slog": { + {"(*JSONHandler).Enabled", Method, 21}, + {"(*JSONHandler).Handle", Method, 21}, + {"(*JSONHandler).WithAttrs", Method, 21}, + {"(*JSONHandler).WithGroup", Method, 21}, + {"(*Level).UnmarshalJSON", Method, 21}, + {"(*Level).UnmarshalText", Method, 21}, + {"(*LevelVar).Level", Method, 21}, + {"(*LevelVar).MarshalText", Method, 21}, + {"(*LevelVar).Set", Method, 21}, + {"(*LevelVar).String", Method, 21}, + {"(*LevelVar).UnmarshalText", Method, 21}, + {"(*Logger).Debug", Method, 21}, + {"(*Logger).DebugContext", Method, 21}, + {"(*Logger).Enabled", Method, 21}, + {"(*Logger).Error", Method, 21}, + {"(*Logger).ErrorContext", Method, 21}, + {"(*Logger).Handler", Method, 21}, + {"(*Logger).Info", Method, 21}, + {"(*Logger).InfoContext", Method, 21}, + {"(*Logger).Log", Method, 21}, + {"(*Logger).LogAttrs", Method, 21}, + {"(*Logger).Warn", Method, 21}, + {"(*Logger).WarnContext", Method, 21}, + {"(*Logger).With", Method, 21}, + {"(*Logger).WithGroup", Method, 21}, + {"(*Record).Add", Method, 21}, + {"(*Record).AddAttrs", Method, 21}, + {"(*TextHandler).Enabled", Method, 21}, + {"(*TextHandler).Handle", Method, 21}, + {"(*TextHandler).WithAttrs", Method, 21}, + {"(*TextHandler).WithGroup", Method, 21}, + {"(Attr).Equal", Method, 21}, + {"(Attr).String", Method, 21}, + {"(Kind).String", Method, 21}, + {"(Level).Level", Method, 21}, + {"(Level).MarshalJSON", Method, 21}, + {"(Level).MarshalText", Method, 21}, + {"(Level).String", Method, 21}, + {"(Record).Attrs", Method, 21}, + {"(Record).Clone", Method, 21}, + {"(Record).NumAttrs", Method, 21}, + {"(Value).Any", Method, 21}, + {"(Value).Bool", Method, 21}, + {"(Value).Duration", Method, 21}, + {"(Value).Equal", Method, 21}, + {"(Value).Float64", Method, 21}, + {"(Value).Group", Method, 21}, + {"(Value).Int64", Method, 21}, + {"(Value).Kind", Method, 21}, + {"(Value).LogValuer", Method, 21}, + {"(Value).Resolve", Method, 21}, + {"(Value).String", Method, 21}, + {"(Value).Time", Method, 21}, + {"(Value).Uint64", Method, 21}, + {"Any", Func, 21}, + {"AnyValue", Func, 21}, + {"Attr", Type, 21}, + {"Attr.Key", Field, 21}, + {"Attr.Value", Field, 21}, + {"Bool", Func, 21}, + {"BoolValue", Func, 21}, + {"Debug", Func, 21}, + {"DebugContext", Func, 21}, + {"Default", Func, 21}, + {"Duration", Func, 21}, + {"DurationValue", Func, 21}, + {"Error", Func, 21}, + {"ErrorContext", Func, 21}, + {"Float64", Func, 21}, + {"Float64Value", Func, 21}, + {"Group", Func, 21}, + {"GroupValue", Func, 21}, + {"Handler", Type, 21}, + {"HandlerOptions", Type, 21}, + {"HandlerOptions.AddSource", Field, 21}, + {"HandlerOptions.Level", Field, 21}, + {"HandlerOptions.ReplaceAttr", Field, 21}, + {"Info", Func, 21}, + {"InfoContext", Func, 21}, + {"Int", Func, 21}, + {"Int64", Func, 21}, + {"Int64Value", Func, 21}, + {"IntValue", Func, 21}, + {"JSONHandler", Type, 21}, + {"Kind", Type, 21}, + {"KindAny", Const, 21}, + {"KindBool", Const, 21}, + {"KindDuration", Const, 21}, + {"KindFloat64", Const, 21}, + {"KindGroup", Const, 21}, + {"KindInt64", Const, 21}, + {"KindLogValuer", Const, 21}, + {"KindString", Const, 21}, + {"KindTime", Const, 21}, + {"KindUint64", Const, 21}, + {"Level", Type, 21}, + {"LevelDebug", Const, 21}, + {"LevelError", Const, 21}, + {"LevelInfo", Const, 21}, + {"LevelKey", Const, 21}, + {"LevelVar", Type, 21}, + {"LevelWarn", Const, 21}, + {"Leveler", Type, 21}, + {"Log", Func, 21}, + {"LogAttrs", Func, 21}, + {"LogValuer", Type, 21}, + {"Logger", Type, 21}, + {"MessageKey", Const, 21}, + {"New", Func, 21}, + {"NewJSONHandler", Func, 21}, + {"NewLogLogger", Func, 21}, + {"NewRecord", Func, 21}, + {"NewTextHandler", Func, 21}, + {"Record", Type, 21}, + {"Record.Level", Field, 21}, + {"Record.Message", Field, 21}, + {"Record.PC", Field, 21}, + {"Record.Time", Field, 21}, + {"SetDefault", Func, 21}, + {"SetLogLoggerLevel", Func, 22}, + {"Source", Type, 21}, + {"Source.File", Field, 21}, + {"Source.Function", Field, 21}, + {"Source.Line", Field, 21}, + {"SourceKey", Const, 21}, + {"String", Func, 21}, + {"StringValue", Func, 21}, + {"TextHandler", Type, 21}, + {"Time", Func, 21}, + {"TimeKey", Const, 21}, + {"TimeValue", Func, 21}, + {"Uint64", Func, 21}, + {"Uint64Value", Func, 21}, + {"Value", Type, 21}, + {"Warn", Func, 21}, + {"WarnContext", Func, 21}, + {"With", Func, 21}, + }, + "log/syslog": { + {"(*Writer).Alert", Method, 0}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Crit", Method, 0}, + {"(*Writer).Debug", Method, 0}, + {"(*Writer).Emerg", Method, 0}, + {"(*Writer).Err", Method, 0}, + {"(*Writer).Info", Method, 0}, + {"(*Writer).Notice", Method, 0}, + {"(*Writer).Warning", Method, 0}, + {"(*Writer).Write", Method, 0}, + {"Dial", Func, 0}, + {"LOG_ALERT", Const, 0}, + {"LOG_AUTH", Const, 1}, + {"LOG_AUTHPRIV", Const, 1}, + {"LOG_CRIT", Const, 0}, + {"LOG_CRON", Const, 1}, + {"LOG_DAEMON", Const, 1}, + {"LOG_DEBUG", Const, 0}, + {"LOG_EMERG", Const, 0}, + {"LOG_ERR", Const, 0}, + {"LOG_FTP", Const, 1}, + {"LOG_INFO", Const, 0}, + {"LOG_KERN", Const, 1}, + {"LOG_LOCAL0", Const, 1}, + {"LOG_LOCAL1", Const, 1}, + {"LOG_LOCAL2", Const, 1}, + {"LOG_LOCAL3", Const, 1}, + {"LOG_LOCAL4", Const, 1}, + {"LOG_LOCAL5", Const, 1}, + {"LOG_LOCAL6", Const, 1}, + {"LOG_LOCAL7", Const, 1}, + {"LOG_LPR", Const, 1}, + {"LOG_MAIL", Const, 1}, + {"LOG_NEWS", Const, 1}, + {"LOG_NOTICE", Const, 0}, + {"LOG_SYSLOG", Const, 1}, + {"LOG_USER", Const, 1}, + {"LOG_UUCP", Const, 1}, + {"LOG_WARNING", Const, 0}, + {"New", Func, 0}, + {"NewLogger", Func, 0}, + {"Priority", Type, 0}, + {"Writer", Type, 0}, + }, + "maps": { + {"All", Func, 23}, + {"Clone", Func, 21}, + {"Collect", Func, 23}, + {"Copy", Func, 21}, + {"DeleteFunc", Func, 21}, + {"Equal", Func, 21}, + {"EqualFunc", Func, 21}, + {"Insert", Func, 23}, + {"Keys", Func, 23}, + {"Values", Func, 23}, + }, + "math": { + {"Abs", Func, 0}, + {"Acos", Func, 0}, + {"Acosh", Func, 0}, + {"Asin", Func, 0}, + {"Asinh", Func, 0}, + {"Atan", Func, 0}, + {"Atan2", Func, 0}, + {"Atanh", Func, 0}, + {"Cbrt", Func, 0}, + {"Ceil", Func, 0}, + {"Copysign", Func, 0}, + {"Cos", Func, 0}, + {"Cosh", Func, 0}, + {"Dim", Func, 0}, + {"E", Const, 0}, + {"Erf", Func, 0}, + {"Erfc", Func, 0}, + {"Erfcinv", Func, 10}, + {"Erfinv", Func, 10}, + {"Exp", Func, 0}, + {"Exp2", Func, 0}, + {"Expm1", Func, 0}, + {"FMA", Func, 14}, + {"Float32bits", Func, 0}, + {"Float32frombits", Func, 0}, + {"Float64bits", Func, 0}, + {"Float64frombits", Func, 0}, + {"Floor", Func, 0}, + {"Frexp", Func, 0}, + {"Gamma", Func, 0}, + {"Hypot", Func, 0}, + {"Ilogb", Func, 0}, + {"Inf", Func, 0}, + {"IsInf", Func, 0}, + {"IsNaN", Func, 0}, + {"J0", Func, 0}, + {"J1", Func, 0}, + {"Jn", Func, 0}, + {"Ldexp", Func, 0}, + {"Lgamma", Func, 0}, + {"Ln10", Const, 0}, + {"Ln2", Const, 0}, + {"Log", Func, 0}, + {"Log10", Func, 0}, + {"Log10E", Const, 0}, + {"Log1p", Func, 0}, + {"Log2", Func, 0}, + {"Log2E", Const, 0}, + {"Logb", Func, 0}, + {"Max", Func, 0}, + {"MaxFloat32", Const, 0}, + {"MaxFloat64", Const, 0}, + {"MaxInt", Const, 17}, + {"MaxInt16", Const, 0}, + {"MaxInt32", Const, 0}, + {"MaxInt64", Const, 0}, + {"MaxInt8", Const, 0}, + {"MaxUint", Const, 17}, + {"MaxUint16", Const, 0}, + {"MaxUint32", Const, 0}, + {"MaxUint64", Const, 0}, + {"MaxUint8", Const, 0}, + {"Min", Func, 0}, + {"MinInt", Const, 17}, + {"MinInt16", Const, 0}, + {"MinInt32", Const, 0}, + {"MinInt64", Const, 0}, + {"MinInt8", Const, 0}, + {"Mod", Func, 0}, + {"Modf", Func, 0}, + {"NaN", Func, 0}, + {"Nextafter", Func, 0}, + {"Nextafter32", Func, 4}, + {"Phi", Const, 0}, + {"Pi", Const, 0}, + {"Pow", Func, 0}, + {"Pow10", Func, 0}, + {"Remainder", Func, 0}, + {"Round", Func, 10}, + {"RoundToEven", Func, 10}, + {"Signbit", Func, 0}, + {"Sin", Func, 0}, + {"Sincos", Func, 0}, + {"Sinh", Func, 0}, + {"SmallestNonzeroFloat32", Const, 0}, + {"SmallestNonzeroFloat64", Const, 0}, + {"Sqrt", Func, 0}, + {"Sqrt2", Const, 0}, + {"SqrtE", Const, 0}, + {"SqrtPhi", Const, 0}, + {"SqrtPi", Const, 0}, + {"Tan", Func, 0}, + {"Tanh", Func, 0}, + {"Trunc", Func, 0}, + {"Y0", Func, 0}, + {"Y1", Func, 0}, + {"Yn", Func, 0}, + }, + "math/big": { + {"(*Float).Abs", Method, 5}, + {"(*Float).Acc", Method, 5}, + {"(*Float).Add", Method, 5}, + {"(*Float).Append", Method, 5}, + {"(*Float).Cmp", Method, 5}, + {"(*Float).Copy", Method, 5}, + {"(*Float).Float32", Method, 5}, + {"(*Float).Float64", Method, 5}, + {"(*Float).Format", Method, 5}, + {"(*Float).GobDecode", Method, 7}, + {"(*Float).GobEncode", Method, 7}, + {"(*Float).Int", Method, 5}, + {"(*Float).Int64", Method, 5}, + {"(*Float).IsInf", Method, 5}, + {"(*Float).IsInt", Method, 5}, + {"(*Float).MantExp", Method, 5}, + {"(*Float).MarshalText", Method, 6}, + {"(*Float).MinPrec", Method, 5}, + {"(*Float).Mode", Method, 5}, + {"(*Float).Mul", Method, 5}, + {"(*Float).Neg", Method, 5}, + {"(*Float).Parse", Method, 5}, + {"(*Float).Prec", Method, 5}, + {"(*Float).Quo", Method, 5}, + {"(*Float).Rat", Method, 5}, + {"(*Float).Scan", Method, 8}, + {"(*Float).Set", Method, 5}, + {"(*Float).SetFloat64", Method, 5}, + {"(*Float).SetInf", Method, 5}, + {"(*Float).SetInt", Method, 5}, + {"(*Float).SetInt64", Method, 5}, + {"(*Float).SetMantExp", Method, 5}, + {"(*Float).SetMode", Method, 5}, + {"(*Float).SetPrec", Method, 5}, + {"(*Float).SetRat", Method, 5}, + {"(*Float).SetString", Method, 5}, + {"(*Float).SetUint64", Method, 5}, + {"(*Float).Sign", Method, 5}, + {"(*Float).Signbit", Method, 5}, + {"(*Float).Sqrt", Method, 10}, + {"(*Float).String", Method, 5}, + {"(*Float).Sub", Method, 5}, + {"(*Float).Text", Method, 5}, + {"(*Float).Uint64", Method, 5}, + {"(*Float).UnmarshalText", Method, 6}, + {"(*Int).Abs", Method, 0}, + {"(*Int).Add", Method, 0}, + {"(*Int).And", Method, 0}, + {"(*Int).AndNot", Method, 0}, + {"(*Int).Append", Method, 6}, + {"(*Int).Binomial", Method, 0}, + {"(*Int).Bit", Method, 0}, + {"(*Int).BitLen", Method, 0}, + {"(*Int).Bits", Method, 0}, + {"(*Int).Bytes", Method, 0}, + {"(*Int).Cmp", Method, 0}, + {"(*Int).CmpAbs", Method, 10}, + {"(*Int).Div", Method, 0}, + {"(*Int).DivMod", Method, 0}, + {"(*Int).Exp", Method, 0}, + {"(*Int).FillBytes", Method, 15}, + {"(*Int).Float64", Method, 21}, + {"(*Int).Format", Method, 0}, + {"(*Int).GCD", Method, 0}, + {"(*Int).GobDecode", Method, 0}, + {"(*Int).GobEncode", Method, 0}, + {"(*Int).Int64", Method, 0}, + {"(*Int).IsInt64", Method, 9}, + {"(*Int).IsUint64", Method, 9}, + {"(*Int).Lsh", Method, 0}, + {"(*Int).MarshalJSON", Method, 1}, + {"(*Int).MarshalText", Method, 3}, + {"(*Int).Mod", Method, 0}, + {"(*Int).ModInverse", Method, 0}, + {"(*Int).ModSqrt", Method, 5}, + {"(*Int).Mul", Method, 0}, + {"(*Int).MulRange", Method, 0}, + {"(*Int).Neg", Method, 0}, + {"(*Int).Not", Method, 0}, + {"(*Int).Or", Method, 0}, + {"(*Int).ProbablyPrime", Method, 0}, + {"(*Int).Quo", Method, 0}, + {"(*Int).QuoRem", Method, 0}, + {"(*Int).Rand", Method, 0}, + {"(*Int).Rem", Method, 0}, + {"(*Int).Rsh", Method, 0}, + {"(*Int).Scan", Method, 0}, + {"(*Int).Set", Method, 0}, + {"(*Int).SetBit", Method, 0}, + {"(*Int).SetBits", Method, 0}, + {"(*Int).SetBytes", Method, 0}, + {"(*Int).SetInt64", Method, 0}, + {"(*Int).SetString", Method, 0}, + {"(*Int).SetUint64", Method, 1}, + {"(*Int).Sign", Method, 0}, + {"(*Int).Sqrt", Method, 8}, + {"(*Int).String", Method, 0}, + {"(*Int).Sub", Method, 0}, + {"(*Int).Text", Method, 6}, + {"(*Int).TrailingZeroBits", Method, 13}, + {"(*Int).Uint64", Method, 1}, + {"(*Int).UnmarshalJSON", Method, 1}, + {"(*Int).UnmarshalText", Method, 3}, + {"(*Int).Xor", Method, 0}, + {"(*Rat).Abs", Method, 0}, + {"(*Rat).Add", Method, 0}, + {"(*Rat).Cmp", Method, 0}, + {"(*Rat).Denom", Method, 0}, + {"(*Rat).Float32", Method, 4}, + {"(*Rat).Float64", Method, 1}, + {"(*Rat).FloatPrec", Method, 22}, + {"(*Rat).FloatString", Method, 0}, + {"(*Rat).GobDecode", Method, 0}, + {"(*Rat).GobEncode", Method, 0}, + {"(*Rat).Inv", Method, 0}, + {"(*Rat).IsInt", Method, 0}, + {"(*Rat).MarshalText", Method, 3}, + {"(*Rat).Mul", Method, 0}, + {"(*Rat).Neg", Method, 0}, + {"(*Rat).Num", Method, 0}, + {"(*Rat).Quo", Method, 0}, + {"(*Rat).RatString", Method, 0}, + {"(*Rat).Scan", Method, 0}, + {"(*Rat).Set", Method, 0}, + {"(*Rat).SetFloat64", Method, 1}, + {"(*Rat).SetFrac", Method, 0}, + {"(*Rat).SetFrac64", Method, 0}, + {"(*Rat).SetInt", Method, 0}, + {"(*Rat).SetInt64", Method, 0}, + {"(*Rat).SetString", Method, 0}, + {"(*Rat).SetUint64", Method, 13}, + {"(*Rat).Sign", Method, 0}, + {"(*Rat).String", Method, 0}, + {"(*Rat).Sub", Method, 0}, + {"(*Rat).UnmarshalText", Method, 3}, + {"(Accuracy).String", Method, 5}, + {"(ErrNaN).Error", Method, 5}, + {"(RoundingMode).String", Method, 5}, + {"Above", Const, 5}, + {"Accuracy", Type, 5}, + {"AwayFromZero", Const, 5}, + {"Below", Const, 5}, + {"ErrNaN", Type, 5}, + {"Exact", Const, 5}, + {"Float", Type, 5}, + {"Int", Type, 0}, + {"Jacobi", Func, 5}, + {"MaxBase", Const, 0}, + {"MaxExp", Const, 5}, + {"MaxPrec", Const, 5}, + {"MinExp", Const, 5}, + {"NewFloat", Func, 5}, + {"NewInt", Func, 0}, + {"NewRat", Func, 0}, + {"ParseFloat", Func, 5}, + {"Rat", Type, 0}, + {"RoundingMode", Type, 5}, + {"ToNearestAway", Const, 5}, + {"ToNearestEven", Const, 5}, + {"ToNegativeInf", Const, 5}, + {"ToPositiveInf", Const, 5}, + {"ToZero", Const, 5}, + {"Word", Type, 0}, + }, + "math/bits": { + {"Add", Func, 12}, + {"Add32", Func, 12}, + {"Add64", Func, 12}, + {"Div", Func, 12}, + {"Div32", Func, 12}, + {"Div64", Func, 12}, + {"LeadingZeros", Func, 9}, + {"LeadingZeros16", Func, 9}, + {"LeadingZeros32", Func, 9}, + {"LeadingZeros64", Func, 9}, + {"LeadingZeros8", Func, 9}, + {"Len", Func, 9}, + {"Len16", Func, 9}, + {"Len32", Func, 9}, + {"Len64", Func, 9}, + {"Len8", Func, 9}, + {"Mul", Func, 12}, + {"Mul32", Func, 12}, + {"Mul64", Func, 12}, + {"OnesCount", Func, 9}, + {"OnesCount16", Func, 9}, + {"OnesCount32", Func, 9}, + {"OnesCount64", Func, 9}, + {"OnesCount8", Func, 9}, + {"Rem", Func, 14}, + {"Rem32", Func, 14}, + {"Rem64", Func, 14}, + {"Reverse", Func, 9}, + {"Reverse16", Func, 9}, + {"Reverse32", Func, 9}, + {"Reverse64", Func, 9}, + {"Reverse8", Func, 9}, + {"ReverseBytes", Func, 9}, + {"ReverseBytes16", Func, 9}, + {"ReverseBytes32", Func, 9}, + {"ReverseBytes64", Func, 9}, + {"RotateLeft", Func, 9}, + {"RotateLeft16", Func, 9}, + {"RotateLeft32", Func, 9}, + {"RotateLeft64", Func, 9}, + {"RotateLeft8", Func, 9}, + {"Sub", Func, 12}, + {"Sub32", Func, 12}, + {"Sub64", Func, 12}, + {"TrailingZeros", Func, 9}, + {"TrailingZeros16", Func, 9}, + {"TrailingZeros32", Func, 9}, + {"TrailingZeros64", Func, 9}, + {"TrailingZeros8", Func, 9}, + {"UintSize", Const, 9}, + }, + "math/cmplx": { + {"Abs", Func, 0}, + {"Acos", Func, 0}, + {"Acosh", Func, 0}, + {"Asin", Func, 0}, + {"Asinh", Func, 0}, + {"Atan", Func, 0}, + {"Atanh", Func, 0}, + {"Conj", Func, 0}, + {"Cos", Func, 0}, + {"Cosh", Func, 0}, + {"Cot", Func, 0}, + {"Exp", Func, 0}, + {"Inf", Func, 0}, + {"IsInf", Func, 0}, + {"IsNaN", Func, 0}, + {"Log", Func, 0}, + {"Log10", Func, 0}, + {"NaN", Func, 0}, + {"Phase", Func, 0}, + {"Polar", Func, 0}, + {"Pow", Func, 0}, + {"Rect", Func, 0}, + {"Sin", Func, 0}, + {"Sinh", Func, 0}, + {"Sqrt", Func, 0}, + {"Tan", Func, 0}, + {"Tanh", Func, 0}, + }, + "math/rand": { + {"(*Rand).ExpFloat64", Method, 0}, + {"(*Rand).Float32", Method, 0}, + {"(*Rand).Float64", Method, 0}, + {"(*Rand).Int", Method, 0}, + {"(*Rand).Int31", Method, 0}, + {"(*Rand).Int31n", Method, 0}, + {"(*Rand).Int63", Method, 0}, + {"(*Rand).Int63n", Method, 0}, + {"(*Rand).Intn", Method, 0}, + {"(*Rand).NormFloat64", Method, 0}, + {"(*Rand).Perm", Method, 0}, + {"(*Rand).Read", Method, 6}, + {"(*Rand).Seed", Method, 0}, + {"(*Rand).Shuffle", Method, 10}, + {"(*Rand).Uint32", Method, 0}, + {"(*Rand).Uint64", Method, 8}, + {"(*Zipf).Uint64", Method, 0}, + {"ExpFloat64", Func, 0}, + {"Float32", Func, 0}, + {"Float64", Func, 0}, + {"Int", Func, 0}, + {"Int31", Func, 0}, + {"Int31n", Func, 0}, + {"Int63", Func, 0}, + {"Int63n", Func, 0}, + {"Intn", Func, 0}, + {"New", Func, 0}, + {"NewSource", Func, 0}, + {"NewZipf", Func, 0}, + {"NormFloat64", Func, 0}, + {"Perm", Func, 0}, + {"Rand", Type, 0}, + {"Read", Func, 6}, + {"Seed", Func, 0}, + {"Shuffle", Func, 10}, + {"Source", Type, 0}, + {"Source64", Type, 8}, + {"Uint32", Func, 0}, + {"Uint64", Func, 8}, + {"Zipf", Type, 0}, + }, + "math/rand/v2": { + {"(*ChaCha8).MarshalBinary", Method, 22}, + {"(*ChaCha8).Read", Method, 23}, + {"(*ChaCha8).Seed", Method, 22}, + {"(*ChaCha8).Uint64", Method, 22}, + {"(*ChaCha8).UnmarshalBinary", Method, 22}, + {"(*PCG).MarshalBinary", Method, 22}, + {"(*PCG).Seed", Method, 22}, + {"(*PCG).Uint64", Method, 22}, + {"(*PCG).UnmarshalBinary", Method, 22}, + {"(*Rand).ExpFloat64", Method, 22}, + {"(*Rand).Float32", Method, 22}, + {"(*Rand).Float64", Method, 22}, + {"(*Rand).Int", Method, 22}, + {"(*Rand).Int32", Method, 22}, + {"(*Rand).Int32N", Method, 22}, + {"(*Rand).Int64", Method, 22}, + {"(*Rand).Int64N", Method, 22}, + {"(*Rand).IntN", Method, 22}, + {"(*Rand).NormFloat64", Method, 22}, + {"(*Rand).Perm", Method, 22}, + {"(*Rand).Shuffle", Method, 22}, + {"(*Rand).Uint", Method, 23}, + {"(*Rand).Uint32", Method, 22}, + {"(*Rand).Uint32N", Method, 22}, + {"(*Rand).Uint64", Method, 22}, + {"(*Rand).Uint64N", Method, 22}, + {"(*Rand).UintN", Method, 22}, + {"(*Zipf).Uint64", Method, 22}, + {"ChaCha8", Type, 22}, + {"ExpFloat64", Func, 22}, + {"Float32", Func, 22}, + {"Float64", Func, 22}, + {"Int", Func, 22}, + {"Int32", Func, 22}, + {"Int32N", Func, 22}, + {"Int64", Func, 22}, + {"Int64N", Func, 22}, + {"IntN", Func, 22}, + {"N", Func, 22}, + {"New", Func, 22}, + {"NewChaCha8", Func, 22}, + {"NewPCG", Func, 22}, + {"NewZipf", Func, 22}, + {"NormFloat64", Func, 22}, + {"PCG", Type, 22}, + {"Perm", Func, 22}, + {"Rand", Type, 22}, + {"Shuffle", Func, 22}, + {"Source", Type, 22}, + {"Uint", Func, 23}, + {"Uint32", Func, 22}, + {"Uint32N", Func, 22}, + {"Uint64", Func, 22}, + {"Uint64N", Func, 22}, + {"UintN", Func, 22}, + {"Zipf", Type, 22}, + }, + "mime": { + {"(*WordDecoder).Decode", Method, 5}, + {"(*WordDecoder).DecodeHeader", Method, 5}, + {"(WordEncoder).Encode", Method, 5}, + {"AddExtensionType", Func, 0}, + {"BEncoding", Const, 5}, + {"ErrInvalidMediaParameter", Var, 9}, + {"ExtensionsByType", Func, 5}, + {"FormatMediaType", Func, 0}, + {"ParseMediaType", Func, 0}, + {"QEncoding", Const, 5}, + {"TypeByExtension", Func, 0}, + {"WordDecoder", Type, 5}, + {"WordDecoder.CharsetReader", Field, 5}, + {"WordEncoder", Type, 5}, + }, + "mime/multipart": { + {"(*FileHeader).Open", Method, 0}, + {"(*Form).RemoveAll", Method, 0}, + {"(*Part).Close", Method, 0}, + {"(*Part).FileName", Method, 0}, + {"(*Part).FormName", Method, 0}, + {"(*Part).Read", Method, 0}, + {"(*Reader).NextPart", Method, 0}, + {"(*Reader).NextRawPart", Method, 14}, + {"(*Reader).ReadForm", Method, 0}, + {"(*Writer).Boundary", Method, 0}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).CreateFormField", Method, 0}, + {"(*Writer).CreateFormFile", Method, 0}, + {"(*Writer).CreatePart", Method, 0}, + {"(*Writer).FormDataContentType", Method, 0}, + {"(*Writer).SetBoundary", Method, 1}, + {"(*Writer).WriteField", Method, 0}, + {"ErrMessageTooLarge", Var, 9}, + {"File", Type, 0}, + {"FileHeader", Type, 0}, + {"FileHeader.Filename", Field, 0}, + {"FileHeader.Header", Field, 0}, + {"FileHeader.Size", Field, 9}, + {"Form", Type, 0}, + {"Form.File", Field, 0}, + {"Form.Value", Field, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"Part", Type, 0}, + {"Part.Header", Field, 0}, + {"Reader", Type, 0}, + {"Writer", Type, 0}, + }, + "mime/quotedprintable": { + {"(*Reader).Read", Method, 5}, + {"(*Writer).Close", Method, 5}, + {"(*Writer).Write", Method, 5}, + {"NewReader", Func, 5}, + {"NewWriter", Func, 5}, + {"Reader", Type, 5}, + {"Writer", Type, 5}, + {"Writer.Binary", Field, 5}, + }, + "net": { + {"(*AddrError).Error", Method, 0}, + {"(*AddrError).Temporary", Method, 0}, + {"(*AddrError).Timeout", Method, 0}, + {"(*Buffers).Read", Method, 8}, + {"(*Buffers).WriteTo", Method, 8}, + {"(*DNSConfigError).Error", Method, 0}, + {"(*DNSConfigError).Temporary", Method, 0}, + {"(*DNSConfigError).Timeout", Method, 0}, + {"(*DNSConfigError).Unwrap", Method, 13}, + {"(*DNSError).Error", Method, 0}, + {"(*DNSError).Temporary", Method, 0}, + {"(*DNSError).Timeout", Method, 0}, + {"(*DNSError).Unwrap", Method, 23}, + {"(*Dialer).Dial", Method, 1}, + {"(*Dialer).DialContext", Method, 7}, + {"(*Dialer).MultipathTCP", Method, 21}, + {"(*Dialer).SetMultipathTCP", Method, 21}, + {"(*IP).UnmarshalText", Method, 2}, + {"(*IPAddr).Network", Method, 0}, + {"(*IPAddr).String", Method, 0}, + {"(*IPConn).Close", Method, 0}, + {"(*IPConn).File", Method, 0}, + {"(*IPConn).LocalAddr", Method, 0}, + {"(*IPConn).Read", Method, 0}, + {"(*IPConn).ReadFrom", Method, 0}, + {"(*IPConn).ReadFromIP", Method, 0}, + {"(*IPConn).ReadMsgIP", Method, 1}, + {"(*IPConn).RemoteAddr", Method, 0}, + {"(*IPConn).SetDeadline", Method, 0}, + {"(*IPConn).SetReadBuffer", Method, 0}, + {"(*IPConn).SetReadDeadline", Method, 0}, + {"(*IPConn).SetWriteBuffer", Method, 0}, + {"(*IPConn).SetWriteDeadline", Method, 0}, + {"(*IPConn).SyscallConn", Method, 9}, + {"(*IPConn).Write", Method, 0}, + {"(*IPConn).WriteMsgIP", Method, 1}, + {"(*IPConn).WriteTo", Method, 0}, + {"(*IPConn).WriteToIP", Method, 0}, + {"(*IPNet).Contains", Method, 0}, + {"(*IPNet).Network", Method, 0}, + {"(*IPNet).String", Method, 0}, + {"(*Interface).Addrs", Method, 0}, + {"(*Interface).MulticastAddrs", Method, 0}, + {"(*ListenConfig).Listen", Method, 11}, + {"(*ListenConfig).ListenPacket", Method, 11}, + {"(*ListenConfig).MultipathTCP", Method, 21}, + {"(*ListenConfig).SetMultipathTCP", Method, 21}, + {"(*OpError).Error", Method, 0}, + {"(*OpError).Temporary", Method, 0}, + {"(*OpError).Timeout", Method, 0}, + {"(*OpError).Unwrap", Method, 13}, + {"(*ParseError).Error", Method, 0}, + {"(*ParseError).Temporary", Method, 17}, + {"(*ParseError).Timeout", Method, 17}, + {"(*Resolver).LookupAddr", Method, 8}, + {"(*Resolver).LookupCNAME", Method, 8}, + {"(*Resolver).LookupHost", Method, 8}, + {"(*Resolver).LookupIP", Method, 15}, + {"(*Resolver).LookupIPAddr", Method, 8}, + {"(*Resolver).LookupMX", Method, 8}, + {"(*Resolver).LookupNS", Method, 8}, + {"(*Resolver).LookupNetIP", Method, 18}, + {"(*Resolver).LookupPort", Method, 8}, + {"(*Resolver).LookupSRV", Method, 8}, + {"(*Resolver).LookupTXT", Method, 8}, + {"(*TCPAddr).AddrPort", Method, 18}, + {"(*TCPAddr).Network", Method, 0}, + {"(*TCPAddr).String", Method, 0}, + {"(*TCPConn).Close", Method, 0}, + {"(*TCPConn).CloseRead", Method, 0}, + {"(*TCPConn).CloseWrite", Method, 0}, + {"(*TCPConn).File", Method, 0}, + {"(*TCPConn).LocalAddr", Method, 0}, + {"(*TCPConn).MultipathTCP", Method, 21}, + {"(*TCPConn).Read", Method, 0}, + {"(*TCPConn).ReadFrom", Method, 0}, + {"(*TCPConn).RemoteAddr", Method, 0}, + {"(*TCPConn).SetDeadline", Method, 0}, + {"(*TCPConn).SetKeepAlive", Method, 0}, + {"(*TCPConn).SetKeepAliveConfig", Method, 23}, + {"(*TCPConn).SetKeepAlivePeriod", Method, 2}, + {"(*TCPConn).SetLinger", Method, 0}, + {"(*TCPConn).SetNoDelay", Method, 0}, + {"(*TCPConn).SetReadBuffer", Method, 0}, + {"(*TCPConn).SetReadDeadline", Method, 0}, + {"(*TCPConn).SetWriteBuffer", Method, 0}, + {"(*TCPConn).SetWriteDeadline", Method, 0}, + {"(*TCPConn).SyscallConn", Method, 9}, + {"(*TCPConn).Write", Method, 0}, + {"(*TCPConn).WriteTo", Method, 22}, + {"(*TCPListener).Accept", Method, 0}, + {"(*TCPListener).AcceptTCP", Method, 0}, + {"(*TCPListener).Addr", Method, 0}, + {"(*TCPListener).Close", Method, 0}, + {"(*TCPListener).File", Method, 0}, + {"(*TCPListener).SetDeadline", Method, 0}, + {"(*TCPListener).SyscallConn", Method, 10}, + {"(*UDPAddr).AddrPort", Method, 18}, + {"(*UDPAddr).Network", Method, 0}, + {"(*UDPAddr).String", Method, 0}, + {"(*UDPConn).Close", Method, 0}, + {"(*UDPConn).File", Method, 0}, + {"(*UDPConn).LocalAddr", Method, 0}, + {"(*UDPConn).Read", Method, 0}, + {"(*UDPConn).ReadFrom", Method, 0}, + {"(*UDPConn).ReadFromUDP", Method, 0}, + {"(*UDPConn).ReadFromUDPAddrPort", Method, 18}, + {"(*UDPConn).ReadMsgUDP", Method, 1}, + {"(*UDPConn).ReadMsgUDPAddrPort", Method, 18}, + {"(*UDPConn).RemoteAddr", Method, 0}, + {"(*UDPConn).SetDeadline", Method, 0}, + {"(*UDPConn).SetReadBuffer", Method, 0}, + {"(*UDPConn).SetReadDeadline", Method, 0}, + {"(*UDPConn).SetWriteBuffer", Method, 0}, + {"(*UDPConn).SetWriteDeadline", Method, 0}, + {"(*UDPConn).SyscallConn", Method, 9}, + {"(*UDPConn).Write", Method, 0}, + {"(*UDPConn).WriteMsgUDP", Method, 1}, + {"(*UDPConn).WriteMsgUDPAddrPort", Method, 18}, + {"(*UDPConn).WriteTo", Method, 0}, + {"(*UDPConn).WriteToUDP", Method, 0}, + {"(*UDPConn).WriteToUDPAddrPort", Method, 18}, + {"(*UnixAddr).Network", Method, 0}, + {"(*UnixAddr).String", Method, 0}, + {"(*UnixConn).Close", Method, 0}, + {"(*UnixConn).CloseRead", Method, 1}, + {"(*UnixConn).CloseWrite", Method, 1}, + {"(*UnixConn).File", Method, 0}, + {"(*UnixConn).LocalAddr", Method, 0}, + {"(*UnixConn).Read", Method, 0}, + {"(*UnixConn).ReadFrom", Method, 0}, + {"(*UnixConn).ReadFromUnix", Method, 0}, + {"(*UnixConn).ReadMsgUnix", Method, 0}, + {"(*UnixConn).RemoteAddr", Method, 0}, + {"(*UnixConn).SetDeadline", Method, 0}, + {"(*UnixConn).SetReadBuffer", Method, 0}, + {"(*UnixConn).SetReadDeadline", Method, 0}, + {"(*UnixConn).SetWriteBuffer", Method, 0}, + {"(*UnixConn).SetWriteDeadline", Method, 0}, + {"(*UnixConn).SyscallConn", Method, 9}, + {"(*UnixConn).Write", Method, 0}, + {"(*UnixConn).WriteMsgUnix", Method, 0}, + {"(*UnixConn).WriteTo", Method, 0}, + {"(*UnixConn).WriteToUnix", Method, 0}, + {"(*UnixListener).Accept", Method, 0}, + {"(*UnixListener).AcceptUnix", Method, 0}, + {"(*UnixListener).Addr", Method, 0}, + {"(*UnixListener).Close", Method, 0}, + {"(*UnixListener).File", Method, 0}, + {"(*UnixListener).SetDeadline", Method, 0}, + {"(*UnixListener).SetUnlinkOnClose", Method, 8}, + {"(*UnixListener).SyscallConn", Method, 10}, + {"(Flags).String", Method, 0}, + {"(HardwareAddr).String", Method, 0}, + {"(IP).DefaultMask", Method, 0}, + {"(IP).Equal", Method, 0}, + {"(IP).IsGlobalUnicast", Method, 0}, + {"(IP).IsInterfaceLocalMulticast", Method, 0}, + {"(IP).IsLinkLocalMulticast", Method, 0}, + {"(IP).IsLinkLocalUnicast", Method, 0}, + {"(IP).IsLoopback", Method, 0}, + {"(IP).IsMulticast", Method, 0}, + {"(IP).IsPrivate", Method, 17}, + {"(IP).IsUnspecified", Method, 0}, + {"(IP).MarshalText", Method, 2}, + {"(IP).Mask", Method, 0}, + {"(IP).String", Method, 0}, + {"(IP).To16", Method, 0}, + {"(IP).To4", Method, 0}, + {"(IPMask).Size", Method, 0}, + {"(IPMask).String", Method, 0}, + {"(InvalidAddrError).Error", Method, 0}, + {"(InvalidAddrError).Temporary", Method, 0}, + {"(InvalidAddrError).Timeout", Method, 0}, + {"(UnknownNetworkError).Error", Method, 0}, + {"(UnknownNetworkError).Temporary", Method, 0}, + {"(UnknownNetworkError).Timeout", Method, 0}, + {"Addr", Type, 0}, + {"AddrError", Type, 0}, + {"AddrError.Addr", Field, 0}, + {"AddrError.Err", Field, 0}, + {"Buffers", Type, 8}, + {"CIDRMask", Func, 0}, + {"Conn", Type, 0}, + {"DNSConfigError", Type, 0}, + {"DNSConfigError.Err", Field, 0}, + {"DNSError", Type, 0}, + {"DNSError.Err", Field, 0}, + {"DNSError.IsNotFound", Field, 13}, + {"DNSError.IsTemporary", Field, 6}, + {"DNSError.IsTimeout", Field, 0}, + {"DNSError.Name", Field, 0}, + {"DNSError.Server", Field, 0}, + {"DNSError.UnwrapErr", Field, 23}, + {"DefaultResolver", Var, 8}, + {"Dial", Func, 0}, + {"DialIP", Func, 0}, + {"DialTCP", Func, 0}, + {"DialTimeout", Func, 0}, + {"DialUDP", Func, 0}, + {"DialUnix", Func, 0}, + {"Dialer", Type, 1}, + {"Dialer.Cancel", Field, 6}, + {"Dialer.Control", Field, 11}, + {"Dialer.ControlContext", Field, 20}, + {"Dialer.Deadline", Field, 1}, + {"Dialer.DualStack", Field, 2}, + {"Dialer.FallbackDelay", Field, 5}, + {"Dialer.KeepAlive", Field, 3}, + {"Dialer.KeepAliveConfig", Field, 23}, + {"Dialer.LocalAddr", Field, 1}, + {"Dialer.Resolver", Field, 8}, + {"Dialer.Timeout", Field, 1}, + {"ErrClosed", Var, 16}, + {"ErrWriteToConnected", Var, 0}, + {"Error", Type, 0}, + {"FileConn", Func, 0}, + {"FileListener", Func, 0}, + {"FilePacketConn", Func, 0}, + {"FlagBroadcast", Const, 0}, + {"FlagLoopback", Const, 0}, + {"FlagMulticast", Const, 0}, + {"FlagPointToPoint", Const, 0}, + {"FlagRunning", Const, 20}, + {"FlagUp", Const, 0}, + {"Flags", Type, 0}, + {"HardwareAddr", Type, 0}, + {"IP", Type, 0}, + {"IPAddr", Type, 0}, + {"IPAddr.IP", Field, 0}, + {"IPAddr.Zone", Field, 1}, + {"IPConn", Type, 0}, + {"IPMask", Type, 0}, + {"IPNet", Type, 0}, + {"IPNet.IP", Field, 0}, + {"IPNet.Mask", Field, 0}, + {"IPv4", Func, 0}, + {"IPv4Mask", Func, 0}, + {"IPv4allrouter", Var, 0}, + {"IPv4allsys", Var, 0}, + {"IPv4bcast", Var, 0}, + {"IPv4len", Const, 0}, + {"IPv4zero", Var, 0}, + {"IPv6interfacelocalallnodes", Var, 0}, + {"IPv6len", Const, 0}, + {"IPv6linklocalallnodes", Var, 0}, + {"IPv6linklocalallrouters", Var, 0}, + {"IPv6loopback", Var, 0}, + {"IPv6unspecified", Var, 0}, + {"IPv6zero", Var, 0}, + {"Interface", Type, 0}, + {"Interface.Flags", Field, 0}, + {"Interface.HardwareAddr", Field, 0}, + {"Interface.Index", Field, 0}, + {"Interface.MTU", Field, 0}, + {"Interface.Name", Field, 0}, + {"InterfaceAddrs", Func, 0}, + {"InterfaceByIndex", Func, 0}, + {"InterfaceByName", Func, 0}, + {"Interfaces", Func, 0}, + {"InvalidAddrError", Type, 0}, + {"JoinHostPort", Func, 0}, + {"KeepAliveConfig", Type, 23}, + {"KeepAliveConfig.Count", Field, 23}, + {"KeepAliveConfig.Enable", Field, 23}, + {"KeepAliveConfig.Idle", Field, 23}, + {"KeepAliveConfig.Interval", Field, 23}, + {"Listen", Func, 0}, + {"ListenConfig", Type, 11}, + {"ListenConfig.Control", Field, 11}, + {"ListenConfig.KeepAlive", Field, 13}, + {"ListenConfig.KeepAliveConfig", Field, 23}, + {"ListenIP", Func, 0}, + {"ListenMulticastUDP", Func, 0}, + {"ListenPacket", Func, 0}, + {"ListenTCP", Func, 0}, + {"ListenUDP", Func, 0}, + {"ListenUnix", Func, 0}, + {"ListenUnixgram", Func, 0}, + {"Listener", Type, 0}, + {"LookupAddr", Func, 0}, + {"LookupCNAME", Func, 0}, + {"LookupHost", Func, 0}, + {"LookupIP", Func, 0}, + {"LookupMX", Func, 0}, + {"LookupNS", Func, 1}, + {"LookupPort", Func, 0}, + {"LookupSRV", Func, 0}, + {"LookupTXT", Func, 0}, + {"MX", Type, 0}, + {"MX.Host", Field, 0}, + {"MX.Pref", Field, 0}, + {"NS", Type, 1}, + {"NS.Host", Field, 1}, + {"OpError", Type, 0}, + {"OpError.Addr", Field, 0}, + {"OpError.Err", Field, 0}, + {"OpError.Net", Field, 0}, + {"OpError.Op", Field, 0}, + {"OpError.Source", Field, 5}, + {"PacketConn", Type, 0}, + {"ParseCIDR", Func, 0}, + {"ParseError", Type, 0}, + {"ParseError.Text", Field, 0}, + {"ParseError.Type", Field, 0}, + {"ParseIP", Func, 0}, + {"ParseMAC", Func, 0}, + {"Pipe", Func, 0}, + {"ResolveIPAddr", Func, 0}, + {"ResolveTCPAddr", Func, 0}, + {"ResolveUDPAddr", Func, 0}, + {"ResolveUnixAddr", Func, 0}, + {"Resolver", Type, 8}, + {"Resolver.Dial", Field, 9}, + {"Resolver.PreferGo", Field, 8}, + {"Resolver.StrictErrors", Field, 9}, + {"SRV", Type, 0}, + {"SRV.Port", Field, 0}, + {"SRV.Priority", Field, 0}, + {"SRV.Target", Field, 0}, + {"SRV.Weight", Field, 0}, + {"SplitHostPort", Func, 0}, + {"TCPAddr", Type, 0}, + {"TCPAddr.IP", Field, 0}, + {"TCPAddr.Port", Field, 0}, + {"TCPAddr.Zone", Field, 1}, + {"TCPAddrFromAddrPort", Func, 18}, + {"TCPConn", Type, 0}, + {"TCPListener", Type, 0}, + {"UDPAddr", Type, 0}, + {"UDPAddr.IP", Field, 0}, + {"UDPAddr.Port", Field, 0}, + {"UDPAddr.Zone", Field, 1}, + {"UDPAddrFromAddrPort", Func, 18}, + {"UDPConn", Type, 0}, + {"UnixAddr", Type, 0}, + {"UnixAddr.Name", Field, 0}, + {"UnixAddr.Net", Field, 0}, + {"UnixConn", Type, 0}, + {"UnixListener", Type, 0}, + {"UnknownNetworkError", Type, 0}, + }, + "net/http": { + {"(*Client).CloseIdleConnections", Method, 12}, + {"(*Client).Do", Method, 0}, + {"(*Client).Get", Method, 0}, + {"(*Client).Head", Method, 0}, + {"(*Client).Post", Method, 0}, + {"(*Client).PostForm", Method, 0}, + {"(*Cookie).String", Method, 0}, + {"(*Cookie).Valid", Method, 18}, + {"(*MaxBytesError).Error", Method, 19}, + {"(*ProtocolError).Error", Method, 0}, + {"(*ProtocolError).Is", Method, 21}, + {"(*Request).AddCookie", Method, 0}, + {"(*Request).BasicAuth", Method, 4}, + {"(*Request).Clone", Method, 13}, + {"(*Request).Context", Method, 7}, + {"(*Request).Cookie", Method, 0}, + {"(*Request).Cookies", Method, 0}, + {"(*Request).CookiesNamed", Method, 23}, + {"(*Request).FormFile", Method, 0}, + {"(*Request).FormValue", Method, 0}, + {"(*Request).MultipartReader", Method, 0}, + {"(*Request).ParseForm", Method, 0}, + {"(*Request).ParseMultipartForm", Method, 0}, + {"(*Request).PathValue", Method, 22}, + {"(*Request).PostFormValue", Method, 1}, + {"(*Request).ProtoAtLeast", Method, 0}, + {"(*Request).Referer", Method, 0}, + {"(*Request).SetBasicAuth", Method, 0}, + {"(*Request).SetPathValue", Method, 22}, + {"(*Request).UserAgent", Method, 0}, + {"(*Request).WithContext", Method, 7}, + {"(*Request).Write", Method, 0}, + {"(*Request).WriteProxy", Method, 0}, + {"(*Response).Cookies", Method, 0}, + {"(*Response).Location", Method, 0}, + {"(*Response).ProtoAtLeast", Method, 0}, + {"(*Response).Write", Method, 0}, + {"(*ResponseController).EnableFullDuplex", Method, 21}, + {"(*ResponseController).Flush", Method, 20}, + {"(*ResponseController).Hijack", Method, 20}, + {"(*ResponseController).SetReadDeadline", Method, 20}, + {"(*ResponseController).SetWriteDeadline", Method, 20}, + {"(*ServeMux).Handle", Method, 0}, + {"(*ServeMux).HandleFunc", Method, 0}, + {"(*ServeMux).Handler", Method, 1}, + {"(*ServeMux).ServeHTTP", Method, 0}, + {"(*Server).Close", Method, 8}, + {"(*Server).ListenAndServe", Method, 0}, + {"(*Server).ListenAndServeTLS", Method, 0}, + {"(*Server).RegisterOnShutdown", Method, 9}, + {"(*Server).Serve", Method, 0}, + {"(*Server).ServeTLS", Method, 9}, + {"(*Server).SetKeepAlivesEnabled", Method, 3}, + {"(*Server).Shutdown", Method, 8}, + {"(*Transport).CancelRequest", Method, 1}, + {"(*Transport).Clone", Method, 13}, + {"(*Transport).CloseIdleConnections", Method, 0}, + {"(*Transport).RegisterProtocol", Method, 0}, + {"(*Transport).RoundTrip", Method, 0}, + {"(ConnState).String", Method, 3}, + {"(Dir).Open", Method, 0}, + {"(HandlerFunc).ServeHTTP", Method, 0}, + {"(Header).Add", Method, 0}, + {"(Header).Clone", Method, 13}, + {"(Header).Del", Method, 0}, + {"(Header).Get", Method, 0}, + {"(Header).Set", Method, 0}, + {"(Header).Values", Method, 14}, + {"(Header).Write", Method, 0}, + {"(Header).WriteSubset", Method, 0}, + {"AllowQuerySemicolons", Func, 17}, + {"CanonicalHeaderKey", Func, 0}, + {"Client", Type, 0}, + {"Client.CheckRedirect", Field, 0}, + {"Client.Jar", Field, 0}, + {"Client.Timeout", Field, 3}, + {"Client.Transport", Field, 0}, + {"CloseNotifier", Type, 1}, + {"ConnState", Type, 3}, + {"Cookie", Type, 0}, + {"Cookie.Domain", Field, 0}, + {"Cookie.Expires", Field, 0}, + {"Cookie.HttpOnly", Field, 0}, + {"Cookie.MaxAge", Field, 0}, + {"Cookie.Name", Field, 0}, + {"Cookie.Partitioned", Field, 23}, + {"Cookie.Path", Field, 0}, + {"Cookie.Quoted", Field, 23}, + {"Cookie.Raw", Field, 0}, + {"Cookie.RawExpires", Field, 0}, + {"Cookie.SameSite", Field, 11}, + {"Cookie.Secure", Field, 0}, + {"Cookie.Unparsed", Field, 0}, + {"Cookie.Value", Field, 0}, + {"CookieJar", Type, 0}, + {"DefaultClient", Var, 0}, + {"DefaultMaxHeaderBytes", Const, 0}, + {"DefaultMaxIdleConnsPerHost", Const, 0}, + {"DefaultServeMux", Var, 0}, + {"DefaultTransport", Var, 0}, + {"DetectContentType", Func, 0}, + {"Dir", Type, 0}, + {"ErrAbortHandler", Var, 8}, + {"ErrBodyNotAllowed", Var, 0}, + {"ErrBodyReadAfterClose", Var, 0}, + {"ErrContentLength", Var, 0}, + {"ErrHandlerTimeout", Var, 0}, + {"ErrHeaderTooLong", Var, 0}, + {"ErrHijacked", Var, 0}, + {"ErrLineTooLong", Var, 0}, + {"ErrMissingBoundary", Var, 0}, + {"ErrMissingContentLength", Var, 0}, + {"ErrMissingFile", Var, 0}, + {"ErrNoCookie", Var, 0}, + {"ErrNoLocation", Var, 0}, + {"ErrNotMultipart", Var, 0}, + {"ErrNotSupported", Var, 0}, + {"ErrSchemeMismatch", Var, 21}, + {"ErrServerClosed", Var, 8}, + {"ErrShortBody", Var, 0}, + {"ErrSkipAltProtocol", Var, 6}, + {"ErrUnexpectedTrailer", Var, 0}, + {"ErrUseLastResponse", Var, 7}, + {"ErrWriteAfterFlush", Var, 0}, + {"Error", Func, 0}, + {"FS", Func, 16}, + {"File", Type, 0}, + {"FileServer", Func, 0}, + {"FileServerFS", Func, 22}, + {"FileSystem", Type, 0}, + {"Flusher", Type, 0}, + {"Get", Func, 0}, + {"Handle", Func, 0}, + {"HandleFunc", Func, 0}, + {"Handler", Type, 0}, + {"HandlerFunc", Type, 0}, + {"Head", Func, 0}, + {"Header", Type, 0}, + {"Hijacker", Type, 0}, + {"ListenAndServe", Func, 0}, + {"ListenAndServeTLS", Func, 0}, + {"LocalAddrContextKey", Var, 7}, + {"MaxBytesError", Type, 19}, + {"MaxBytesError.Limit", Field, 19}, + {"MaxBytesHandler", Func, 18}, + {"MaxBytesReader", Func, 0}, + {"MethodConnect", Const, 6}, + {"MethodDelete", Const, 6}, + {"MethodGet", Const, 6}, + {"MethodHead", Const, 6}, + {"MethodOptions", Const, 6}, + {"MethodPatch", Const, 6}, + {"MethodPost", Const, 6}, + {"MethodPut", Const, 6}, + {"MethodTrace", Const, 6}, + {"NewFileTransport", Func, 0}, + {"NewFileTransportFS", Func, 22}, + {"NewRequest", Func, 0}, + {"NewRequestWithContext", Func, 13}, + {"NewResponseController", Func, 20}, + {"NewServeMux", Func, 0}, + {"NoBody", Var, 8}, + {"NotFound", Func, 0}, + {"NotFoundHandler", Func, 0}, + {"ParseCookie", Func, 23}, + {"ParseHTTPVersion", Func, 0}, + {"ParseSetCookie", Func, 23}, + {"ParseTime", Func, 1}, + {"Post", Func, 0}, + {"PostForm", Func, 0}, + {"ProtocolError", Type, 0}, + {"ProtocolError.ErrorString", Field, 0}, + {"ProxyFromEnvironment", Func, 0}, + {"ProxyURL", Func, 0}, + {"PushOptions", Type, 8}, + {"PushOptions.Header", Field, 8}, + {"PushOptions.Method", Field, 8}, + {"Pusher", Type, 8}, + {"ReadRequest", Func, 0}, + {"ReadResponse", Func, 0}, + {"Redirect", Func, 0}, + {"RedirectHandler", Func, 0}, + {"Request", Type, 0}, + {"Request.Body", Field, 0}, + {"Request.Cancel", Field, 5}, + {"Request.Close", Field, 0}, + {"Request.ContentLength", Field, 0}, + {"Request.Form", Field, 0}, + {"Request.GetBody", Field, 8}, + {"Request.Header", Field, 0}, + {"Request.Host", Field, 0}, + {"Request.Method", Field, 0}, + {"Request.MultipartForm", Field, 0}, + {"Request.Pattern", Field, 23}, + {"Request.PostForm", Field, 1}, + {"Request.Proto", Field, 0}, + {"Request.ProtoMajor", Field, 0}, + {"Request.ProtoMinor", Field, 0}, + {"Request.RemoteAddr", Field, 0}, + {"Request.RequestURI", Field, 0}, + {"Request.Response", Field, 7}, + {"Request.TLS", Field, 0}, + {"Request.Trailer", Field, 0}, + {"Request.TransferEncoding", Field, 0}, + {"Request.URL", Field, 0}, + {"Response", Type, 0}, + {"Response.Body", Field, 0}, + {"Response.Close", Field, 0}, + {"Response.ContentLength", Field, 0}, + {"Response.Header", Field, 0}, + {"Response.Proto", Field, 0}, + {"Response.ProtoMajor", Field, 0}, + {"Response.ProtoMinor", Field, 0}, + {"Response.Request", Field, 0}, + {"Response.Status", Field, 0}, + {"Response.StatusCode", Field, 0}, + {"Response.TLS", Field, 3}, + {"Response.Trailer", Field, 0}, + {"Response.TransferEncoding", Field, 0}, + {"Response.Uncompressed", Field, 7}, + {"ResponseController", Type, 20}, + {"ResponseWriter", Type, 0}, + {"RoundTripper", Type, 0}, + {"SameSite", Type, 11}, + {"SameSiteDefaultMode", Const, 11}, + {"SameSiteLaxMode", Const, 11}, + {"SameSiteNoneMode", Const, 13}, + {"SameSiteStrictMode", Const, 11}, + {"Serve", Func, 0}, + {"ServeContent", Func, 0}, + {"ServeFile", Func, 0}, + {"ServeFileFS", Func, 22}, + {"ServeMux", Type, 0}, + {"ServeTLS", Func, 9}, + {"Server", Type, 0}, + {"Server.Addr", Field, 0}, + {"Server.BaseContext", Field, 13}, + {"Server.ConnContext", Field, 13}, + {"Server.ConnState", Field, 3}, + {"Server.DisableGeneralOptionsHandler", Field, 20}, + {"Server.ErrorLog", Field, 3}, + {"Server.Handler", Field, 0}, + {"Server.IdleTimeout", Field, 8}, + {"Server.MaxHeaderBytes", Field, 0}, + {"Server.ReadHeaderTimeout", Field, 8}, + {"Server.ReadTimeout", Field, 0}, + {"Server.TLSConfig", Field, 0}, + {"Server.TLSNextProto", Field, 1}, + {"Server.WriteTimeout", Field, 0}, + {"ServerContextKey", Var, 7}, + {"SetCookie", Func, 0}, + {"StateActive", Const, 3}, + {"StateClosed", Const, 3}, + {"StateHijacked", Const, 3}, + {"StateIdle", Const, 3}, + {"StateNew", Const, 3}, + {"StatusAccepted", Const, 0}, + {"StatusAlreadyReported", Const, 7}, + {"StatusBadGateway", Const, 0}, + {"StatusBadRequest", Const, 0}, + {"StatusConflict", Const, 0}, + {"StatusContinue", Const, 0}, + {"StatusCreated", Const, 0}, + {"StatusEarlyHints", Const, 13}, + {"StatusExpectationFailed", Const, 0}, + {"StatusFailedDependency", Const, 7}, + {"StatusForbidden", Const, 0}, + {"StatusFound", Const, 0}, + {"StatusGatewayTimeout", Const, 0}, + {"StatusGone", Const, 0}, + {"StatusHTTPVersionNotSupported", Const, 0}, + {"StatusIMUsed", Const, 7}, + {"StatusInsufficientStorage", Const, 7}, + {"StatusInternalServerError", Const, 0}, + {"StatusLengthRequired", Const, 0}, + {"StatusLocked", Const, 7}, + {"StatusLoopDetected", Const, 7}, + {"StatusMethodNotAllowed", Const, 0}, + {"StatusMisdirectedRequest", Const, 11}, + {"StatusMovedPermanently", Const, 0}, + {"StatusMultiStatus", Const, 7}, + {"StatusMultipleChoices", Const, 0}, + {"StatusNetworkAuthenticationRequired", Const, 6}, + {"StatusNoContent", Const, 0}, + {"StatusNonAuthoritativeInfo", Const, 0}, + {"StatusNotAcceptable", Const, 0}, + {"StatusNotExtended", Const, 7}, + {"StatusNotFound", Const, 0}, + {"StatusNotImplemented", Const, 0}, + {"StatusNotModified", Const, 0}, + {"StatusOK", Const, 0}, + {"StatusPartialContent", Const, 0}, + {"StatusPaymentRequired", Const, 0}, + {"StatusPermanentRedirect", Const, 7}, + {"StatusPreconditionFailed", Const, 0}, + {"StatusPreconditionRequired", Const, 6}, + {"StatusProcessing", Const, 7}, + {"StatusProxyAuthRequired", Const, 0}, + {"StatusRequestEntityTooLarge", Const, 0}, + {"StatusRequestHeaderFieldsTooLarge", Const, 6}, + {"StatusRequestTimeout", Const, 0}, + {"StatusRequestURITooLong", Const, 0}, + {"StatusRequestedRangeNotSatisfiable", Const, 0}, + {"StatusResetContent", Const, 0}, + {"StatusSeeOther", Const, 0}, + {"StatusServiceUnavailable", Const, 0}, + {"StatusSwitchingProtocols", Const, 0}, + {"StatusTeapot", Const, 0}, + {"StatusTemporaryRedirect", Const, 0}, + {"StatusText", Func, 0}, + {"StatusTooEarly", Const, 12}, + {"StatusTooManyRequests", Const, 6}, + {"StatusUnauthorized", Const, 0}, + {"StatusUnavailableForLegalReasons", Const, 6}, + {"StatusUnprocessableEntity", Const, 7}, + {"StatusUnsupportedMediaType", Const, 0}, + {"StatusUpgradeRequired", Const, 7}, + {"StatusUseProxy", Const, 0}, + {"StatusVariantAlsoNegotiates", Const, 7}, + {"StripPrefix", Func, 0}, + {"TimeFormat", Const, 0}, + {"TimeoutHandler", Func, 0}, + {"TrailerPrefix", Const, 8}, + {"Transport", Type, 0}, + {"Transport.Dial", Field, 0}, + {"Transport.DialContext", Field, 7}, + {"Transport.DialTLS", Field, 4}, + {"Transport.DialTLSContext", Field, 14}, + {"Transport.DisableCompression", Field, 0}, + {"Transport.DisableKeepAlives", Field, 0}, + {"Transport.ExpectContinueTimeout", Field, 6}, + {"Transport.ForceAttemptHTTP2", Field, 13}, + {"Transport.GetProxyConnectHeader", Field, 16}, + {"Transport.IdleConnTimeout", Field, 7}, + {"Transport.MaxConnsPerHost", Field, 11}, + {"Transport.MaxIdleConns", Field, 7}, + {"Transport.MaxIdleConnsPerHost", Field, 0}, + {"Transport.MaxResponseHeaderBytes", Field, 7}, + {"Transport.OnProxyConnectResponse", Field, 20}, + {"Transport.Proxy", Field, 0}, + {"Transport.ProxyConnectHeader", Field, 8}, + {"Transport.ReadBufferSize", Field, 13}, + {"Transport.ResponseHeaderTimeout", Field, 1}, + {"Transport.TLSClientConfig", Field, 0}, + {"Transport.TLSHandshakeTimeout", Field, 3}, + {"Transport.TLSNextProto", Field, 6}, + {"Transport.WriteBufferSize", Field, 13}, + }, + "net/http/cgi": { + {"(*Handler).ServeHTTP", Method, 0}, + {"Handler", Type, 0}, + {"Handler.Args", Field, 0}, + {"Handler.Dir", Field, 0}, + {"Handler.Env", Field, 0}, + {"Handler.InheritEnv", Field, 0}, + {"Handler.Logger", Field, 0}, + {"Handler.Path", Field, 0}, + {"Handler.PathLocationHandler", Field, 0}, + {"Handler.Root", Field, 0}, + {"Handler.Stderr", Field, 7}, + {"Request", Func, 0}, + {"RequestFromMap", Func, 0}, + {"Serve", Func, 0}, + }, + "net/http/cookiejar": { + {"(*Jar).Cookies", Method, 1}, + {"(*Jar).SetCookies", Method, 1}, + {"Jar", Type, 1}, + {"New", Func, 1}, + {"Options", Type, 1}, + {"Options.PublicSuffixList", Field, 1}, + {"PublicSuffixList", Type, 1}, + }, + "net/http/fcgi": { + {"ErrConnClosed", Var, 5}, + {"ErrRequestAborted", Var, 5}, + {"ProcessEnv", Func, 9}, + {"Serve", Func, 0}, + }, + "net/http/httptest": { + {"(*ResponseRecorder).Flush", Method, 0}, + {"(*ResponseRecorder).Header", Method, 0}, + {"(*ResponseRecorder).Result", Method, 7}, + {"(*ResponseRecorder).Write", Method, 0}, + {"(*ResponseRecorder).WriteHeader", Method, 0}, + {"(*ResponseRecorder).WriteString", Method, 6}, + {"(*Server).Certificate", Method, 9}, + {"(*Server).Client", Method, 9}, + {"(*Server).Close", Method, 0}, + {"(*Server).CloseClientConnections", Method, 0}, + {"(*Server).Start", Method, 0}, + {"(*Server).StartTLS", Method, 0}, + {"DefaultRemoteAddr", Const, 0}, + {"NewRecorder", Func, 0}, + {"NewRequest", Func, 7}, + {"NewRequestWithContext", Func, 23}, + {"NewServer", Func, 0}, + {"NewTLSServer", Func, 0}, + {"NewUnstartedServer", Func, 0}, + {"ResponseRecorder", Type, 0}, + {"ResponseRecorder.Body", Field, 0}, + {"ResponseRecorder.Code", Field, 0}, + {"ResponseRecorder.Flushed", Field, 0}, + {"ResponseRecorder.HeaderMap", Field, 0}, + {"Server", Type, 0}, + {"Server.Config", Field, 0}, + {"Server.EnableHTTP2", Field, 14}, + {"Server.Listener", Field, 0}, + {"Server.TLS", Field, 0}, + {"Server.URL", Field, 0}, + }, + "net/http/httptrace": { + {"ClientTrace", Type, 7}, + {"ClientTrace.ConnectDone", Field, 7}, + {"ClientTrace.ConnectStart", Field, 7}, + {"ClientTrace.DNSDone", Field, 7}, + {"ClientTrace.DNSStart", Field, 7}, + {"ClientTrace.GetConn", Field, 7}, + {"ClientTrace.Got100Continue", Field, 7}, + {"ClientTrace.Got1xxResponse", Field, 11}, + {"ClientTrace.GotConn", Field, 7}, + {"ClientTrace.GotFirstResponseByte", Field, 7}, + {"ClientTrace.PutIdleConn", Field, 7}, + {"ClientTrace.TLSHandshakeDone", Field, 8}, + {"ClientTrace.TLSHandshakeStart", Field, 8}, + {"ClientTrace.Wait100Continue", Field, 7}, + {"ClientTrace.WroteHeaderField", Field, 11}, + {"ClientTrace.WroteHeaders", Field, 7}, + {"ClientTrace.WroteRequest", Field, 7}, + {"ContextClientTrace", Func, 7}, + {"DNSDoneInfo", Type, 7}, + {"DNSDoneInfo.Addrs", Field, 7}, + {"DNSDoneInfo.Coalesced", Field, 7}, + {"DNSDoneInfo.Err", Field, 7}, + {"DNSStartInfo", Type, 7}, + {"DNSStartInfo.Host", Field, 7}, + {"GotConnInfo", Type, 7}, + {"GotConnInfo.Conn", Field, 7}, + {"GotConnInfo.IdleTime", Field, 7}, + {"GotConnInfo.Reused", Field, 7}, + {"GotConnInfo.WasIdle", Field, 7}, + {"WithClientTrace", Func, 7}, + {"WroteRequestInfo", Type, 7}, + {"WroteRequestInfo.Err", Field, 7}, + }, + "net/http/httputil": { + {"(*ClientConn).Close", Method, 0}, + {"(*ClientConn).Do", Method, 0}, + {"(*ClientConn).Hijack", Method, 0}, + {"(*ClientConn).Pending", Method, 0}, + {"(*ClientConn).Read", Method, 0}, + {"(*ClientConn).Write", Method, 0}, + {"(*ProxyRequest).SetURL", Method, 20}, + {"(*ProxyRequest).SetXForwarded", Method, 20}, + {"(*ReverseProxy).ServeHTTP", Method, 0}, + {"(*ServerConn).Close", Method, 0}, + {"(*ServerConn).Hijack", Method, 0}, + {"(*ServerConn).Pending", Method, 0}, + {"(*ServerConn).Read", Method, 0}, + {"(*ServerConn).Write", Method, 0}, + {"BufferPool", Type, 6}, + {"ClientConn", Type, 0}, + {"DumpRequest", Func, 0}, + {"DumpRequestOut", Func, 0}, + {"DumpResponse", Func, 0}, + {"ErrClosed", Var, 0}, + {"ErrLineTooLong", Var, 0}, + {"ErrPersistEOF", Var, 0}, + {"ErrPipeline", Var, 0}, + {"NewChunkedReader", Func, 0}, + {"NewChunkedWriter", Func, 0}, + {"NewClientConn", Func, 0}, + {"NewProxyClientConn", Func, 0}, + {"NewServerConn", Func, 0}, + {"NewSingleHostReverseProxy", Func, 0}, + {"ProxyRequest", Type, 20}, + {"ProxyRequest.In", Field, 20}, + {"ProxyRequest.Out", Field, 20}, + {"ReverseProxy", Type, 0}, + {"ReverseProxy.BufferPool", Field, 6}, + {"ReverseProxy.Director", Field, 0}, + {"ReverseProxy.ErrorHandler", Field, 11}, + {"ReverseProxy.ErrorLog", Field, 4}, + {"ReverseProxy.FlushInterval", Field, 0}, + {"ReverseProxy.ModifyResponse", Field, 8}, + {"ReverseProxy.Rewrite", Field, 20}, + {"ReverseProxy.Transport", Field, 0}, + {"ServerConn", Type, 0}, + }, + "net/http/pprof": { + {"Cmdline", Func, 0}, + {"Handler", Func, 0}, + {"Index", Func, 0}, + {"Profile", Func, 0}, + {"Symbol", Func, 0}, + {"Trace", Func, 5}, + }, + "net/mail": { + {"(*Address).String", Method, 0}, + {"(*AddressParser).Parse", Method, 5}, + {"(*AddressParser).ParseList", Method, 5}, + {"(Header).AddressList", Method, 0}, + {"(Header).Date", Method, 0}, + {"(Header).Get", Method, 0}, + {"Address", Type, 0}, + {"Address.Address", Field, 0}, + {"Address.Name", Field, 0}, + {"AddressParser", Type, 5}, + {"AddressParser.WordDecoder", Field, 5}, + {"ErrHeaderNotPresent", Var, 0}, + {"Header", Type, 0}, + {"Message", Type, 0}, + {"Message.Body", Field, 0}, + {"Message.Header", Field, 0}, + {"ParseAddress", Func, 1}, + {"ParseAddressList", Func, 1}, + {"ParseDate", Func, 8}, + {"ReadMessage", Func, 0}, + }, + "net/netip": { + {"(*Addr).UnmarshalBinary", Method, 18}, + {"(*Addr).UnmarshalText", Method, 18}, + {"(*AddrPort).UnmarshalBinary", Method, 18}, + {"(*AddrPort).UnmarshalText", Method, 18}, + {"(*Prefix).UnmarshalBinary", Method, 18}, + {"(*Prefix).UnmarshalText", Method, 18}, + {"(Addr).AppendTo", Method, 18}, + {"(Addr).As16", Method, 18}, + {"(Addr).As4", Method, 18}, + {"(Addr).AsSlice", Method, 18}, + {"(Addr).BitLen", Method, 18}, + {"(Addr).Compare", Method, 18}, + {"(Addr).Is4", Method, 18}, + {"(Addr).Is4In6", Method, 18}, + {"(Addr).Is6", Method, 18}, + {"(Addr).IsGlobalUnicast", Method, 18}, + {"(Addr).IsInterfaceLocalMulticast", Method, 18}, + {"(Addr).IsLinkLocalMulticast", Method, 18}, + {"(Addr).IsLinkLocalUnicast", Method, 18}, + {"(Addr).IsLoopback", Method, 18}, + {"(Addr).IsMulticast", Method, 18}, + {"(Addr).IsPrivate", Method, 18}, + {"(Addr).IsUnspecified", Method, 18}, + {"(Addr).IsValid", Method, 18}, + {"(Addr).Less", Method, 18}, + {"(Addr).MarshalBinary", Method, 18}, + {"(Addr).MarshalText", Method, 18}, + {"(Addr).Next", Method, 18}, + {"(Addr).Prefix", Method, 18}, + {"(Addr).Prev", Method, 18}, + {"(Addr).String", Method, 18}, + {"(Addr).StringExpanded", Method, 18}, + {"(Addr).Unmap", Method, 18}, + {"(Addr).WithZone", Method, 18}, + {"(Addr).Zone", Method, 18}, + {"(AddrPort).Addr", Method, 18}, + {"(AddrPort).AppendTo", Method, 18}, + {"(AddrPort).Compare", Method, 22}, + {"(AddrPort).IsValid", Method, 18}, + {"(AddrPort).MarshalBinary", Method, 18}, + {"(AddrPort).MarshalText", Method, 18}, + {"(AddrPort).Port", Method, 18}, + {"(AddrPort).String", Method, 18}, + {"(Prefix).Addr", Method, 18}, + {"(Prefix).AppendTo", Method, 18}, + {"(Prefix).Bits", Method, 18}, + {"(Prefix).Contains", Method, 18}, + {"(Prefix).IsSingleIP", Method, 18}, + {"(Prefix).IsValid", Method, 18}, + {"(Prefix).MarshalBinary", Method, 18}, + {"(Prefix).MarshalText", Method, 18}, + {"(Prefix).Masked", Method, 18}, + {"(Prefix).Overlaps", Method, 18}, + {"(Prefix).String", Method, 18}, + {"Addr", Type, 18}, + {"AddrFrom16", Func, 18}, + {"AddrFrom4", Func, 18}, + {"AddrFromSlice", Func, 18}, + {"AddrPort", Type, 18}, + {"AddrPortFrom", Func, 18}, + {"IPv4Unspecified", Func, 18}, + {"IPv6LinkLocalAllNodes", Func, 18}, + {"IPv6LinkLocalAllRouters", Func, 20}, + {"IPv6Loopback", Func, 20}, + {"IPv6Unspecified", Func, 18}, + {"MustParseAddr", Func, 18}, + {"MustParseAddrPort", Func, 18}, + {"MustParsePrefix", Func, 18}, + {"ParseAddr", Func, 18}, + {"ParseAddrPort", Func, 18}, + {"ParsePrefix", Func, 18}, + {"Prefix", Type, 18}, + {"PrefixFrom", Func, 18}, + }, + "net/rpc": { + {"(*Client).Call", Method, 0}, + {"(*Client).Close", Method, 0}, + {"(*Client).Go", Method, 0}, + {"(*Server).Accept", Method, 0}, + {"(*Server).HandleHTTP", Method, 0}, + {"(*Server).Register", Method, 0}, + {"(*Server).RegisterName", Method, 0}, + {"(*Server).ServeCodec", Method, 0}, + {"(*Server).ServeConn", Method, 0}, + {"(*Server).ServeHTTP", Method, 0}, + {"(*Server).ServeRequest", Method, 0}, + {"(ServerError).Error", Method, 0}, + {"Accept", Func, 0}, + {"Call", Type, 0}, + {"Call.Args", Field, 0}, + {"Call.Done", Field, 0}, + {"Call.Error", Field, 0}, + {"Call.Reply", Field, 0}, + {"Call.ServiceMethod", Field, 0}, + {"Client", Type, 0}, + {"ClientCodec", Type, 0}, + {"DefaultDebugPath", Const, 0}, + {"DefaultRPCPath", Const, 0}, + {"DefaultServer", Var, 0}, + {"Dial", Func, 0}, + {"DialHTTP", Func, 0}, + {"DialHTTPPath", Func, 0}, + {"ErrShutdown", Var, 0}, + {"HandleHTTP", Func, 0}, + {"NewClient", Func, 0}, + {"NewClientWithCodec", Func, 0}, + {"NewServer", Func, 0}, + {"Register", Func, 0}, + {"RegisterName", Func, 0}, + {"Request", Type, 0}, + {"Request.Seq", Field, 0}, + {"Request.ServiceMethod", Field, 0}, + {"Response", Type, 0}, + {"Response.Error", Field, 0}, + {"Response.Seq", Field, 0}, + {"Response.ServiceMethod", Field, 0}, + {"ServeCodec", Func, 0}, + {"ServeConn", Func, 0}, + {"ServeRequest", Func, 0}, + {"Server", Type, 0}, + {"ServerCodec", Type, 0}, + {"ServerError", Type, 0}, + }, + "net/rpc/jsonrpc": { + {"Dial", Func, 0}, + {"NewClient", Func, 0}, + {"NewClientCodec", Func, 0}, + {"NewServerCodec", Func, 0}, + {"ServeConn", Func, 0}, + }, + "net/smtp": { + {"(*Client).Auth", Method, 0}, + {"(*Client).Close", Method, 2}, + {"(*Client).Data", Method, 0}, + {"(*Client).Extension", Method, 0}, + {"(*Client).Hello", Method, 1}, + {"(*Client).Mail", Method, 0}, + {"(*Client).Noop", Method, 10}, + {"(*Client).Quit", Method, 0}, + {"(*Client).Rcpt", Method, 0}, + {"(*Client).Reset", Method, 0}, + {"(*Client).StartTLS", Method, 0}, + {"(*Client).TLSConnectionState", Method, 5}, + {"(*Client).Verify", Method, 0}, + {"Auth", Type, 0}, + {"CRAMMD5Auth", Func, 0}, + {"Client", Type, 0}, + {"Client.Text", Field, 0}, + {"Dial", Func, 0}, + {"NewClient", Func, 0}, + {"PlainAuth", Func, 0}, + {"SendMail", Func, 0}, + {"ServerInfo", Type, 0}, + {"ServerInfo.Auth", Field, 0}, + {"ServerInfo.Name", Field, 0}, + {"ServerInfo.TLS", Field, 0}, + }, + "net/textproto": { + {"(*Conn).Close", Method, 0}, + {"(*Conn).Cmd", Method, 0}, + {"(*Conn).DotReader", Method, 0}, + {"(*Conn).DotWriter", Method, 0}, + {"(*Conn).EndRequest", Method, 0}, + {"(*Conn).EndResponse", Method, 0}, + {"(*Conn).Next", Method, 0}, + {"(*Conn).PrintfLine", Method, 0}, + {"(*Conn).ReadCodeLine", Method, 0}, + {"(*Conn).ReadContinuedLine", Method, 0}, + {"(*Conn).ReadContinuedLineBytes", Method, 0}, + {"(*Conn).ReadDotBytes", Method, 0}, + {"(*Conn).ReadDotLines", Method, 0}, + {"(*Conn).ReadLine", Method, 0}, + {"(*Conn).ReadLineBytes", Method, 0}, + {"(*Conn).ReadMIMEHeader", Method, 0}, + {"(*Conn).ReadResponse", Method, 0}, + {"(*Conn).StartRequest", Method, 0}, + {"(*Conn).StartResponse", Method, 0}, + {"(*Error).Error", Method, 0}, + {"(*Pipeline).EndRequest", Method, 0}, + {"(*Pipeline).EndResponse", Method, 0}, + {"(*Pipeline).Next", Method, 0}, + {"(*Pipeline).StartRequest", Method, 0}, + {"(*Pipeline).StartResponse", Method, 0}, + {"(*Reader).DotReader", Method, 0}, + {"(*Reader).ReadCodeLine", Method, 0}, + {"(*Reader).ReadContinuedLine", Method, 0}, + {"(*Reader).ReadContinuedLineBytes", Method, 0}, + {"(*Reader).ReadDotBytes", Method, 0}, + {"(*Reader).ReadDotLines", Method, 0}, + {"(*Reader).ReadLine", Method, 0}, + {"(*Reader).ReadLineBytes", Method, 0}, + {"(*Reader).ReadMIMEHeader", Method, 0}, + {"(*Reader).ReadResponse", Method, 0}, + {"(*Writer).DotWriter", Method, 0}, + {"(*Writer).PrintfLine", Method, 0}, + {"(MIMEHeader).Add", Method, 0}, + {"(MIMEHeader).Del", Method, 0}, + {"(MIMEHeader).Get", Method, 0}, + {"(MIMEHeader).Set", Method, 0}, + {"(MIMEHeader).Values", Method, 14}, + {"(ProtocolError).Error", Method, 0}, + {"CanonicalMIMEHeaderKey", Func, 0}, + {"Conn", Type, 0}, + {"Conn.Pipeline", Field, 0}, + {"Conn.Reader", Field, 0}, + {"Conn.Writer", Field, 0}, + {"Dial", Func, 0}, + {"Error", Type, 0}, + {"Error.Code", Field, 0}, + {"Error.Msg", Field, 0}, + {"MIMEHeader", Type, 0}, + {"NewConn", Func, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"Pipeline", Type, 0}, + {"ProtocolError", Type, 0}, + {"Reader", Type, 0}, + {"Reader.R", Field, 0}, + {"TrimBytes", Func, 1}, + {"TrimString", Func, 1}, + {"Writer", Type, 0}, + {"Writer.W", Field, 0}, + }, + "net/url": { + {"(*Error).Error", Method, 0}, + {"(*Error).Temporary", Method, 6}, + {"(*Error).Timeout", Method, 6}, + {"(*Error).Unwrap", Method, 13}, + {"(*URL).EscapedFragment", Method, 15}, + {"(*URL).EscapedPath", Method, 5}, + {"(*URL).Hostname", Method, 8}, + {"(*URL).IsAbs", Method, 0}, + {"(*URL).JoinPath", Method, 19}, + {"(*URL).MarshalBinary", Method, 8}, + {"(*URL).Parse", Method, 0}, + {"(*URL).Port", Method, 8}, + {"(*URL).Query", Method, 0}, + {"(*URL).Redacted", Method, 15}, + {"(*URL).RequestURI", Method, 0}, + {"(*URL).ResolveReference", Method, 0}, + {"(*URL).String", Method, 0}, + {"(*URL).UnmarshalBinary", Method, 8}, + {"(*Userinfo).Password", Method, 0}, + {"(*Userinfo).String", Method, 0}, + {"(*Userinfo).Username", Method, 0}, + {"(EscapeError).Error", Method, 0}, + {"(InvalidHostError).Error", Method, 6}, + {"(Values).Add", Method, 0}, + {"(Values).Del", Method, 0}, + {"(Values).Encode", Method, 0}, + {"(Values).Get", Method, 0}, + {"(Values).Has", Method, 17}, + {"(Values).Set", Method, 0}, + {"Error", Type, 0}, + {"Error.Err", Field, 0}, + {"Error.Op", Field, 0}, + {"Error.URL", Field, 0}, + {"EscapeError", Type, 0}, + {"InvalidHostError", Type, 6}, + {"JoinPath", Func, 19}, + {"Parse", Func, 0}, + {"ParseQuery", Func, 0}, + {"ParseRequestURI", Func, 0}, + {"PathEscape", Func, 8}, + {"PathUnescape", Func, 8}, + {"QueryEscape", Func, 0}, + {"QueryUnescape", Func, 0}, + {"URL", Type, 0}, + {"URL.ForceQuery", Field, 7}, + {"URL.Fragment", Field, 0}, + {"URL.Host", Field, 0}, + {"URL.OmitHost", Field, 19}, + {"URL.Opaque", Field, 0}, + {"URL.Path", Field, 0}, + {"URL.RawFragment", Field, 15}, + {"URL.RawPath", Field, 5}, + {"URL.RawQuery", Field, 0}, + {"URL.Scheme", Field, 0}, + {"URL.User", Field, 0}, + {"User", Func, 0}, + {"UserPassword", Func, 0}, + {"Userinfo", Type, 0}, + {"Values", Type, 0}, + }, + "os": { + {"(*File).Chdir", Method, 0}, + {"(*File).Chmod", Method, 0}, + {"(*File).Chown", Method, 0}, + {"(*File).Close", Method, 0}, + {"(*File).Fd", Method, 0}, + {"(*File).Name", Method, 0}, + {"(*File).Read", Method, 0}, + {"(*File).ReadAt", Method, 0}, + {"(*File).ReadDir", Method, 16}, + {"(*File).ReadFrom", Method, 15}, + {"(*File).Readdir", Method, 0}, + {"(*File).Readdirnames", Method, 0}, + {"(*File).Seek", Method, 0}, + {"(*File).SetDeadline", Method, 10}, + {"(*File).SetReadDeadline", Method, 10}, + {"(*File).SetWriteDeadline", Method, 10}, + {"(*File).Stat", Method, 0}, + {"(*File).Sync", Method, 0}, + {"(*File).SyscallConn", Method, 12}, + {"(*File).Truncate", Method, 0}, + {"(*File).Write", Method, 0}, + {"(*File).WriteAt", Method, 0}, + {"(*File).WriteString", Method, 0}, + {"(*File).WriteTo", Method, 22}, + {"(*LinkError).Error", Method, 0}, + {"(*LinkError).Unwrap", Method, 13}, + {"(*PathError).Error", Method, 0}, + {"(*PathError).Timeout", Method, 10}, + {"(*PathError).Unwrap", Method, 13}, + {"(*Process).Kill", Method, 0}, + {"(*Process).Release", Method, 0}, + {"(*Process).Signal", Method, 0}, + {"(*Process).Wait", Method, 0}, + {"(*ProcessState).ExitCode", Method, 12}, + {"(*ProcessState).Exited", Method, 0}, + {"(*ProcessState).Pid", Method, 0}, + {"(*ProcessState).String", Method, 0}, + {"(*ProcessState).Success", Method, 0}, + {"(*ProcessState).Sys", Method, 0}, + {"(*ProcessState).SysUsage", Method, 0}, + {"(*ProcessState).SystemTime", Method, 0}, + {"(*ProcessState).UserTime", Method, 0}, + {"(*SyscallError).Error", Method, 0}, + {"(*SyscallError).Timeout", Method, 10}, + {"(*SyscallError).Unwrap", Method, 13}, + {"(FileMode).IsDir", Method, 0}, + {"(FileMode).IsRegular", Method, 1}, + {"(FileMode).Perm", Method, 0}, + {"(FileMode).String", Method, 0}, + {"Args", Var, 0}, + {"Chdir", Func, 0}, + {"Chmod", Func, 0}, + {"Chown", Func, 0}, + {"Chtimes", Func, 0}, + {"Clearenv", Func, 0}, + {"CopyFS", Func, 23}, + {"Create", Func, 0}, + {"CreateTemp", Func, 16}, + {"DevNull", Const, 0}, + {"DirEntry", Type, 16}, + {"DirFS", Func, 16}, + {"Environ", Func, 0}, + {"ErrClosed", Var, 8}, + {"ErrDeadlineExceeded", Var, 15}, + {"ErrExist", Var, 0}, + {"ErrInvalid", Var, 0}, + {"ErrNoDeadline", Var, 10}, + {"ErrNotExist", Var, 0}, + {"ErrPermission", Var, 0}, + {"ErrProcessDone", Var, 16}, + {"Executable", Func, 8}, + {"Exit", Func, 0}, + {"Expand", Func, 0}, + {"ExpandEnv", Func, 0}, + {"File", Type, 0}, + {"FileInfo", Type, 0}, + {"FileMode", Type, 0}, + {"FindProcess", Func, 0}, + {"Getegid", Func, 0}, + {"Getenv", Func, 0}, + {"Geteuid", Func, 0}, + {"Getgid", Func, 0}, + {"Getgroups", Func, 0}, + {"Getpagesize", Func, 0}, + {"Getpid", Func, 0}, + {"Getppid", Func, 0}, + {"Getuid", Func, 0}, + {"Getwd", Func, 0}, + {"Hostname", Func, 0}, + {"Interrupt", Var, 0}, + {"IsExist", Func, 0}, + {"IsNotExist", Func, 0}, + {"IsPathSeparator", Func, 0}, + {"IsPermission", Func, 0}, + {"IsTimeout", Func, 10}, + {"Kill", Var, 0}, + {"Lchown", Func, 0}, + {"Link", Func, 0}, + {"LinkError", Type, 0}, + {"LinkError.Err", Field, 0}, + {"LinkError.New", Field, 0}, + {"LinkError.Old", Field, 0}, + {"LinkError.Op", Field, 0}, + {"LookupEnv", Func, 5}, + {"Lstat", Func, 0}, + {"Mkdir", Func, 0}, + {"MkdirAll", Func, 0}, + {"MkdirTemp", Func, 16}, + {"ModeAppend", Const, 0}, + {"ModeCharDevice", Const, 0}, + {"ModeDevice", Const, 0}, + {"ModeDir", Const, 0}, + {"ModeExclusive", Const, 0}, + {"ModeIrregular", Const, 11}, + {"ModeNamedPipe", Const, 0}, + {"ModePerm", Const, 0}, + {"ModeSetgid", Const, 0}, + {"ModeSetuid", Const, 0}, + {"ModeSocket", Const, 0}, + {"ModeSticky", Const, 0}, + {"ModeSymlink", Const, 0}, + {"ModeTemporary", Const, 0}, + {"ModeType", Const, 0}, + {"NewFile", Func, 0}, + {"NewSyscallError", Func, 0}, + {"O_APPEND", Const, 0}, + {"O_CREATE", Const, 0}, + {"O_EXCL", Const, 0}, + {"O_RDONLY", Const, 0}, + {"O_RDWR", Const, 0}, + {"O_SYNC", Const, 0}, + {"O_TRUNC", Const, 0}, + {"O_WRONLY", Const, 0}, + {"Open", Func, 0}, + {"OpenFile", Func, 0}, + {"PathError", Type, 0}, + {"PathError.Err", Field, 0}, + {"PathError.Op", Field, 0}, + {"PathError.Path", Field, 0}, + {"PathListSeparator", Const, 0}, + {"PathSeparator", Const, 0}, + {"Pipe", Func, 0}, + {"ProcAttr", Type, 0}, + {"ProcAttr.Dir", Field, 0}, + {"ProcAttr.Env", Field, 0}, + {"ProcAttr.Files", Field, 0}, + {"ProcAttr.Sys", Field, 0}, + {"Process", Type, 0}, + {"Process.Pid", Field, 0}, + {"ProcessState", Type, 0}, + {"ReadDir", Func, 16}, + {"ReadFile", Func, 16}, + {"Readlink", Func, 0}, + {"Remove", Func, 0}, + {"RemoveAll", Func, 0}, + {"Rename", Func, 0}, + {"SEEK_CUR", Const, 0}, + {"SEEK_END", Const, 0}, + {"SEEK_SET", Const, 0}, + {"SameFile", Func, 0}, + {"Setenv", Func, 0}, + {"Signal", Type, 0}, + {"StartProcess", Func, 0}, + {"Stat", Func, 0}, + {"Stderr", Var, 0}, + {"Stdin", Var, 0}, + {"Stdout", Var, 0}, + {"Symlink", Func, 0}, + {"SyscallError", Type, 0}, + {"SyscallError.Err", Field, 0}, + {"SyscallError.Syscall", Field, 0}, + {"TempDir", Func, 0}, + {"Truncate", Func, 0}, + {"Unsetenv", Func, 4}, + {"UserCacheDir", Func, 11}, + {"UserConfigDir", Func, 13}, + {"UserHomeDir", Func, 12}, + {"WriteFile", Func, 16}, + }, + "os/exec": { + {"(*Cmd).CombinedOutput", Method, 0}, + {"(*Cmd).Environ", Method, 19}, + {"(*Cmd).Output", Method, 0}, + {"(*Cmd).Run", Method, 0}, + {"(*Cmd).Start", Method, 0}, + {"(*Cmd).StderrPipe", Method, 0}, + {"(*Cmd).StdinPipe", Method, 0}, + {"(*Cmd).StdoutPipe", Method, 0}, + {"(*Cmd).String", Method, 13}, + {"(*Cmd).Wait", Method, 0}, + {"(*Error).Error", Method, 0}, + {"(*Error).Unwrap", Method, 13}, + {"(*ExitError).Error", Method, 0}, + {"(ExitError).ExitCode", Method, 12}, + {"(ExitError).Exited", Method, 0}, + {"(ExitError).Pid", Method, 0}, + {"(ExitError).String", Method, 0}, + {"(ExitError).Success", Method, 0}, + {"(ExitError).Sys", Method, 0}, + {"(ExitError).SysUsage", Method, 0}, + {"(ExitError).SystemTime", Method, 0}, + {"(ExitError).UserTime", Method, 0}, + {"Cmd", Type, 0}, + {"Cmd.Args", Field, 0}, + {"Cmd.Cancel", Field, 20}, + {"Cmd.Dir", Field, 0}, + {"Cmd.Env", Field, 0}, + {"Cmd.Err", Field, 19}, + {"Cmd.ExtraFiles", Field, 0}, + {"Cmd.Path", Field, 0}, + {"Cmd.Process", Field, 0}, + {"Cmd.ProcessState", Field, 0}, + {"Cmd.Stderr", Field, 0}, + {"Cmd.Stdin", Field, 0}, + {"Cmd.Stdout", Field, 0}, + {"Cmd.SysProcAttr", Field, 0}, + {"Cmd.WaitDelay", Field, 20}, + {"Command", Func, 0}, + {"CommandContext", Func, 7}, + {"ErrDot", Var, 19}, + {"ErrNotFound", Var, 0}, + {"ErrWaitDelay", Var, 20}, + {"Error", Type, 0}, + {"Error.Err", Field, 0}, + {"Error.Name", Field, 0}, + {"ExitError", Type, 0}, + {"ExitError.ProcessState", Field, 0}, + {"ExitError.Stderr", Field, 6}, + {"LookPath", Func, 0}, + }, + "os/signal": { + {"Ignore", Func, 5}, + {"Ignored", Func, 11}, + {"Notify", Func, 0}, + {"NotifyContext", Func, 16}, + {"Reset", Func, 5}, + {"Stop", Func, 1}, + }, + "os/user": { + {"(*User).GroupIds", Method, 7}, + {"(UnknownGroupError).Error", Method, 7}, + {"(UnknownGroupIdError).Error", Method, 7}, + {"(UnknownUserError).Error", Method, 0}, + {"(UnknownUserIdError).Error", Method, 0}, + {"Current", Func, 0}, + {"Group", Type, 7}, + {"Group.Gid", Field, 7}, + {"Group.Name", Field, 7}, + {"Lookup", Func, 0}, + {"LookupGroup", Func, 7}, + {"LookupGroupId", Func, 7}, + {"LookupId", Func, 0}, + {"UnknownGroupError", Type, 7}, + {"UnknownGroupIdError", Type, 7}, + {"UnknownUserError", Type, 0}, + {"UnknownUserIdError", Type, 0}, + {"User", Type, 0}, + {"User.Gid", Field, 0}, + {"User.HomeDir", Field, 0}, + {"User.Name", Field, 0}, + {"User.Uid", Field, 0}, + {"User.Username", Field, 0}, + }, + "path": { + {"Base", Func, 0}, + {"Clean", Func, 0}, + {"Dir", Func, 0}, + {"ErrBadPattern", Var, 0}, + {"Ext", Func, 0}, + {"IsAbs", Func, 0}, + {"Join", Func, 0}, + {"Match", Func, 0}, + {"Split", Func, 0}, + }, + "path/filepath": { + {"Abs", Func, 0}, + {"Base", Func, 0}, + {"Clean", Func, 0}, + {"Dir", Func, 0}, + {"ErrBadPattern", Var, 0}, + {"EvalSymlinks", Func, 0}, + {"Ext", Func, 0}, + {"FromSlash", Func, 0}, + {"Glob", Func, 0}, + {"HasPrefix", Func, 0}, + {"IsAbs", Func, 0}, + {"IsLocal", Func, 20}, + {"Join", Func, 0}, + {"ListSeparator", Const, 0}, + {"Localize", Func, 23}, + {"Match", Func, 0}, + {"Rel", Func, 0}, + {"Separator", Const, 0}, + {"SkipAll", Var, 20}, + {"SkipDir", Var, 0}, + {"Split", Func, 0}, + {"SplitList", Func, 0}, + {"ToSlash", Func, 0}, + {"VolumeName", Func, 0}, + {"Walk", Func, 0}, + {"WalkDir", Func, 16}, + {"WalkFunc", Type, 0}, + }, + "plugin": { + {"(*Plugin).Lookup", Method, 8}, + {"Open", Func, 8}, + {"Plugin", Type, 8}, + {"Symbol", Type, 8}, + }, + "reflect": { + {"(*MapIter).Key", Method, 12}, + {"(*MapIter).Next", Method, 12}, + {"(*MapIter).Reset", Method, 18}, + {"(*MapIter).Value", Method, 12}, + {"(*ValueError).Error", Method, 0}, + {"(ChanDir).String", Method, 0}, + {"(Kind).String", Method, 0}, + {"(Method).IsExported", Method, 17}, + {"(StructField).IsExported", Method, 17}, + {"(StructTag).Get", Method, 0}, + {"(StructTag).Lookup", Method, 7}, + {"(Value).Addr", Method, 0}, + {"(Value).Bool", Method, 0}, + {"(Value).Bytes", Method, 0}, + {"(Value).Call", Method, 0}, + {"(Value).CallSlice", Method, 0}, + {"(Value).CanAddr", Method, 0}, + {"(Value).CanComplex", Method, 18}, + {"(Value).CanConvert", Method, 17}, + {"(Value).CanFloat", Method, 18}, + {"(Value).CanInt", Method, 18}, + {"(Value).CanInterface", Method, 0}, + {"(Value).CanSet", Method, 0}, + {"(Value).CanUint", Method, 18}, + {"(Value).Cap", Method, 0}, + {"(Value).Clear", Method, 21}, + {"(Value).Close", Method, 0}, + {"(Value).Comparable", Method, 20}, + {"(Value).Complex", Method, 0}, + {"(Value).Convert", Method, 1}, + {"(Value).Elem", Method, 0}, + {"(Value).Equal", Method, 20}, + {"(Value).Field", Method, 0}, + {"(Value).FieldByIndex", Method, 0}, + {"(Value).FieldByIndexErr", Method, 18}, + {"(Value).FieldByName", Method, 0}, + {"(Value).FieldByNameFunc", Method, 0}, + {"(Value).Float", Method, 0}, + {"(Value).Grow", Method, 20}, + {"(Value).Index", Method, 0}, + {"(Value).Int", Method, 0}, + {"(Value).Interface", Method, 0}, + {"(Value).InterfaceData", Method, 0}, + {"(Value).IsNil", Method, 0}, + {"(Value).IsValid", Method, 0}, + {"(Value).IsZero", Method, 13}, + {"(Value).Kind", Method, 0}, + {"(Value).Len", Method, 0}, + {"(Value).MapIndex", Method, 0}, + {"(Value).MapKeys", Method, 0}, + {"(Value).MapRange", Method, 12}, + {"(Value).Method", Method, 0}, + {"(Value).MethodByName", Method, 0}, + {"(Value).NumField", Method, 0}, + {"(Value).NumMethod", Method, 0}, + {"(Value).OverflowComplex", Method, 0}, + {"(Value).OverflowFloat", Method, 0}, + {"(Value).OverflowInt", Method, 0}, + {"(Value).OverflowUint", Method, 0}, + {"(Value).Pointer", Method, 0}, + {"(Value).Recv", Method, 0}, + {"(Value).Send", Method, 0}, + {"(Value).Seq", Method, 23}, + {"(Value).Seq2", Method, 23}, + {"(Value).Set", Method, 0}, + {"(Value).SetBool", Method, 0}, + {"(Value).SetBytes", Method, 0}, + {"(Value).SetCap", Method, 2}, + {"(Value).SetComplex", Method, 0}, + {"(Value).SetFloat", Method, 0}, + {"(Value).SetInt", Method, 0}, + {"(Value).SetIterKey", Method, 18}, + {"(Value).SetIterValue", Method, 18}, + {"(Value).SetLen", Method, 0}, + {"(Value).SetMapIndex", Method, 0}, + {"(Value).SetPointer", Method, 0}, + {"(Value).SetString", Method, 0}, + {"(Value).SetUint", Method, 0}, + {"(Value).SetZero", Method, 20}, + {"(Value).Slice", Method, 0}, + {"(Value).Slice3", Method, 2}, + {"(Value).String", Method, 0}, + {"(Value).TryRecv", Method, 0}, + {"(Value).TrySend", Method, 0}, + {"(Value).Type", Method, 0}, + {"(Value).Uint", Method, 0}, + {"(Value).UnsafeAddr", Method, 0}, + {"(Value).UnsafePointer", Method, 18}, + {"Append", Func, 0}, + {"AppendSlice", Func, 0}, + {"Array", Const, 0}, + {"ArrayOf", Func, 5}, + {"Bool", Const, 0}, + {"BothDir", Const, 0}, + {"Chan", Const, 0}, + {"ChanDir", Type, 0}, + {"ChanOf", Func, 1}, + {"Complex128", Const, 0}, + {"Complex64", Const, 0}, + {"Copy", Func, 0}, + {"DeepEqual", Func, 0}, + {"Float32", Const, 0}, + {"Float64", Const, 0}, + {"Func", Const, 0}, + {"FuncOf", Func, 5}, + {"Indirect", Func, 0}, + {"Int", Const, 0}, + {"Int16", Const, 0}, + {"Int32", Const, 0}, + {"Int64", Const, 0}, + {"Int8", Const, 0}, + {"Interface", Const, 0}, + {"Invalid", Const, 0}, + {"Kind", Type, 0}, + {"MakeChan", Func, 0}, + {"MakeFunc", Func, 1}, + {"MakeMap", Func, 0}, + {"MakeMapWithSize", Func, 9}, + {"MakeSlice", Func, 0}, + {"Map", Const, 0}, + {"MapIter", Type, 12}, + {"MapOf", Func, 1}, + {"Method", Type, 0}, + {"Method.Func", Field, 0}, + {"Method.Index", Field, 0}, + {"Method.Name", Field, 0}, + {"Method.PkgPath", Field, 0}, + {"Method.Type", Field, 0}, + {"New", Func, 0}, + {"NewAt", Func, 0}, + {"Pointer", Const, 18}, + {"PointerTo", Func, 18}, + {"Ptr", Const, 0}, + {"PtrTo", Func, 0}, + {"RecvDir", Const, 0}, + {"Select", Func, 1}, + {"SelectCase", Type, 1}, + {"SelectCase.Chan", Field, 1}, + {"SelectCase.Dir", Field, 1}, + {"SelectCase.Send", Field, 1}, + {"SelectDefault", Const, 1}, + {"SelectDir", Type, 1}, + {"SelectRecv", Const, 1}, + {"SelectSend", Const, 1}, + {"SendDir", Const, 0}, + {"Slice", Const, 0}, + {"SliceAt", Func, 23}, + {"SliceHeader", Type, 0}, + {"SliceHeader.Cap", Field, 0}, + {"SliceHeader.Data", Field, 0}, + {"SliceHeader.Len", Field, 0}, + {"SliceOf", Func, 1}, + {"String", Const, 0}, + {"StringHeader", Type, 0}, + {"StringHeader.Data", Field, 0}, + {"StringHeader.Len", Field, 0}, + {"Struct", Const, 0}, + {"StructField", Type, 0}, + {"StructField.Anonymous", Field, 0}, + {"StructField.Index", Field, 0}, + {"StructField.Name", Field, 0}, + {"StructField.Offset", Field, 0}, + {"StructField.PkgPath", Field, 0}, + {"StructField.Tag", Field, 0}, + {"StructField.Type", Field, 0}, + {"StructOf", Func, 7}, + {"StructTag", Type, 0}, + {"Swapper", Func, 8}, + {"Type", Type, 0}, + {"TypeFor", Func, 22}, + {"TypeOf", Func, 0}, + {"Uint", Const, 0}, + {"Uint16", Const, 0}, + {"Uint32", Const, 0}, + {"Uint64", Const, 0}, + {"Uint8", Const, 0}, + {"Uintptr", Const, 0}, + {"UnsafePointer", Const, 0}, + {"Value", Type, 0}, + {"ValueError", Type, 0}, + {"ValueError.Kind", Field, 0}, + {"ValueError.Method", Field, 0}, + {"ValueOf", Func, 0}, + {"VisibleFields", Func, 17}, + {"Zero", Func, 0}, + }, + "regexp": { + {"(*Regexp).Copy", Method, 6}, + {"(*Regexp).Expand", Method, 0}, + {"(*Regexp).ExpandString", Method, 0}, + {"(*Regexp).Find", Method, 0}, + {"(*Regexp).FindAll", Method, 0}, + {"(*Regexp).FindAllIndex", Method, 0}, + {"(*Regexp).FindAllString", Method, 0}, + {"(*Regexp).FindAllStringIndex", Method, 0}, + {"(*Regexp).FindAllStringSubmatch", Method, 0}, + {"(*Regexp).FindAllStringSubmatchIndex", Method, 0}, + {"(*Regexp).FindAllSubmatch", Method, 0}, + {"(*Regexp).FindAllSubmatchIndex", Method, 0}, + {"(*Regexp).FindIndex", Method, 0}, + {"(*Regexp).FindReaderIndex", Method, 0}, + {"(*Regexp).FindReaderSubmatchIndex", Method, 0}, + {"(*Regexp).FindString", Method, 0}, + {"(*Regexp).FindStringIndex", Method, 0}, + {"(*Regexp).FindStringSubmatch", Method, 0}, + {"(*Regexp).FindStringSubmatchIndex", Method, 0}, + {"(*Regexp).FindSubmatch", Method, 0}, + {"(*Regexp).FindSubmatchIndex", Method, 0}, + {"(*Regexp).LiteralPrefix", Method, 0}, + {"(*Regexp).Longest", Method, 1}, + {"(*Regexp).MarshalText", Method, 21}, + {"(*Regexp).Match", Method, 0}, + {"(*Regexp).MatchReader", Method, 0}, + {"(*Regexp).MatchString", Method, 0}, + {"(*Regexp).NumSubexp", Method, 0}, + {"(*Regexp).ReplaceAll", Method, 0}, + {"(*Regexp).ReplaceAllFunc", Method, 0}, + {"(*Regexp).ReplaceAllLiteral", Method, 0}, + {"(*Regexp).ReplaceAllLiteralString", Method, 0}, + {"(*Regexp).ReplaceAllString", Method, 0}, + {"(*Regexp).ReplaceAllStringFunc", Method, 0}, + {"(*Regexp).Split", Method, 1}, + {"(*Regexp).String", Method, 0}, + {"(*Regexp).SubexpIndex", Method, 15}, + {"(*Regexp).SubexpNames", Method, 0}, + {"(*Regexp).UnmarshalText", Method, 21}, + {"Compile", Func, 0}, + {"CompilePOSIX", Func, 0}, + {"Match", Func, 0}, + {"MatchReader", Func, 0}, + {"MatchString", Func, 0}, + {"MustCompile", Func, 0}, + {"MustCompilePOSIX", Func, 0}, + {"QuoteMeta", Func, 0}, + {"Regexp", Type, 0}, + }, + "regexp/syntax": { + {"(*Error).Error", Method, 0}, + {"(*Inst).MatchEmptyWidth", Method, 0}, + {"(*Inst).MatchRune", Method, 0}, + {"(*Inst).MatchRunePos", Method, 3}, + {"(*Inst).String", Method, 0}, + {"(*Prog).Prefix", Method, 0}, + {"(*Prog).StartCond", Method, 0}, + {"(*Prog).String", Method, 0}, + {"(*Regexp).CapNames", Method, 0}, + {"(*Regexp).Equal", Method, 0}, + {"(*Regexp).MaxCap", Method, 0}, + {"(*Regexp).Simplify", Method, 0}, + {"(*Regexp).String", Method, 0}, + {"(ErrorCode).String", Method, 0}, + {"(InstOp).String", Method, 3}, + {"(Op).String", Method, 11}, + {"ClassNL", Const, 0}, + {"Compile", Func, 0}, + {"DotNL", Const, 0}, + {"EmptyBeginLine", Const, 0}, + {"EmptyBeginText", Const, 0}, + {"EmptyEndLine", Const, 0}, + {"EmptyEndText", Const, 0}, + {"EmptyNoWordBoundary", Const, 0}, + {"EmptyOp", Type, 0}, + {"EmptyOpContext", Func, 0}, + {"EmptyWordBoundary", Const, 0}, + {"ErrInternalError", Const, 0}, + {"ErrInvalidCharClass", Const, 0}, + {"ErrInvalidCharRange", Const, 0}, + {"ErrInvalidEscape", Const, 0}, + {"ErrInvalidNamedCapture", Const, 0}, + {"ErrInvalidPerlOp", Const, 0}, + {"ErrInvalidRepeatOp", Const, 0}, + {"ErrInvalidRepeatSize", Const, 0}, + {"ErrInvalidUTF8", Const, 0}, + {"ErrLarge", Const, 20}, + {"ErrMissingBracket", Const, 0}, + {"ErrMissingParen", Const, 0}, + {"ErrMissingRepeatArgument", Const, 0}, + {"ErrNestingDepth", Const, 19}, + {"ErrTrailingBackslash", Const, 0}, + {"ErrUnexpectedParen", Const, 1}, + {"Error", Type, 0}, + {"Error.Code", Field, 0}, + {"Error.Expr", Field, 0}, + {"ErrorCode", Type, 0}, + {"Flags", Type, 0}, + {"FoldCase", Const, 0}, + {"Inst", Type, 0}, + {"Inst.Arg", Field, 0}, + {"Inst.Op", Field, 0}, + {"Inst.Out", Field, 0}, + {"Inst.Rune", Field, 0}, + {"InstAlt", Const, 0}, + {"InstAltMatch", Const, 0}, + {"InstCapture", Const, 0}, + {"InstEmptyWidth", Const, 0}, + {"InstFail", Const, 0}, + {"InstMatch", Const, 0}, + {"InstNop", Const, 0}, + {"InstOp", Type, 0}, + {"InstRune", Const, 0}, + {"InstRune1", Const, 0}, + {"InstRuneAny", Const, 0}, + {"InstRuneAnyNotNL", Const, 0}, + {"IsWordChar", Func, 0}, + {"Literal", Const, 0}, + {"MatchNL", Const, 0}, + {"NonGreedy", Const, 0}, + {"OneLine", Const, 0}, + {"Op", Type, 0}, + {"OpAlternate", Const, 0}, + {"OpAnyChar", Const, 0}, + {"OpAnyCharNotNL", Const, 0}, + {"OpBeginLine", Const, 0}, + {"OpBeginText", Const, 0}, + {"OpCapture", Const, 0}, + {"OpCharClass", Const, 0}, + {"OpConcat", Const, 0}, + {"OpEmptyMatch", Const, 0}, + {"OpEndLine", Const, 0}, + {"OpEndText", Const, 0}, + {"OpLiteral", Const, 0}, + {"OpNoMatch", Const, 0}, + {"OpNoWordBoundary", Const, 0}, + {"OpPlus", Const, 0}, + {"OpQuest", Const, 0}, + {"OpRepeat", Const, 0}, + {"OpStar", Const, 0}, + {"OpWordBoundary", Const, 0}, + {"POSIX", Const, 0}, + {"Parse", Func, 0}, + {"Perl", Const, 0}, + {"PerlX", Const, 0}, + {"Prog", Type, 0}, + {"Prog.Inst", Field, 0}, + {"Prog.NumCap", Field, 0}, + {"Prog.Start", Field, 0}, + {"Regexp", Type, 0}, + {"Regexp.Cap", Field, 0}, + {"Regexp.Flags", Field, 0}, + {"Regexp.Max", Field, 0}, + {"Regexp.Min", Field, 0}, + {"Regexp.Name", Field, 0}, + {"Regexp.Op", Field, 0}, + {"Regexp.Rune", Field, 0}, + {"Regexp.Rune0", Field, 0}, + {"Regexp.Sub", Field, 0}, + {"Regexp.Sub0", Field, 0}, + {"Simple", Const, 0}, + {"UnicodeGroups", Const, 0}, + {"WasDollar", Const, 0}, + }, + "runtime": { + {"(*BlockProfileRecord).Stack", Method, 1}, + {"(*Frames).Next", Method, 7}, + {"(*Func).Entry", Method, 0}, + {"(*Func).FileLine", Method, 0}, + {"(*Func).Name", Method, 0}, + {"(*MemProfileRecord).InUseBytes", Method, 0}, + {"(*MemProfileRecord).InUseObjects", Method, 0}, + {"(*MemProfileRecord).Stack", Method, 0}, + {"(*PanicNilError).Error", Method, 21}, + {"(*PanicNilError).RuntimeError", Method, 21}, + {"(*Pinner).Pin", Method, 21}, + {"(*Pinner).Unpin", Method, 21}, + {"(*StackRecord).Stack", Method, 0}, + {"(*TypeAssertionError).Error", Method, 0}, + {"(*TypeAssertionError).RuntimeError", Method, 0}, + {"BlockProfile", Func, 1}, + {"BlockProfileRecord", Type, 1}, + {"BlockProfileRecord.Count", Field, 1}, + {"BlockProfileRecord.Cycles", Field, 1}, + {"BlockProfileRecord.StackRecord", Field, 1}, + {"Breakpoint", Func, 0}, + {"CPUProfile", Func, 0}, + {"Caller", Func, 0}, + {"Callers", Func, 0}, + {"CallersFrames", Func, 7}, + {"Compiler", Const, 0}, + {"Error", Type, 0}, + {"Frame", Type, 7}, + {"Frame.Entry", Field, 7}, + {"Frame.File", Field, 7}, + {"Frame.Func", Field, 7}, + {"Frame.Function", Field, 7}, + {"Frame.Line", Field, 7}, + {"Frame.PC", Field, 7}, + {"Frames", Type, 7}, + {"Func", Type, 0}, + {"FuncForPC", Func, 0}, + {"GC", Func, 0}, + {"GOARCH", Const, 0}, + {"GOMAXPROCS", Func, 0}, + {"GOOS", Const, 0}, + {"GOROOT", Func, 0}, + {"Goexit", Func, 0}, + {"GoroutineProfile", Func, 0}, + {"Gosched", Func, 0}, + {"KeepAlive", Func, 7}, + {"LockOSThread", Func, 0}, + {"MemProfile", Func, 0}, + {"MemProfileRate", Var, 0}, + {"MemProfileRecord", Type, 0}, + {"MemProfileRecord.AllocBytes", Field, 0}, + {"MemProfileRecord.AllocObjects", Field, 0}, + {"MemProfileRecord.FreeBytes", Field, 0}, + {"MemProfileRecord.FreeObjects", Field, 0}, + {"MemProfileRecord.Stack0", Field, 0}, + {"MemStats", Type, 0}, + {"MemStats.Alloc", Field, 0}, + {"MemStats.BuckHashSys", Field, 0}, + {"MemStats.BySize", Field, 0}, + {"MemStats.DebugGC", Field, 0}, + {"MemStats.EnableGC", Field, 0}, + {"MemStats.Frees", Field, 0}, + {"MemStats.GCCPUFraction", Field, 5}, + {"MemStats.GCSys", Field, 2}, + {"MemStats.HeapAlloc", Field, 0}, + {"MemStats.HeapIdle", Field, 0}, + {"MemStats.HeapInuse", Field, 0}, + {"MemStats.HeapObjects", Field, 0}, + {"MemStats.HeapReleased", Field, 0}, + {"MemStats.HeapSys", Field, 0}, + {"MemStats.LastGC", Field, 0}, + {"MemStats.Lookups", Field, 0}, + {"MemStats.MCacheInuse", Field, 0}, + {"MemStats.MCacheSys", Field, 0}, + {"MemStats.MSpanInuse", Field, 0}, + {"MemStats.MSpanSys", Field, 0}, + {"MemStats.Mallocs", Field, 0}, + {"MemStats.NextGC", Field, 0}, + {"MemStats.NumForcedGC", Field, 8}, + {"MemStats.NumGC", Field, 0}, + {"MemStats.OtherSys", Field, 2}, + {"MemStats.PauseEnd", Field, 4}, + {"MemStats.PauseNs", Field, 0}, + {"MemStats.PauseTotalNs", Field, 0}, + {"MemStats.StackInuse", Field, 0}, + {"MemStats.StackSys", Field, 0}, + {"MemStats.Sys", Field, 0}, + {"MemStats.TotalAlloc", Field, 0}, + {"MutexProfile", Func, 8}, + {"NumCPU", Func, 0}, + {"NumCgoCall", Func, 0}, + {"NumGoroutine", Func, 0}, + {"PanicNilError", Type, 21}, + {"Pinner", Type, 21}, + {"ReadMemStats", Func, 0}, + {"ReadTrace", Func, 5}, + {"SetBlockProfileRate", Func, 1}, + {"SetCPUProfileRate", Func, 0}, + {"SetCgoTraceback", Func, 7}, + {"SetFinalizer", Func, 0}, + {"SetMutexProfileFraction", Func, 8}, + {"Stack", Func, 0}, + {"StackRecord", Type, 0}, + {"StackRecord.Stack0", Field, 0}, + {"StartTrace", Func, 5}, + {"StopTrace", Func, 5}, + {"ThreadCreateProfile", Func, 0}, + {"TypeAssertionError", Type, 0}, + {"UnlockOSThread", Func, 0}, + {"Version", Func, 0}, + }, + "runtime/cgo": { + {"(Handle).Delete", Method, 17}, + {"(Handle).Value", Method, 17}, + {"Handle", Type, 17}, + {"Incomplete", Type, 20}, + {"NewHandle", Func, 17}, + }, + "runtime/coverage": { + {"ClearCounters", Func, 20}, + {"WriteCounters", Func, 20}, + {"WriteCountersDir", Func, 20}, + {"WriteMeta", Func, 20}, + {"WriteMetaDir", Func, 20}, + }, + "runtime/debug": { + {"(*BuildInfo).String", Method, 18}, + {"BuildInfo", Type, 12}, + {"BuildInfo.Deps", Field, 12}, + {"BuildInfo.GoVersion", Field, 18}, + {"BuildInfo.Main", Field, 12}, + {"BuildInfo.Path", Field, 12}, + {"BuildInfo.Settings", Field, 18}, + {"BuildSetting", Type, 18}, + {"BuildSetting.Key", Field, 18}, + {"BuildSetting.Value", Field, 18}, + {"CrashOptions", Type, 23}, + {"FreeOSMemory", Func, 1}, + {"GCStats", Type, 1}, + {"GCStats.LastGC", Field, 1}, + {"GCStats.NumGC", Field, 1}, + {"GCStats.Pause", Field, 1}, + {"GCStats.PauseEnd", Field, 4}, + {"GCStats.PauseQuantiles", Field, 1}, + {"GCStats.PauseTotal", Field, 1}, + {"Module", Type, 12}, + {"Module.Path", Field, 12}, + {"Module.Replace", Field, 12}, + {"Module.Sum", Field, 12}, + {"Module.Version", Field, 12}, + {"ParseBuildInfo", Func, 18}, + {"PrintStack", Func, 0}, + {"ReadBuildInfo", Func, 12}, + {"ReadGCStats", Func, 1}, + {"SetCrashOutput", Func, 23}, + {"SetGCPercent", Func, 1}, + {"SetMaxStack", Func, 2}, + {"SetMaxThreads", Func, 2}, + {"SetMemoryLimit", Func, 19}, + {"SetPanicOnFault", Func, 3}, + {"SetTraceback", Func, 6}, + {"Stack", Func, 0}, + {"WriteHeapDump", Func, 3}, + }, + "runtime/metrics": { + {"(Value).Float64", Method, 16}, + {"(Value).Float64Histogram", Method, 16}, + {"(Value).Kind", Method, 16}, + {"(Value).Uint64", Method, 16}, + {"All", Func, 16}, + {"Description", Type, 16}, + {"Description.Cumulative", Field, 16}, + {"Description.Description", Field, 16}, + {"Description.Kind", Field, 16}, + {"Description.Name", Field, 16}, + {"Float64Histogram", Type, 16}, + {"Float64Histogram.Buckets", Field, 16}, + {"Float64Histogram.Counts", Field, 16}, + {"KindBad", Const, 16}, + {"KindFloat64", Const, 16}, + {"KindFloat64Histogram", Const, 16}, + {"KindUint64", Const, 16}, + {"Read", Func, 16}, + {"Sample", Type, 16}, + {"Sample.Name", Field, 16}, + {"Sample.Value", Field, 16}, + {"Value", Type, 16}, + {"ValueKind", Type, 16}, + }, + "runtime/pprof": { + {"(*Profile).Add", Method, 0}, + {"(*Profile).Count", Method, 0}, + {"(*Profile).Name", Method, 0}, + {"(*Profile).Remove", Method, 0}, + {"(*Profile).WriteTo", Method, 0}, + {"Do", Func, 9}, + {"ForLabels", Func, 9}, + {"Label", Func, 9}, + {"LabelSet", Type, 9}, + {"Labels", Func, 9}, + {"Lookup", Func, 0}, + {"NewProfile", Func, 0}, + {"Profile", Type, 0}, + {"Profiles", Func, 0}, + {"SetGoroutineLabels", Func, 9}, + {"StartCPUProfile", Func, 0}, + {"StopCPUProfile", Func, 0}, + {"WithLabels", Func, 9}, + {"WriteHeapProfile", Func, 0}, + }, + "runtime/trace": { + {"(*Region).End", Method, 11}, + {"(*Task).End", Method, 11}, + {"IsEnabled", Func, 11}, + {"Log", Func, 11}, + {"Logf", Func, 11}, + {"NewTask", Func, 11}, + {"Region", Type, 11}, + {"Start", Func, 5}, + {"StartRegion", Func, 11}, + {"Stop", Func, 5}, + {"Task", Type, 11}, + {"WithRegion", Func, 11}, + }, + "slices": { + {"All", Func, 23}, + {"AppendSeq", Func, 23}, + {"Backward", Func, 23}, + {"BinarySearch", Func, 21}, + {"BinarySearchFunc", Func, 21}, + {"Chunk", Func, 23}, + {"Clip", Func, 21}, + {"Clone", Func, 21}, + {"Collect", Func, 23}, + {"Compact", Func, 21}, + {"CompactFunc", Func, 21}, + {"Compare", Func, 21}, + {"CompareFunc", Func, 21}, + {"Concat", Func, 22}, + {"Contains", Func, 21}, + {"ContainsFunc", Func, 21}, + {"Delete", Func, 21}, + {"DeleteFunc", Func, 21}, + {"Equal", Func, 21}, + {"EqualFunc", Func, 21}, + {"Grow", Func, 21}, + {"Index", Func, 21}, + {"IndexFunc", Func, 21}, + {"Insert", Func, 21}, + {"IsSorted", Func, 21}, + {"IsSortedFunc", Func, 21}, + {"Max", Func, 21}, + {"MaxFunc", Func, 21}, + {"Min", Func, 21}, + {"MinFunc", Func, 21}, + {"Repeat", Func, 23}, + {"Replace", Func, 21}, + {"Reverse", Func, 21}, + {"Sort", Func, 21}, + {"SortFunc", Func, 21}, + {"SortStableFunc", Func, 21}, + {"Sorted", Func, 23}, + {"SortedFunc", Func, 23}, + {"SortedStableFunc", Func, 23}, + {"Values", Func, 23}, + }, + "sort": { + {"(Float64Slice).Len", Method, 0}, + {"(Float64Slice).Less", Method, 0}, + {"(Float64Slice).Search", Method, 0}, + {"(Float64Slice).Sort", Method, 0}, + {"(Float64Slice).Swap", Method, 0}, + {"(IntSlice).Len", Method, 0}, + {"(IntSlice).Less", Method, 0}, + {"(IntSlice).Search", Method, 0}, + {"(IntSlice).Sort", Method, 0}, + {"(IntSlice).Swap", Method, 0}, + {"(StringSlice).Len", Method, 0}, + {"(StringSlice).Less", Method, 0}, + {"(StringSlice).Search", Method, 0}, + {"(StringSlice).Sort", Method, 0}, + {"(StringSlice).Swap", Method, 0}, + {"Find", Func, 19}, + {"Float64Slice", Type, 0}, + {"Float64s", Func, 0}, + {"Float64sAreSorted", Func, 0}, + {"IntSlice", Type, 0}, + {"Interface", Type, 0}, + {"Ints", Func, 0}, + {"IntsAreSorted", Func, 0}, + {"IsSorted", Func, 0}, + {"Reverse", Func, 1}, + {"Search", Func, 0}, + {"SearchFloat64s", Func, 0}, + {"SearchInts", Func, 0}, + {"SearchStrings", Func, 0}, + {"Slice", Func, 8}, + {"SliceIsSorted", Func, 8}, + {"SliceStable", Func, 8}, + {"Sort", Func, 0}, + {"Stable", Func, 2}, + {"StringSlice", Type, 0}, + {"Strings", Func, 0}, + {"StringsAreSorted", Func, 0}, + }, + "strconv": { + {"(*NumError).Error", Method, 0}, + {"(*NumError).Unwrap", Method, 14}, + {"AppendBool", Func, 0}, + {"AppendFloat", Func, 0}, + {"AppendInt", Func, 0}, + {"AppendQuote", Func, 0}, + {"AppendQuoteRune", Func, 0}, + {"AppendQuoteRuneToASCII", Func, 0}, + {"AppendQuoteRuneToGraphic", Func, 6}, + {"AppendQuoteToASCII", Func, 0}, + {"AppendQuoteToGraphic", Func, 6}, + {"AppendUint", Func, 0}, + {"Atoi", Func, 0}, + {"CanBackquote", Func, 0}, + {"ErrRange", Var, 0}, + {"ErrSyntax", Var, 0}, + {"FormatBool", Func, 0}, + {"FormatComplex", Func, 15}, + {"FormatFloat", Func, 0}, + {"FormatInt", Func, 0}, + {"FormatUint", Func, 0}, + {"IntSize", Const, 0}, + {"IsGraphic", Func, 6}, + {"IsPrint", Func, 0}, + {"Itoa", Func, 0}, + {"NumError", Type, 0}, + {"NumError.Err", Field, 0}, + {"NumError.Func", Field, 0}, + {"NumError.Num", Field, 0}, + {"ParseBool", Func, 0}, + {"ParseComplex", Func, 15}, + {"ParseFloat", Func, 0}, + {"ParseInt", Func, 0}, + {"ParseUint", Func, 0}, + {"Quote", Func, 0}, + {"QuoteRune", Func, 0}, + {"QuoteRuneToASCII", Func, 0}, + {"QuoteRuneToGraphic", Func, 6}, + {"QuoteToASCII", Func, 0}, + {"QuoteToGraphic", Func, 6}, + {"QuotedPrefix", Func, 17}, + {"Unquote", Func, 0}, + {"UnquoteChar", Func, 0}, + }, + "strings": { + {"(*Builder).Cap", Method, 12}, + {"(*Builder).Grow", Method, 10}, + {"(*Builder).Len", Method, 10}, + {"(*Builder).Reset", Method, 10}, + {"(*Builder).String", Method, 10}, + {"(*Builder).Write", Method, 10}, + {"(*Builder).WriteByte", Method, 10}, + {"(*Builder).WriteRune", Method, 10}, + {"(*Builder).WriteString", Method, 10}, + {"(*Reader).Len", Method, 0}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).ReadAt", Method, 0}, + {"(*Reader).ReadByte", Method, 0}, + {"(*Reader).ReadRune", Method, 0}, + {"(*Reader).Reset", Method, 7}, + {"(*Reader).Seek", Method, 0}, + {"(*Reader).Size", Method, 5}, + {"(*Reader).UnreadByte", Method, 0}, + {"(*Reader).UnreadRune", Method, 0}, + {"(*Reader).WriteTo", Method, 1}, + {"(*Replacer).Replace", Method, 0}, + {"(*Replacer).WriteString", Method, 0}, + {"Builder", Type, 10}, + {"Clone", Func, 18}, + {"Compare", Func, 5}, + {"Contains", Func, 0}, + {"ContainsAny", Func, 0}, + {"ContainsFunc", Func, 21}, + {"ContainsRune", Func, 0}, + {"Count", Func, 0}, + {"Cut", Func, 18}, + {"CutPrefix", Func, 20}, + {"CutSuffix", Func, 20}, + {"EqualFold", Func, 0}, + {"Fields", Func, 0}, + {"FieldsFunc", Func, 0}, + {"HasPrefix", Func, 0}, + {"HasSuffix", Func, 0}, + {"Index", Func, 0}, + {"IndexAny", Func, 0}, + {"IndexByte", Func, 2}, + {"IndexFunc", Func, 0}, + {"IndexRune", Func, 0}, + {"Join", Func, 0}, + {"LastIndex", Func, 0}, + {"LastIndexAny", Func, 0}, + {"LastIndexByte", Func, 5}, + {"LastIndexFunc", Func, 0}, + {"Map", Func, 0}, + {"NewReader", Func, 0}, + {"NewReplacer", Func, 0}, + {"Reader", Type, 0}, + {"Repeat", Func, 0}, + {"Replace", Func, 0}, + {"ReplaceAll", Func, 12}, + {"Replacer", Type, 0}, + {"Split", Func, 0}, + {"SplitAfter", Func, 0}, + {"SplitAfterN", Func, 0}, + {"SplitN", Func, 0}, + {"Title", Func, 0}, + {"ToLower", Func, 0}, + {"ToLowerSpecial", Func, 0}, + {"ToTitle", Func, 0}, + {"ToTitleSpecial", Func, 0}, + {"ToUpper", Func, 0}, + {"ToUpperSpecial", Func, 0}, + {"ToValidUTF8", Func, 13}, + {"Trim", Func, 0}, + {"TrimFunc", Func, 0}, + {"TrimLeft", Func, 0}, + {"TrimLeftFunc", Func, 0}, + {"TrimPrefix", Func, 1}, + {"TrimRight", Func, 0}, + {"TrimRightFunc", Func, 0}, + {"TrimSpace", Func, 0}, + {"TrimSuffix", Func, 1}, + }, + "structs": { + {"HostLayout", Type, 23}, + }, + "sync": { + {"(*Cond).Broadcast", Method, 0}, + {"(*Cond).Signal", Method, 0}, + {"(*Cond).Wait", Method, 0}, + {"(*Map).Clear", Method, 23}, + {"(*Map).CompareAndDelete", Method, 20}, + {"(*Map).CompareAndSwap", Method, 20}, + {"(*Map).Delete", Method, 9}, + {"(*Map).Load", Method, 9}, + {"(*Map).LoadAndDelete", Method, 15}, + {"(*Map).LoadOrStore", Method, 9}, + {"(*Map).Range", Method, 9}, + {"(*Map).Store", Method, 9}, + {"(*Map).Swap", Method, 20}, + {"(*Mutex).Lock", Method, 0}, + {"(*Mutex).TryLock", Method, 18}, + {"(*Mutex).Unlock", Method, 0}, + {"(*Once).Do", Method, 0}, + {"(*Pool).Get", Method, 3}, + {"(*Pool).Put", Method, 3}, + {"(*RWMutex).Lock", Method, 0}, + {"(*RWMutex).RLock", Method, 0}, + {"(*RWMutex).RLocker", Method, 0}, + {"(*RWMutex).RUnlock", Method, 0}, + {"(*RWMutex).TryLock", Method, 18}, + {"(*RWMutex).TryRLock", Method, 18}, + {"(*RWMutex).Unlock", Method, 0}, + {"(*WaitGroup).Add", Method, 0}, + {"(*WaitGroup).Done", Method, 0}, + {"(*WaitGroup).Wait", Method, 0}, + {"Cond", Type, 0}, + {"Cond.L", Field, 0}, + {"Locker", Type, 0}, + {"Map", Type, 9}, + {"Mutex", Type, 0}, + {"NewCond", Func, 0}, + {"Once", Type, 0}, + {"OnceFunc", Func, 21}, + {"OnceValue", Func, 21}, + {"OnceValues", Func, 21}, + {"Pool", Type, 3}, + {"Pool.New", Field, 3}, + {"RWMutex", Type, 0}, + {"WaitGroup", Type, 0}, + }, + "sync/atomic": { + {"(*Bool).CompareAndSwap", Method, 19}, + {"(*Bool).Load", Method, 19}, + {"(*Bool).Store", Method, 19}, + {"(*Bool).Swap", Method, 19}, + {"(*Int32).Add", Method, 19}, + {"(*Int32).And", Method, 23}, + {"(*Int32).CompareAndSwap", Method, 19}, + {"(*Int32).Load", Method, 19}, + {"(*Int32).Or", Method, 23}, + {"(*Int32).Store", Method, 19}, + {"(*Int32).Swap", Method, 19}, + {"(*Int64).Add", Method, 19}, + {"(*Int64).And", Method, 23}, + {"(*Int64).CompareAndSwap", Method, 19}, + {"(*Int64).Load", Method, 19}, + {"(*Int64).Or", Method, 23}, + {"(*Int64).Store", Method, 19}, + {"(*Int64).Swap", Method, 19}, + {"(*Pointer).CompareAndSwap", Method, 19}, + {"(*Pointer).Load", Method, 19}, + {"(*Pointer).Store", Method, 19}, + {"(*Pointer).Swap", Method, 19}, + {"(*Uint32).Add", Method, 19}, + {"(*Uint32).And", Method, 23}, + {"(*Uint32).CompareAndSwap", Method, 19}, + {"(*Uint32).Load", Method, 19}, + {"(*Uint32).Or", Method, 23}, + {"(*Uint32).Store", Method, 19}, + {"(*Uint32).Swap", Method, 19}, + {"(*Uint64).Add", Method, 19}, + {"(*Uint64).And", Method, 23}, + {"(*Uint64).CompareAndSwap", Method, 19}, + {"(*Uint64).Load", Method, 19}, + {"(*Uint64).Or", Method, 23}, + {"(*Uint64).Store", Method, 19}, + {"(*Uint64).Swap", Method, 19}, + {"(*Uintptr).Add", Method, 19}, + {"(*Uintptr).And", Method, 23}, + {"(*Uintptr).CompareAndSwap", Method, 19}, + {"(*Uintptr).Load", Method, 19}, + {"(*Uintptr).Or", Method, 23}, + {"(*Uintptr).Store", Method, 19}, + {"(*Uintptr).Swap", Method, 19}, + {"(*Value).CompareAndSwap", Method, 17}, + {"(*Value).Load", Method, 4}, + {"(*Value).Store", Method, 4}, + {"(*Value).Swap", Method, 17}, + {"AddInt32", Func, 0}, + {"AddInt64", Func, 0}, + {"AddUint32", Func, 0}, + {"AddUint64", Func, 0}, + {"AddUintptr", Func, 0}, + {"AndInt32", Func, 23}, + {"AndInt64", Func, 23}, + {"AndUint32", Func, 23}, + {"AndUint64", Func, 23}, + {"AndUintptr", Func, 23}, + {"Bool", Type, 19}, + {"CompareAndSwapInt32", Func, 0}, + {"CompareAndSwapInt64", Func, 0}, + {"CompareAndSwapPointer", Func, 0}, + {"CompareAndSwapUint32", Func, 0}, + {"CompareAndSwapUint64", Func, 0}, + {"CompareAndSwapUintptr", Func, 0}, + {"Int32", Type, 19}, + {"Int64", Type, 19}, + {"LoadInt32", Func, 0}, + {"LoadInt64", Func, 0}, + {"LoadPointer", Func, 0}, + {"LoadUint32", Func, 0}, + {"LoadUint64", Func, 0}, + {"LoadUintptr", Func, 0}, + {"OrInt32", Func, 23}, + {"OrInt64", Func, 23}, + {"OrUint32", Func, 23}, + {"OrUint64", Func, 23}, + {"OrUintptr", Func, 23}, + {"Pointer", Type, 19}, + {"StoreInt32", Func, 0}, + {"StoreInt64", Func, 0}, + {"StorePointer", Func, 0}, + {"StoreUint32", Func, 0}, + {"StoreUint64", Func, 0}, + {"StoreUintptr", Func, 0}, + {"SwapInt32", Func, 2}, + {"SwapInt64", Func, 2}, + {"SwapPointer", Func, 2}, + {"SwapUint32", Func, 2}, + {"SwapUint64", Func, 2}, + {"SwapUintptr", Func, 2}, + {"Uint32", Type, 19}, + {"Uint64", Type, 19}, + {"Uintptr", Type, 19}, + {"Value", Type, 4}, + }, + "syscall": { + {"(*Cmsghdr).SetLen", Method, 0}, + {"(*DLL).FindProc", Method, 0}, + {"(*DLL).MustFindProc", Method, 0}, + {"(*DLL).Release", Method, 0}, + {"(*DLLError).Error", Method, 0}, + {"(*DLLError).Unwrap", Method, 16}, + {"(*Filetime).Nanoseconds", Method, 0}, + {"(*Iovec).SetLen", Method, 0}, + {"(*LazyDLL).Handle", Method, 0}, + {"(*LazyDLL).Load", Method, 0}, + {"(*LazyDLL).NewProc", Method, 0}, + {"(*LazyProc).Addr", Method, 0}, + {"(*LazyProc).Call", Method, 0}, + {"(*LazyProc).Find", Method, 0}, + {"(*Msghdr).SetControllen", Method, 0}, + {"(*Proc).Addr", Method, 0}, + {"(*Proc).Call", Method, 0}, + {"(*PtraceRegs).PC", Method, 0}, + {"(*PtraceRegs).SetPC", Method, 0}, + {"(*RawSockaddrAny).Sockaddr", Method, 0}, + {"(*SID).Copy", Method, 0}, + {"(*SID).Len", Method, 0}, + {"(*SID).LookupAccount", Method, 0}, + {"(*SID).String", Method, 0}, + {"(*Timespec).Nano", Method, 0}, + {"(*Timespec).Unix", Method, 0}, + {"(*Timeval).Nano", Method, 0}, + {"(*Timeval).Nanoseconds", Method, 0}, + {"(*Timeval).Unix", Method, 0}, + {"(Errno).Error", Method, 0}, + {"(Errno).Is", Method, 13}, + {"(Errno).Temporary", Method, 0}, + {"(Errno).Timeout", Method, 0}, + {"(Signal).Signal", Method, 0}, + {"(Signal).String", Method, 0}, + {"(Token).Close", Method, 0}, + {"(Token).GetTokenPrimaryGroup", Method, 0}, + {"(Token).GetTokenUser", Method, 0}, + {"(Token).GetUserProfileDirectory", Method, 0}, + {"(WaitStatus).Continued", Method, 0}, + {"(WaitStatus).CoreDump", Method, 0}, + {"(WaitStatus).ExitStatus", Method, 0}, + {"(WaitStatus).Exited", Method, 0}, + {"(WaitStatus).Signal", Method, 0}, + {"(WaitStatus).Signaled", Method, 0}, + {"(WaitStatus).StopSignal", Method, 0}, + {"(WaitStatus).Stopped", Method, 0}, + {"(WaitStatus).TrapCause", Method, 0}, + {"AF_ALG", Const, 0}, + {"AF_APPLETALK", Const, 0}, + {"AF_ARP", Const, 0}, + {"AF_ASH", Const, 0}, + {"AF_ATM", Const, 0}, + {"AF_ATMPVC", Const, 0}, + {"AF_ATMSVC", Const, 0}, + {"AF_AX25", Const, 0}, + {"AF_BLUETOOTH", Const, 0}, + {"AF_BRIDGE", Const, 0}, + {"AF_CAIF", Const, 0}, + {"AF_CAN", Const, 0}, + {"AF_CCITT", Const, 0}, + {"AF_CHAOS", Const, 0}, + {"AF_CNT", Const, 0}, + {"AF_COIP", Const, 0}, + {"AF_DATAKIT", Const, 0}, + {"AF_DECnet", Const, 0}, + {"AF_DLI", Const, 0}, + {"AF_E164", Const, 0}, + {"AF_ECMA", Const, 0}, + {"AF_ECONET", Const, 0}, + {"AF_ENCAP", Const, 1}, + {"AF_FILE", Const, 0}, + {"AF_HYLINK", Const, 0}, + {"AF_IEEE80211", Const, 0}, + {"AF_IEEE802154", Const, 0}, + {"AF_IMPLINK", Const, 0}, + {"AF_INET", Const, 0}, + {"AF_INET6", Const, 0}, + {"AF_INET6_SDP", Const, 3}, + {"AF_INET_SDP", Const, 3}, + {"AF_IPX", Const, 0}, + {"AF_IRDA", Const, 0}, + {"AF_ISDN", Const, 0}, + {"AF_ISO", Const, 0}, + {"AF_IUCV", Const, 0}, + {"AF_KEY", Const, 0}, + {"AF_LAT", Const, 0}, + {"AF_LINK", Const, 0}, + {"AF_LLC", Const, 0}, + {"AF_LOCAL", Const, 0}, + {"AF_MAX", Const, 0}, + {"AF_MPLS", Const, 1}, + {"AF_NATM", Const, 0}, + {"AF_NDRV", Const, 0}, + {"AF_NETBEUI", Const, 0}, + {"AF_NETBIOS", Const, 0}, + {"AF_NETGRAPH", Const, 0}, + {"AF_NETLINK", Const, 0}, + {"AF_NETROM", Const, 0}, + {"AF_NS", Const, 0}, + {"AF_OROUTE", Const, 1}, + {"AF_OSI", Const, 0}, + {"AF_PACKET", Const, 0}, + {"AF_PHONET", Const, 0}, + {"AF_PPP", Const, 0}, + {"AF_PPPOX", Const, 0}, + {"AF_PUP", Const, 0}, + {"AF_RDS", Const, 0}, + {"AF_RESERVED_36", Const, 0}, + {"AF_ROSE", Const, 0}, + {"AF_ROUTE", Const, 0}, + {"AF_RXRPC", Const, 0}, + {"AF_SCLUSTER", Const, 0}, + {"AF_SECURITY", Const, 0}, + {"AF_SIP", Const, 0}, + {"AF_SLOW", Const, 0}, + {"AF_SNA", Const, 0}, + {"AF_SYSTEM", Const, 0}, + {"AF_TIPC", Const, 0}, + {"AF_UNIX", Const, 0}, + {"AF_UNSPEC", Const, 0}, + {"AF_UTUN", Const, 16}, + {"AF_VENDOR00", Const, 0}, + {"AF_VENDOR01", Const, 0}, + {"AF_VENDOR02", Const, 0}, + {"AF_VENDOR03", Const, 0}, + {"AF_VENDOR04", Const, 0}, + {"AF_VENDOR05", Const, 0}, + {"AF_VENDOR06", Const, 0}, + {"AF_VENDOR07", Const, 0}, + {"AF_VENDOR08", Const, 0}, + {"AF_VENDOR09", Const, 0}, + {"AF_VENDOR10", Const, 0}, + {"AF_VENDOR11", Const, 0}, + {"AF_VENDOR12", Const, 0}, + {"AF_VENDOR13", Const, 0}, + {"AF_VENDOR14", Const, 0}, + {"AF_VENDOR15", Const, 0}, + {"AF_VENDOR16", Const, 0}, + {"AF_VENDOR17", Const, 0}, + {"AF_VENDOR18", Const, 0}, + {"AF_VENDOR19", Const, 0}, + {"AF_VENDOR20", Const, 0}, + {"AF_VENDOR21", Const, 0}, + {"AF_VENDOR22", Const, 0}, + {"AF_VENDOR23", Const, 0}, + {"AF_VENDOR24", Const, 0}, + {"AF_VENDOR25", Const, 0}, + {"AF_VENDOR26", Const, 0}, + {"AF_VENDOR27", Const, 0}, + {"AF_VENDOR28", Const, 0}, + {"AF_VENDOR29", Const, 0}, + {"AF_VENDOR30", Const, 0}, + {"AF_VENDOR31", Const, 0}, + {"AF_VENDOR32", Const, 0}, + {"AF_VENDOR33", Const, 0}, + {"AF_VENDOR34", Const, 0}, + {"AF_VENDOR35", Const, 0}, + {"AF_VENDOR36", Const, 0}, + {"AF_VENDOR37", Const, 0}, + {"AF_VENDOR38", Const, 0}, + {"AF_VENDOR39", Const, 0}, + {"AF_VENDOR40", Const, 0}, + {"AF_VENDOR41", Const, 0}, + {"AF_VENDOR42", Const, 0}, + {"AF_VENDOR43", Const, 0}, + {"AF_VENDOR44", Const, 0}, + {"AF_VENDOR45", Const, 0}, + {"AF_VENDOR46", Const, 0}, + {"AF_VENDOR47", Const, 0}, + {"AF_WANPIPE", Const, 0}, + {"AF_X25", Const, 0}, + {"AI_CANONNAME", Const, 1}, + {"AI_NUMERICHOST", Const, 1}, + {"AI_PASSIVE", Const, 1}, + {"APPLICATION_ERROR", Const, 0}, + {"ARPHRD_ADAPT", Const, 0}, + {"ARPHRD_APPLETLK", Const, 0}, + {"ARPHRD_ARCNET", Const, 0}, + {"ARPHRD_ASH", Const, 0}, + {"ARPHRD_ATM", Const, 0}, + {"ARPHRD_AX25", Const, 0}, + {"ARPHRD_BIF", Const, 0}, + {"ARPHRD_CHAOS", Const, 0}, + {"ARPHRD_CISCO", Const, 0}, + {"ARPHRD_CSLIP", Const, 0}, + {"ARPHRD_CSLIP6", Const, 0}, + {"ARPHRD_DDCMP", Const, 0}, + {"ARPHRD_DLCI", Const, 0}, + {"ARPHRD_ECONET", Const, 0}, + {"ARPHRD_EETHER", Const, 0}, + {"ARPHRD_ETHER", Const, 0}, + {"ARPHRD_EUI64", Const, 0}, + {"ARPHRD_FCAL", Const, 0}, + {"ARPHRD_FCFABRIC", Const, 0}, + {"ARPHRD_FCPL", Const, 0}, + {"ARPHRD_FCPP", Const, 0}, + {"ARPHRD_FDDI", Const, 0}, + {"ARPHRD_FRAD", Const, 0}, + {"ARPHRD_FRELAY", Const, 1}, + {"ARPHRD_HDLC", Const, 0}, + {"ARPHRD_HIPPI", Const, 0}, + {"ARPHRD_HWX25", Const, 0}, + {"ARPHRD_IEEE1394", Const, 0}, + {"ARPHRD_IEEE802", Const, 0}, + {"ARPHRD_IEEE80211", Const, 0}, + {"ARPHRD_IEEE80211_PRISM", Const, 0}, + {"ARPHRD_IEEE80211_RADIOTAP", Const, 0}, + {"ARPHRD_IEEE802154", Const, 0}, + {"ARPHRD_IEEE802154_PHY", Const, 0}, + {"ARPHRD_IEEE802_TR", Const, 0}, + {"ARPHRD_INFINIBAND", Const, 0}, + {"ARPHRD_IPDDP", Const, 0}, + {"ARPHRD_IPGRE", Const, 0}, + {"ARPHRD_IRDA", Const, 0}, + {"ARPHRD_LAPB", Const, 0}, + {"ARPHRD_LOCALTLK", Const, 0}, + {"ARPHRD_LOOPBACK", Const, 0}, + {"ARPHRD_METRICOM", Const, 0}, + {"ARPHRD_NETROM", Const, 0}, + {"ARPHRD_NONE", Const, 0}, + {"ARPHRD_PIMREG", Const, 0}, + {"ARPHRD_PPP", Const, 0}, + {"ARPHRD_PRONET", Const, 0}, + {"ARPHRD_RAWHDLC", Const, 0}, + {"ARPHRD_ROSE", Const, 0}, + {"ARPHRD_RSRVD", Const, 0}, + {"ARPHRD_SIT", Const, 0}, + {"ARPHRD_SKIP", Const, 0}, + {"ARPHRD_SLIP", Const, 0}, + {"ARPHRD_SLIP6", Const, 0}, + {"ARPHRD_STRIP", Const, 1}, + {"ARPHRD_TUNNEL", Const, 0}, + {"ARPHRD_TUNNEL6", Const, 0}, + {"ARPHRD_VOID", Const, 0}, + {"ARPHRD_X25", Const, 0}, + {"AUTHTYPE_CLIENT", Const, 0}, + {"AUTHTYPE_SERVER", Const, 0}, + {"Accept", Func, 0}, + {"Accept4", Func, 1}, + {"AcceptEx", Func, 0}, + {"Access", Func, 0}, + {"Acct", Func, 0}, + {"AddrinfoW", Type, 1}, + {"AddrinfoW.Addr", Field, 1}, + {"AddrinfoW.Addrlen", Field, 1}, + {"AddrinfoW.Canonname", Field, 1}, + {"AddrinfoW.Family", Field, 1}, + {"AddrinfoW.Flags", Field, 1}, + {"AddrinfoW.Next", Field, 1}, + {"AddrinfoW.Protocol", Field, 1}, + {"AddrinfoW.Socktype", Field, 1}, + {"Adjtime", Func, 0}, + {"Adjtimex", Func, 0}, + {"AllThreadsSyscall", Func, 16}, + {"AllThreadsSyscall6", Func, 16}, + {"AttachLsf", Func, 0}, + {"B0", Const, 0}, + {"B1000000", Const, 0}, + {"B110", Const, 0}, + {"B115200", Const, 0}, + {"B1152000", Const, 0}, + {"B1200", Const, 0}, + {"B134", Const, 0}, + {"B14400", Const, 1}, + {"B150", Const, 0}, + {"B1500000", Const, 0}, + {"B1800", Const, 0}, + {"B19200", Const, 0}, + {"B200", Const, 0}, + {"B2000000", Const, 0}, + {"B230400", Const, 0}, + {"B2400", Const, 0}, + {"B2500000", Const, 0}, + {"B28800", Const, 1}, + {"B300", Const, 0}, + {"B3000000", Const, 0}, + {"B3500000", Const, 0}, + {"B38400", Const, 0}, + {"B4000000", Const, 0}, + {"B460800", Const, 0}, + {"B4800", Const, 0}, + {"B50", Const, 0}, + {"B500000", Const, 0}, + {"B57600", Const, 0}, + {"B576000", Const, 0}, + {"B600", Const, 0}, + {"B7200", Const, 1}, + {"B75", Const, 0}, + {"B76800", Const, 1}, + {"B921600", Const, 0}, + {"B9600", Const, 0}, + {"BASE_PROTOCOL", Const, 2}, + {"BIOCFEEDBACK", Const, 0}, + {"BIOCFLUSH", Const, 0}, + {"BIOCGBLEN", Const, 0}, + {"BIOCGDIRECTION", Const, 0}, + {"BIOCGDIRFILT", Const, 1}, + {"BIOCGDLT", Const, 0}, + {"BIOCGDLTLIST", Const, 0}, + {"BIOCGETBUFMODE", Const, 0}, + {"BIOCGETIF", Const, 0}, + {"BIOCGETZMAX", Const, 0}, + {"BIOCGFEEDBACK", Const, 1}, + {"BIOCGFILDROP", Const, 1}, + {"BIOCGHDRCMPLT", Const, 0}, + {"BIOCGRSIG", Const, 0}, + {"BIOCGRTIMEOUT", Const, 0}, + {"BIOCGSEESENT", Const, 0}, + {"BIOCGSTATS", Const, 0}, + {"BIOCGSTATSOLD", Const, 1}, + {"BIOCGTSTAMP", Const, 1}, + {"BIOCIMMEDIATE", Const, 0}, + {"BIOCLOCK", Const, 0}, + {"BIOCPROMISC", Const, 0}, + {"BIOCROTZBUF", Const, 0}, + {"BIOCSBLEN", Const, 0}, + {"BIOCSDIRECTION", Const, 0}, + {"BIOCSDIRFILT", Const, 1}, + {"BIOCSDLT", Const, 0}, + {"BIOCSETBUFMODE", Const, 0}, + {"BIOCSETF", Const, 0}, + {"BIOCSETFNR", Const, 0}, + {"BIOCSETIF", Const, 0}, + {"BIOCSETWF", Const, 0}, + {"BIOCSETZBUF", Const, 0}, + {"BIOCSFEEDBACK", Const, 1}, + {"BIOCSFILDROP", Const, 1}, + {"BIOCSHDRCMPLT", Const, 0}, + {"BIOCSRSIG", Const, 0}, + {"BIOCSRTIMEOUT", Const, 0}, + {"BIOCSSEESENT", Const, 0}, + {"BIOCSTCPF", Const, 1}, + {"BIOCSTSTAMP", Const, 1}, + {"BIOCSUDPF", Const, 1}, + {"BIOCVERSION", Const, 0}, + {"BPF_A", Const, 0}, + {"BPF_ABS", Const, 0}, + {"BPF_ADD", Const, 0}, + {"BPF_ALIGNMENT", Const, 0}, + {"BPF_ALIGNMENT32", Const, 1}, + {"BPF_ALU", Const, 0}, + {"BPF_AND", Const, 0}, + {"BPF_B", Const, 0}, + {"BPF_BUFMODE_BUFFER", Const, 0}, + {"BPF_BUFMODE_ZBUF", Const, 0}, + {"BPF_DFLTBUFSIZE", Const, 1}, + {"BPF_DIRECTION_IN", Const, 1}, + {"BPF_DIRECTION_OUT", Const, 1}, + {"BPF_DIV", Const, 0}, + {"BPF_H", Const, 0}, + {"BPF_IMM", Const, 0}, + {"BPF_IND", Const, 0}, + {"BPF_JA", Const, 0}, + {"BPF_JEQ", Const, 0}, + {"BPF_JGE", Const, 0}, + {"BPF_JGT", Const, 0}, + {"BPF_JMP", Const, 0}, + {"BPF_JSET", Const, 0}, + {"BPF_K", Const, 0}, + {"BPF_LD", Const, 0}, + {"BPF_LDX", Const, 0}, + {"BPF_LEN", Const, 0}, + {"BPF_LSH", Const, 0}, + {"BPF_MAJOR_VERSION", Const, 0}, + {"BPF_MAXBUFSIZE", Const, 0}, + {"BPF_MAXINSNS", Const, 0}, + {"BPF_MEM", Const, 0}, + {"BPF_MEMWORDS", Const, 0}, + {"BPF_MINBUFSIZE", Const, 0}, + {"BPF_MINOR_VERSION", Const, 0}, + {"BPF_MISC", Const, 0}, + {"BPF_MSH", Const, 0}, + {"BPF_MUL", Const, 0}, + {"BPF_NEG", Const, 0}, + {"BPF_OR", Const, 0}, + {"BPF_RELEASE", Const, 0}, + {"BPF_RET", Const, 0}, + {"BPF_RSH", Const, 0}, + {"BPF_ST", Const, 0}, + {"BPF_STX", Const, 0}, + {"BPF_SUB", Const, 0}, + {"BPF_TAX", Const, 0}, + {"BPF_TXA", Const, 0}, + {"BPF_T_BINTIME", Const, 1}, + {"BPF_T_BINTIME_FAST", Const, 1}, + {"BPF_T_BINTIME_MONOTONIC", Const, 1}, + {"BPF_T_BINTIME_MONOTONIC_FAST", Const, 1}, + {"BPF_T_FAST", Const, 1}, + {"BPF_T_FLAG_MASK", Const, 1}, + {"BPF_T_FORMAT_MASK", Const, 1}, + {"BPF_T_MICROTIME", Const, 1}, + {"BPF_T_MICROTIME_FAST", Const, 1}, + {"BPF_T_MICROTIME_MONOTONIC", Const, 1}, + {"BPF_T_MICROTIME_MONOTONIC_FAST", Const, 1}, + {"BPF_T_MONOTONIC", Const, 1}, + {"BPF_T_MONOTONIC_FAST", Const, 1}, + {"BPF_T_NANOTIME", Const, 1}, + {"BPF_T_NANOTIME_FAST", Const, 1}, + {"BPF_T_NANOTIME_MONOTONIC", Const, 1}, + {"BPF_T_NANOTIME_MONOTONIC_FAST", Const, 1}, + {"BPF_T_NONE", Const, 1}, + {"BPF_T_NORMAL", Const, 1}, + {"BPF_W", Const, 0}, + {"BPF_X", Const, 0}, + {"BRKINT", Const, 0}, + {"Bind", Func, 0}, + {"BindToDevice", Func, 0}, + {"BpfBuflen", Func, 0}, + {"BpfDatalink", Func, 0}, + {"BpfHdr", Type, 0}, + {"BpfHdr.Caplen", Field, 0}, + {"BpfHdr.Datalen", Field, 0}, + {"BpfHdr.Hdrlen", Field, 0}, + {"BpfHdr.Pad_cgo_0", Field, 0}, + {"BpfHdr.Tstamp", Field, 0}, + {"BpfHeadercmpl", Func, 0}, + {"BpfInsn", Type, 0}, + {"BpfInsn.Code", Field, 0}, + {"BpfInsn.Jf", Field, 0}, + {"BpfInsn.Jt", Field, 0}, + {"BpfInsn.K", Field, 0}, + {"BpfInterface", Func, 0}, + {"BpfJump", Func, 0}, + {"BpfProgram", Type, 0}, + {"BpfProgram.Insns", Field, 0}, + {"BpfProgram.Len", Field, 0}, + {"BpfProgram.Pad_cgo_0", Field, 0}, + {"BpfStat", Type, 0}, + {"BpfStat.Capt", Field, 2}, + {"BpfStat.Drop", Field, 0}, + {"BpfStat.Padding", Field, 2}, + {"BpfStat.Recv", Field, 0}, + {"BpfStats", Func, 0}, + {"BpfStmt", Func, 0}, + {"BpfTimeout", Func, 0}, + {"BpfTimeval", Type, 2}, + {"BpfTimeval.Sec", Field, 2}, + {"BpfTimeval.Usec", Field, 2}, + {"BpfVersion", Type, 0}, + {"BpfVersion.Major", Field, 0}, + {"BpfVersion.Minor", Field, 0}, + {"BpfZbuf", Type, 0}, + {"BpfZbuf.Bufa", Field, 0}, + {"BpfZbuf.Bufb", Field, 0}, + {"BpfZbuf.Buflen", Field, 0}, + {"BpfZbufHeader", Type, 0}, + {"BpfZbufHeader.Kernel_gen", Field, 0}, + {"BpfZbufHeader.Kernel_len", Field, 0}, + {"BpfZbufHeader.User_gen", Field, 0}, + {"BpfZbufHeader.X_bzh_pad", Field, 0}, + {"ByHandleFileInformation", Type, 0}, + {"ByHandleFileInformation.CreationTime", Field, 0}, + {"ByHandleFileInformation.FileAttributes", Field, 0}, + {"ByHandleFileInformation.FileIndexHigh", Field, 0}, + {"ByHandleFileInformation.FileIndexLow", Field, 0}, + {"ByHandleFileInformation.FileSizeHigh", Field, 0}, + {"ByHandleFileInformation.FileSizeLow", Field, 0}, + {"ByHandleFileInformation.LastAccessTime", Field, 0}, + {"ByHandleFileInformation.LastWriteTime", Field, 0}, + {"ByHandleFileInformation.NumberOfLinks", Field, 0}, + {"ByHandleFileInformation.VolumeSerialNumber", Field, 0}, + {"BytePtrFromString", Func, 1}, + {"ByteSliceFromString", Func, 1}, + {"CCR0_FLUSH", Const, 1}, + {"CERT_CHAIN_POLICY_AUTHENTICODE", Const, 0}, + {"CERT_CHAIN_POLICY_AUTHENTICODE_TS", Const, 0}, + {"CERT_CHAIN_POLICY_BASE", Const, 0}, + {"CERT_CHAIN_POLICY_BASIC_CONSTRAINTS", Const, 0}, + {"CERT_CHAIN_POLICY_EV", Const, 0}, + {"CERT_CHAIN_POLICY_MICROSOFT_ROOT", Const, 0}, + {"CERT_CHAIN_POLICY_NT_AUTH", Const, 0}, + {"CERT_CHAIN_POLICY_SSL", Const, 0}, + {"CERT_E_CN_NO_MATCH", Const, 0}, + {"CERT_E_EXPIRED", Const, 0}, + {"CERT_E_PURPOSE", Const, 0}, + {"CERT_E_ROLE", Const, 0}, + {"CERT_E_UNTRUSTEDROOT", Const, 0}, + {"CERT_STORE_ADD_ALWAYS", Const, 0}, + {"CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG", Const, 0}, + {"CERT_STORE_PROV_MEMORY", Const, 0}, + {"CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT", Const, 0}, + {"CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT", Const, 0}, + {"CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT", Const, 0}, + {"CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT", Const, 0}, + {"CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT", Const, 0}, + {"CERT_TRUST_INVALID_BASIC_CONSTRAINTS", Const, 0}, + {"CERT_TRUST_INVALID_EXTENSION", Const, 0}, + {"CERT_TRUST_INVALID_NAME_CONSTRAINTS", Const, 0}, + {"CERT_TRUST_INVALID_POLICY_CONSTRAINTS", Const, 0}, + {"CERT_TRUST_IS_CYCLIC", Const, 0}, + {"CERT_TRUST_IS_EXPLICIT_DISTRUST", Const, 0}, + {"CERT_TRUST_IS_NOT_SIGNATURE_VALID", Const, 0}, + {"CERT_TRUST_IS_NOT_TIME_VALID", Const, 0}, + {"CERT_TRUST_IS_NOT_VALID_FOR_USAGE", Const, 0}, + {"CERT_TRUST_IS_OFFLINE_REVOCATION", Const, 0}, + {"CERT_TRUST_IS_REVOKED", Const, 0}, + {"CERT_TRUST_IS_UNTRUSTED_ROOT", Const, 0}, + {"CERT_TRUST_NO_ERROR", Const, 0}, + {"CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY", Const, 0}, + {"CERT_TRUST_REVOCATION_STATUS_UNKNOWN", Const, 0}, + {"CFLUSH", Const, 1}, + {"CLOCAL", Const, 0}, + {"CLONE_CHILD_CLEARTID", Const, 2}, + {"CLONE_CHILD_SETTID", Const, 2}, + {"CLONE_CLEAR_SIGHAND", Const, 20}, + {"CLONE_CSIGNAL", Const, 3}, + {"CLONE_DETACHED", Const, 2}, + {"CLONE_FILES", Const, 2}, + {"CLONE_FS", Const, 2}, + {"CLONE_INTO_CGROUP", Const, 20}, + {"CLONE_IO", Const, 2}, + {"CLONE_NEWCGROUP", Const, 20}, + {"CLONE_NEWIPC", Const, 2}, + {"CLONE_NEWNET", Const, 2}, + {"CLONE_NEWNS", Const, 2}, + {"CLONE_NEWPID", Const, 2}, + {"CLONE_NEWTIME", Const, 20}, + {"CLONE_NEWUSER", Const, 2}, + {"CLONE_NEWUTS", Const, 2}, + {"CLONE_PARENT", Const, 2}, + {"CLONE_PARENT_SETTID", Const, 2}, + {"CLONE_PID", Const, 3}, + {"CLONE_PIDFD", Const, 20}, + {"CLONE_PTRACE", Const, 2}, + {"CLONE_SETTLS", Const, 2}, + {"CLONE_SIGHAND", Const, 2}, + {"CLONE_SYSVSEM", Const, 2}, + {"CLONE_THREAD", Const, 2}, + {"CLONE_UNTRACED", Const, 2}, + {"CLONE_VFORK", Const, 2}, + {"CLONE_VM", Const, 2}, + {"CPUID_CFLUSH", Const, 1}, + {"CREAD", Const, 0}, + {"CREATE_ALWAYS", Const, 0}, + {"CREATE_NEW", Const, 0}, + {"CREATE_NEW_PROCESS_GROUP", Const, 1}, + {"CREATE_UNICODE_ENVIRONMENT", Const, 0}, + {"CRYPT_DEFAULT_CONTAINER_OPTIONAL", Const, 0}, + {"CRYPT_DELETEKEYSET", Const, 0}, + {"CRYPT_MACHINE_KEYSET", Const, 0}, + {"CRYPT_NEWKEYSET", Const, 0}, + {"CRYPT_SILENT", Const, 0}, + {"CRYPT_VERIFYCONTEXT", Const, 0}, + {"CS5", Const, 0}, + {"CS6", Const, 0}, + {"CS7", Const, 0}, + {"CS8", Const, 0}, + {"CSIZE", Const, 0}, + {"CSTART", Const, 1}, + {"CSTATUS", Const, 1}, + {"CSTOP", Const, 1}, + {"CSTOPB", Const, 0}, + {"CSUSP", Const, 1}, + {"CTL_MAXNAME", Const, 0}, + {"CTL_NET", Const, 0}, + {"CTL_QUERY", Const, 1}, + {"CTRL_BREAK_EVENT", Const, 1}, + {"CTRL_CLOSE_EVENT", Const, 14}, + {"CTRL_C_EVENT", Const, 1}, + {"CTRL_LOGOFF_EVENT", Const, 14}, + {"CTRL_SHUTDOWN_EVENT", Const, 14}, + {"CancelIo", Func, 0}, + {"CancelIoEx", Func, 1}, + {"CertAddCertificateContextToStore", Func, 0}, + {"CertChainContext", Type, 0}, + {"CertChainContext.ChainCount", Field, 0}, + {"CertChainContext.Chains", Field, 0}, + {"CertChainContext.HasRevocationFreshnessTime", Field, 0}, + {"CertChainContext.LowerQualityChainCount", Field, 0}, + {"CertChainContext.LowerQualityChains", Field, 0}, + {"CertChainContext.RevocationFreshnessTime", Field, 0}, + {"CertChainContext.Size", Field, 0}, + {"CertChainContext.TrustStatus", Field, 0}, + {"CertChainElement", Type, 0}, + {"CertChainElement.ApplicationUsage", Field, 0}, + {"CertChainElement.CertContext", Field, 0}, + {"CertChainElement.ExtendedErrorInfo", Field, 0}, + {"CertChainElement.IssuanceUsage", Field, 0}, + {"CertChainElement.RevocationInfo", Field, 0}, + {"CertChainElement.Size", Field, 0}, + {"CertChainElement.TrustStatus", Field, 0}, + {"CertChainPara", Type, 0}, + {"CertChainPara.CacheResync", Field, 0}, + {"CertChainPara.CheckRevocationFreshnessTime", Field, 0}, + {"CertChainPara.RequestedUsage", Field, 0}, + {"CertChainPara.RequstedIssuancePolicy", Field, 0}, + {"CertChainPara.RevocationFreshnessTime", Field, 0}, + {"CertChainPara.Size", Field, 0}, + {"CertChainPara.URLRetrievalTimeout", Field, 0}, + {"CertChainPolicyPara", Type, 0}, + {"CertChainPolicyPara.ExtraPolicyPara", Field, 0}, + {"CertChainPolicyPara.Flags", Field, 0}, + {"CertChainPolicyPara.Size", Field, 0}, + {"CertChainPolicyStatus", Type, 0}, + {"CertChainPolicyStatus.ChainIndex", Field, 0}, + {"CertChainPolicyStatus.ElementIndex", Field, 0}, + {"CertChainPolicyStatus.Error", Field, 0}, + {"CertChainPolicyStatus.ExtraPolicyStatus", Field, 0}, + {"CertChainPolicyStatus.Size", Field, 0}, + {"CertCloseStore", Func, 0}, + {"CertContext", Type, 0}, + {"CertContext.CertInfo", Field, 0}, + {"CertContext.EncodedCert", Field, 0}, + {"CertContext.EncodingType", Field, 0}, + {"CertContext.Length", Field, 0}, + {"CertContext.Store", Field, 0}, + {"CertCreateCertificateContext", Func, 0}, + {"CertEnhKeyUsage", Type, 0}, + {"CertEnhKeyUsage.Length", Field, 0}, + {"CertEnhKeyUsage.UsageIdentifiers", Field, 0}, + {"CertEnumCertificatesInStore", Func, 0}, + {"CertFreeCertificateChain", Func, 0}, + {"CertFreeCertificateContext", Func, 0}, + {"CertGetCertificateChain", Func, 0}, + {"CertInfo", Type, 11}, + {"CertOpenStore", Func, 0}, + {"CertOpenSystemStore", Func, 0}, + {"CertRevocationCrlInfo", Type, 11}, + {"CertRevocationInfo", Type, 0}, + {"CertRevocationInfo.CrlInfo", Field, 0}, + {"CertRevocationInfo.FreshnessTime", Field, 0}, + {"CertRevocationInfo.HasFreshnessTime", Field, 0}, + {"CertRevocationInfo.OidSpecificInfo", Field, 0}, + {"CertRevocationInfo.RevocationOid", Field, 0}, + {"CertRevocationInfo.RevocationResult", Field, 0}, + {"CertRevocationInfo.Size", Field, 0}, + {"CertSimpleChain", Type, 0}, + {"CertSimpleChain.Elements", Field, 0}, + {"CertSimpleChain.HasRevocationFreshnessTime", Field, 0}, + {"CertSimpleChain.NumElements", Field, 0}, + {"CertSimpleChain.RevocationFreshnessTime", Field, 0}, + {"CertSimpleChain.Size", Field, 0}, + {"CertSimpleChain.TrustListInfo", Field, 0}, + {"CertSimpleChain.TrustStatus", Field, 0}, + {"CertTrustListInfo", Type, 11}, + {"CertTrustStatus", Type, 0}, + {"CertTrustStatus.ErrorStatus", Field, 0}, + {"CertTrustStatus.InfoStatus", Field, 0}, + {"CertUsageMatch", Type, 0}, + {"CertUsageMatch.Type", Field, 0}, + {"CertUsageMatch.Usage", Field, 0}, + {"CertVerifyCertificateChainPolicy", Func, 0}, + {"Chdir", Func, 0}, + {"CheckBpfVersion", Func, 0}, + {"Chflags", Func, 0}, + {"Chmod", Func, 0}, + {"Chown", Func, 0}, + {"Chroot", Func, 0}, + {"Clearenv", Func, 0}, + {"Close", Func, 0}, + {"CloseHandle", Func, 0}, + {"CloseOnExec", Func, 0}, + {"Closesocket", Func, 0}, + {"CmsgLen", Func, 0}, + {"CmsgSpace", Func, 0}, + {"Cmsghdr", Type, 0}, + {"Cmsghdr.Len", Field, 0}, + {"Cmsghdr.Level", Field, 0}, + {"Cmsghdr.Type", Field, 0}, + {"Cmsghdr.X__cmsg_data", Field, 0}, + {"CommandLineToArgv", Func, 0}, + {"ComputerName", Func, 0}, + {"Conn", Type, 9}, + {"Connect", Func, 0}, + {"ConnectEx", Func, 1}, + {"ConvertSidToStringSid", Func, 0}, + {"ConvertStringSidToSid", Func, 0}, + {"CopySid", Func, 0}, + {"Creat", Func, 0}, + {"CreateDirectory", Func, 0}, + {"CreateFile", Func, 0}, + {"CreateFileMapping", Func, 0}, + {"CreateHardLink", Func, 4}, + {"CreateIoCompletionPort", Func, 0}, + {"CreatePipe", Func, 0}, + {"CreateProcess", Func, 0}, + {"CreateProcessAsUser", Func, 10}, + {"CreateSymbolicLink", Func, 4}, + {"CreateToolhelp32Snapshot", Func, 4}, + {"Credential", Type, 0}, + {"Credential.Gid", Field, 0}, + {"Credential.Groups", Field, 0}, + {"Credential.NoSetGroups", Field, 9}, + {"Credential.Uid", Field, 0}, + {"CryptAcquireContext", Func, 0}, + {"CryptGenRandom", Func, 0}, + {"CryptReleaseContext", Func, 0}, + {"DIOCBSFLUSH", Const, 1}, + {"DIOCOSFPFLUSH", Const, 1}, + {"DLL", Type, 0}, + {"DLL.Handle", Field, 0}, + {"DLL.Name", Field, 0}, + {"DLLError", Type, 0}, + {"DLLError.Err", Field, 0}, + {"DLLError.Msg", Field, 0}, + {"DLLError.ObjName", Field, 0}, + {"DLT_A429", Const, 0}, + {"DLT_A653_ICM", Const, 0}, + {"DLT_AIRONET_HEADER", Const, 0}, + {"DLT_AOS", Const, 1}, + {"DLT_APPLE_IP_OVER_IEEE1394", Const, 0}, + {"DLT_ARCNET", Const, 0}, + {"DLT_ARCNET_LINUX", Const, 0}, + {"DLT_ATM_CLIP", Const, 0}, + {"DLT_ATM_RFC1483", Const, 0}, + {"DLT_AURORA", Const, 0}, + {"DLT_AX25", Const, 0}, + {"DLT_AX25_KISS", Const, 0}, + {"DLT_BACNET_MS_TP", Const, 0}, + {"DLT_BLUETOOTH_HCI_H4", Const, 0}, + {"DLT_BLUETOOTH_HCI_H4_WITH_PHDR", Const, 0}, + {"DLT_CAN20B", Const, 0}, + {"DLT_CAN_SOCKETCAN", Const, 1}, + {"DLT_CHAOS", Const, 0}, + {"DLT_CHDLC", Const, 0}, + {"DLT_CISCO_IOS", Const, 0}, + {"DLT_C_HDLC", Const, 0}, + {"DLT_C_HDLC_WITH_DIR", Const, 0}, + {"DLT_DBUS", Const, 1}, + {"DLT_DECT", Const, 1}, + {"DLT_DOCSIS", Const, 0}, + {"DLT_DVB_CI", Const, 1}, + {"DLT_ECONET", Const, 0}, + {"DLT_EN10MB", Const, 0}, + {"DLT_EN3MB", Const, 0}, + {"DLT_ENC", Const, 0}, + {"DLT_ERF", Const, 0}, + {"DLT_ERF_ETH", Const, 0}, + {"DLT_ERF_POS", Const, 0}, + {"DLT_FC_2", Const, 1}, + {"DLT_FC_2_WITH_FRAME_DELIMS", Const, 1}, + {"DLT_FDDI", Const, 0}, + {"DLT_FLEXRAY", Const, 0}, + {"DLT_FRELAY", Const, 0}, + {"DLT_FRELAY_WITH_DIR", Const, 0}, + {"DLT_GCOM_SERIAL", Const, 0}, + {"DLT_GCOM_T1E1", Const, 0}, + {"DLT_GPF_F", Const, 0}, + {"DLT_GPF_T", Const, 0}, + {"DLT_GPRS_LLC", Const, 0}, + {"DLT_GSMTAP_ABIS", Const, 1}, + {"DLT_GSMTAP_UM", Const, 1}, + {"DLT_HDLC", Const, 1}, + {"DLT_HHDLC", Const, 0}, + {"DLT_HIPPI", Const, 1}, + {"DLT_IBM_SN", Const, 0}, + {"DLT_IBM_SP", Const, 0}, + {"DLT_IEEE802", Const, 0}, + {"DLT_IEEE802_11", Const, 0}, + {"DLT_IEEE802_11_RADIO", Const, 0}, + {"DLT_IEEE802_11_RADIO_AVS", Const, 0}, + {"DLT_IEEE802_15_4", Const, 0}, + {"DLT_IEEE802_15_4_LINUX", Const, 0}, + {"DLT_IEEE802_15_4_NOFCS", Const, 1}, + {"DLT_IEEE802_15_4_NONASK_PHY", Const, 0}, + {"DLT_IEEE802_16_MAC_CPS", Const, 0}, + {"DLT_IEEE802_16_MAC_CPS_RADIO", Const, 0}, + {"DLT_IPFILTER", Const, 0}, + {"DLT_IPMB", Const, 0}, + {"DLT_IPMB_LINUX", Const, 0}, + {"DLT_IPNET", Const, 1}, + {"DLT_IPOIB", Const, 1}, + {"DLT_IPV4", Const, 1}, + {"DLT_IPV6", Const, 1}, + {"DLT_IP_OVER_FC", Const, 0}, + {"DLT_JUNIPER_ATM1", Const, 0}, + {"DLT_JUNIPER_ATM2", Const, 0}, + {"DLT_JUNIPER_ATM_CEMIC", Const, 1}, + {"DLT_JUNIPER_CHDLC", Const, 0}, + {"DLT_JUNIPER_ES", Const, 0}, + {"DLT_JUNIPER_ETHER", Const, 0}, + {"DLT_JUNIPER_FIBRECHANNEL", Const, 1}, + {"DLT_JUNIPER_FRELAY", Const, 0}, + {"DLT_JUNIPER_GGSN", Const, 0}, + {"DLT_JUNIPER_ISM", Const, 0}, + {"DLT_JUNIPER_MFR", Const, 0}, + {"DLT_JUNIPER_MLFR", Const, 0}, + {"DLT_JUNIPER_MLPPP", Const, 0}, + {"DLT_JUNIPER_MONITOR", Const, 0}, + {"DLT_JUNIPER_PIC_PEER", Const, 0}, + {"DLT_JUNIPER_PPP", Const, 0}, + {"DLT_JUNIPER_PPPOE", Const, 0}, + {"DLT_JUNIPER_PPPOE_ATM", Const, 0}, + {"DLT_JUNIPER_SERVICES", Const, 0}, + {"DLT_JUNIPER_SRX_E2E", Const, 1}, + {"DLT_JUNIPER_ST", Const, 0}, + {"DLT_JUNIPER_VP", Const, 0}, + {"DLT_JUNIPER_VS", Const, 1}, + {"DLT_LAPB_WITH_DIR", Const, 0}, + {"DLT_LAPD", Const, 0}, + {"DLT_LIN", Const, 0}, + {"DLT_LINUX_EVDEV", Const, 1}, + {"DLT_LINUX_IRDA", Const, 0}, + {"DLT_LINUX_LAPD", Const, 0}, + {"DLT_LINUX_PPP_WITHDIRECTION", Const, 0}, + {"DLT_LINUX_SLL", Const, 0}, + {"DLT_LOOP", Const, 0}, + {"DLT_LTALK", Const, 0}, + {"DLT_MATCHING_MAX", Const, 1}, + {"DLT_MATCHING_MIN", Const, 1}, + {"DLT_MFR", Const, 0}, + {"DLT_MOST", Const, 0}, + {"DLT_MPEG_2_TS", Const, 1}, + {"DLT_MPLS", Const, 1}, + {"DLT_MTP2", Const, 0}, + {"DLT_MTP2_WITH_PHDR", Const, 0}, + {"DLT_MTP3", Const, 0}, + {"DLT_MUX27010", Const, 1}, + {"DLT_NETANALYZER", Const, 1}, + {"DLT_NETANALYZER_TRANSPARENT", Const, 1}, + {"DLT_NFC_LLCP", Const, 1}, + {"DLT_NFLOG", Const, 1}, + {"DLT_NG40", Const, 1}, + {"DLT_NULL", Const, 0}, + {"DLT_PCI_EXP", Const, 0}, + {"DLT_PFLOG", Const, 0}, + {"DLT_PFSYNC", Const, 0}, + {"DLT_PPI", Const, 0}, + {"DLT_PPP", Const, 0}, + {"DLT_PPP_BSDOS", Const, 0}, + {"DLT_PPP_ETHER", Const, 0}, + {"DLT_PPP_PPPD", Const, 0}, + {"DLT_PPP_SERIAL", Const, 0}, + {"DLT_PPP_WITH_DIR", Const, 0}, + {"DLT_PPP_WITH_DIRECTION", Const, 0}, + {"DLT_PRISM_HEADER", Const, 0}, + {"DLT_PRONET", Const, 0}, + {"DLT_RAIF1", Const, 0}, + {"DLT_RAW", Const, 0}, + {"DLT_RAWAF_MASK", Const, 1}, + {"DLT_RIO", Const, 0}, + {"DLT_SCCP", Const, 0}, + {"DLT_SITA", Const, 0}, + {"DLT_SLIP", Const, 0}, + {"DLT_SLIP_BSDOS", Const, 0}, + {"DLT_STANAG_5066_D_PDU", Const, 1}, + {"DLT_SUNATM", Const, 0}, + {"DLT_SYMANTEC_FIREWALL", Const, 0}, + {"DLT_TZSP", Const, 0}, + {"DLT_USB", Const, 0}, + {"DLT_USB_LINUX", Const, 0}, + {"DLT_USB_LINUX_MMAPPED", Const, 1}, + {"DLT_USER0", Const, 0}, + {"DLT_USER1", Const, 0}, + {"DLT_USER10", Const, 0}, + {"DLT_USER11", Const, 0}, + {"DLT_USER12", Const, 0}, + {"DLT_USER13", Const, 0}, + {"DLT_USER14", Const, 0}, + {"DLT_USER15", Const, 0}, + {"DLT_USER2", Const, 0}, + {"DLT_USER3", Const, 0}, + {"DLT_USER4", Const, 0}, + {"DLT_USER5", Const, 0}, + {"DLT_USER6", Const, 0}, + {"DLT_USER7", Const, 0}, + {"DLT_USER8", Const, 0}, + {"DLT_USER9", Const, 0}, + {"DLT_WIHART", Const, 1}, + {"DLT_X2E_SERIAL", Const, 0}, + {"DLT_X2E_XORAYA", Const, 0}, + {"DNSMXData", Type, 0}, + {"DNSMXData.NameExchange", Field, 0}, + {"DNSMXData.Pad", Field, 0}, + {"DNSMXData.Preference", Field, 0}, + {"DNSPTRData", Type, 0}, + {"DNSPTRData.Host", Field, 0}, + {"DNSRecord", Type, 0}, + {"DNSRecord.Data", Field, 0}, + {"DNSRecord.Dw", Field, 0}, + {"DNSRecord.Length", Field, 0}, + {"DNSRecord.Name", Field, 0}, + {"DNSRecord.Next", Field, 0}, + {"DNSRecord.Reserved", Field, 0}, + {"DNSRecord.Ttl", Field, 0}, + {"DNSRecord.Type", Field, 0}, + {"DNSSRVData", Type, 0}, + {"DNSSRVData.Pad", Field, 0}, + {"DNSSRVData.Port", Field, 0}, + {"DNSSRVData.Priority", Field, 0}, + {"DNSSRVData.Target", Field, 0}, + {"DNSSRVData.Weight", Field, 0}, + {"DNSTXTData", Type, 0}, + {"DNSTXTData.StringArray", Field, 0}, + {"DNSTXTData.StringCount", Field, 0}, + {"DNS_INFO_NO_RECORDS", Const, 4}, + {"DNS_TYPE_A", Const, 0}, + {"DNS_TYPE_A6", Const, 0}, + {"DNS_TYPE_AAAA", Const, 0}, + {"DNS_TYPE_ADDRS", Const, 0}, + {"DNS_TYPE_AFSDB", Const, 0}, + {"DNS_TYPE_ALL", Const, 0}, + {"DNS_TYPE_ANY", Const, 0}, + {"DNS_TYPE_ATMA", Const, 0}, + {"DNS_TYPE_AXFR", Const, 0}, + {"DNS_TYPE_CERT", Const, 0}, + {"DNS_TYPE_CNAME", Const, 0}, + {"DNS_TYPE_DHCID", Const, 0}, + {"DNS_TYPE_DNAME", Const, 0}, + {"DNS_TYPE_DNSKEY", Const, 0}, + {"DNS_TYPE_DS", Const, 0}, + {"DNS_TYPE_EID", Const, 0}, + {"DNS_TYPE_GID", Const, 0}, + {"DNS_TYPE_GPOS", Const, 0}, + {"DNS_TYPE_HINFO", Const, 0}, + {"DNS_TYPE_ISDN", Const, 0}, + {"DNS_TYPE_IXFR", Const, 0}, + {"DNS_TYPE_KEY", Const, 0}, + {"DNS_TYPE_KX", Const, 0}, + {"DNS_TYPE_LOC", Const, 0}, + {"DNS_TYPE_MAILA", Const, 0}, + {"DNS_TYPE_MAILB", Const, 0}, + {"DNS_TYPE_MB", Const, 0}, + {"DNS_TYPE_MD", Const, 0}, + {"DNS_TYPE_MF", Const, 0}, + {"DNS_TYPE_MG", Const, 0}, + {"DNS_TYPE_MINFO", Const, 0}, + {"DNS_TYPE_MR", Const, 0}, + {"DNS_TYPE_MX", Const, 0}, + {"DNS_TYPE_NAPTR", Const, 0}, + {"DNS_TYPE_NBSTAT", Const, 0}, + {"DNS_TYPE_NIMLOC", Const, 0}, + {"DNS_TYPE_NS", Const, 0}, + {"DNS_TYPE_NSAP", Const, 0}, + {"DNS_TYPE_NSAPPTR", Const, 0}, + {"DNS_TYPE_NSEC", Const, 0}, + {"DNS_TYPE_NULL", Const, 0}, + {"DNS_TYPE_NXT", Const, 0}, + {"DNS_TYPE_OPT", Const, 0}, + {"DNS_TYPE_PTR", Const, 0}, + {"DNS_TYPE_PX", Const, 0}, + {"DNS_TYPE_RP", Const, 0}, + {"DNS_TYPE_RRSIG", Const, 0}, + {"DNS_TYPE_RT", Const, 0}, + {"DNS_TYPE_SIG", Const, 0}, + {"DNS_TYPE_SINK", Const, 0}, + {"DNS_TYPE_SOA", Const, 0}, + {"DNS_TYPE_SRV", Const, 0}, + {"DNS_TYPE_TEXT", Const, 0}, + {"DNS_TYPE_TKEY", Const, 0}, + {"DNS_TYPE_TSIG", Const, 0}, + {"DNS_TYPE_UID", Const, 0}, + {"DNS_TYPE_UINFO", Const, 0}, + {"DNS_TYPE_UNSPEC", Const, 0}, + {"DNS_TYPE_WINS", Const, 0}, + {"DNS_TYPE_WINSR", Const, 0}, + {"DNS_TYPE_WKS", Const, 0}, + {"DNS_TYPE_X25", Const, 0}, + {"DT_BLK", Const, 0}, + {"DT_CHR", Const, 0}, + {"DT_DIR", Const, 0}, + {"DT_FIFO", Const, 0}, + {"DT_LNK", Const, 0}, + {"DT_REG", Const, 0}, + {"DT_SOCK", Const, 0}, + {"DT_UNKNOWN", Const, 0}, + {"DT_WHT", Const, 0}, + {"DUPLICATE_CLOSE_SOURCE", Const, 0}, + {"DUPLICATE_SAME_ACCESS", Const, 0}, + {"DeleteFile", Func, 0}, + {"DetachLsf", Func, 0}, + {"DeviceIoControl", Func, 4}, + {"Dirent", Type, 0}, + {"Dirent.Fileno", Field, 0}, + {"Dirent.Ino", Field, 0}, + {"Dirent.Name", Field, 0}, + {"Dirent.Namlen", Field, 0}, + {"Dirent.Off", Field, 0}, + {"Dirent.Pad0", Field, 12}, + {"Dirent.Pad1", Field, 12}, + {"Dirent.Pad_cgo_0", Field, 0}, + {"Dirent.Reclen", Field, 0}, + {"Dirent.Seekoff", Field, 0}, + {"Dirent.Type", Field, 0}, + {"Dirent.X__d_padding", Field, 3}, + {"DnsNameCompare", Func, 4}, + {"DnsQuery", Func, 0}, + {"DnsRecordListFree", Func, 0}, + {"DnsSectionAdditional", Const, 4}, + {"DnsSectionAnswer", Const, 4}, + {"DnsSectionAuthority", Const, 4}, + {"DnsSectionQuestion", Const, 4}, + {"Dup", Func, 0}, + {"Dup2", Func, 0}, + {"Dup3", Func, 2}, + {"DuplicateHandle", Func, 0}, + {"E2BIG", Const, 0}, + {"EACCES", Const, 0}, + {"EADDRINUSE", Const, 0}, + {"EADDRNOTAVAIL", Const, 0}, + {"EADV", Const, 0}, + {"EAFNOSUPPORT", Const, 0}, + {"EAGAIN", Const, 0}, + {"EALREADY", Const, 0}, + {"EAUTH", Const, 0}, + {"EBADARCH", Const, 0}, + {"EBADE", Const, 0}, + {"EBADEXEC", Const, 0}, + {"EBADF", Const, 0}, + {"EBADFD", Const, 0}, + {"EBADMACHO", Const, 0}, + {"EBADMSG", Const, 0}, + {"EBADR", Const, 0}, + {"EBADRPC", Const, 0}, + {"EBADRQC", Const, 0}, + {"EBADSLT", Const, 0}, + {"EBFONT", Const, 0}, + {"EBUSY", Const, 0}, + {"ECANCELED", Const, 0}, + {"ECAPMODE", Const, 1}, + {"ECHILD", Const, 0}, + {"ECHO", Const, 0}, + {"ECHOCTL", Const, 0}, + {"ECHOE", Const, 0}, + {"ECHOK", Const, 0}, + {"ECHOKE", Const, 0}, + {"ECHONL", Const, 0}, + {"ECHOPRT", Const, 0}, + {"ECHRNG", Const, 0}, + {"ECOMM", Const, 0}, + {"ECONNABORTED", Const, 0}, + {"ECONNREFUSED", Const, 0}, + {"ECONNRESET", Const, 0}, + {"EDEADLK", Const, 0}, + {"EDEADLOCK", Const, 0}, + {"EDESTADDRREQ", Const, 0}, + {"EDEVERR", Const, 0}, + {"EDOM", Const, 0}, + {"EDOOFUS", Const, 0}, + {"EDOTDOT", Const, 0}, + {"EDQUOT", Const, 0}, + {"EEXIST", Const, 0}, + {"EFAULT", Const, 0}, + {"EFBIG", Const, 0}, + {"EFER_LMA", Const, 1}, + {"EFER_LME", Const, 1}, + {"EFER_NXE", Const, 1}, + {"EFER_SCE", Const, 1}, + {"EFTYPE", Const, 0}, + {"EHOSTDOWN", Const, 0}, + {"EHOSTUNREACH", Const, 0}, + {"EHWPOISON", Const, 0}, + {"EIDRM", Const, 0}, + {"EILSEQ", Const, 0}, + {"EINPROGRESS", Const, 0}, + {"EINTR", Const, 0}, + {"EINVAL", Const, 0}, + {"EIO", Const, 0}, + {"EIPSEC", Const, 1}, + {"EISCONN", Const, 0}, + {"EISDIR", Const, 0}, + {"EISNAM", Const, 0}, + {"EKEYEXPIRED", Const, 0}, + {"EKEYREJECTED", Const, 0}, + {"EKEYREVOKED", Const, 0}, + {"EL2HLT", Const, 0}, + {"EL2NSYNC", Const, 0}, + {"EL3HLT", Const, 0}, + {"EL3RST", Const, 0}, + {"ELAST", Const, 0}, + {"ELF_NGREG", Const, 0}, + {"ELF_PRARGSZ", Const, 0}, + {"ELIBACC", Const, 0}, + {"ELIBBAD", Const, 0}, + {"ELIBEXEC", Const, 0}, + {"ELIBMAX", Const, 0}, + {"ELIBSCN", Const, 0}, + {"ELNRNG", Const, 0}, + {"ELOOP", Const, 0}, + {"EMEDIUMTYPE", Const, 0}, + {"EMFILE", Const, 0}, + {"EMLINK", Const, 0}, + {"EMSGSIZE", Const, 0}, + {"EMT_TAGOVF", Const, 1}, + {"EMULTIHOP", Const, 0}, + {"EMUL_ENABLED", Const, 1}, + {"EMUL_LINUX", Const, 1}, + {"EMUL_LINUX32", Const, 1}, + {"EMUL_MAXID", Const, 1}, + {"EMUL_NATIVE", Const, 1}, + {"ENAMETOOLONG", Const, 0}, + {"ENAVAIL", Const, 0}, + {"ENDRUNDISC", Const, 1}, + {"ENEEDAUTH", Const, 0}, + {"ENETDOWN", Const, 0}, + {"ENETRESET", Const, 0}, + {"ENETUNREACH", Const, 0}, + {"ENFILE", Const, 0}, + {"ENOANO", Const, 0}, + {"ENOATTR", Const, 0}, + {"ENOBUFS", Const, 0}, + {"ENOCSI", Const, 0}, + {"ENODATA", Const, 0}, + {"ENODEV", Const, 0}, + {"ENOENT", Const, 0}, + {"ENOEXEC", Const, 0}, + {"ENOKEY", Const, 0}, + {"ENOLCK", Const, 0}, + {"ENOLINK", Const, 0}, + {"ENOMEDIUM", Const, 0}, + {"ENOMEM", Const, 0}, + {"ENOMSG", Const, 0}, + {"ENONET", Const, 0}, + {"ENOPKG", Const, 0}, + {"ENOPOLICY", Const, 0}, + {"ENOPROTOOPT", Const, 0}, + {"ENOSPC", Const, 0}, + {"ENOSR", Const, 0}, + {"ENOSTR", Const, 0}, + {"ENOSYS", Const, 0}, + {"ENOTBLK", Const, 0}, + {"ENOTCAPABLE", Const, 0}, + {"ENOTCONN", Const, 0}, + {"ENOTDIR", Const, 0}, + {"ENOTEMPTY", Const, 0}, + {"ENOTNAM", Const, 0}, + {"ENOTRECOVERABLE", Const, 0}, + {"ENOTSOCK", Const, 0}, + {"ENOTSUP", Const, 0}, + {"ENOTTY", Const, 0}, + {"ENOTUNIQ", Const, 0}, + {"ENXIO", Const, 0}, + {"EN_SW_CTL_INF", Const, 1}, + {"EN_SW_CTL_PREC", Const, 1}, + {"EN_SW_CTL_ROUND", Const, 1}, + {"EN_SW_DATACHAIN", Const, 1}, + {"EN_SW_DENORM", Const, 1}, + {"EN_SW_INVOP", Const, 1}, + {"EN_SW_OVERFLOW", Const, 1}, + {"EN_SW_PRECLOSS", Const, 1}, + {"EN_SW_UNDERFLOW", Const, 1}, + {"EN_SW_ZERODIV", Const, 1}, + {"EOPNOTSUPP", Const, 0}, + {"EOVERFLOW", Const, 0}, + {"EOWNERDEAD", Const, 0}, + {"EPERM", Const, 0}, + {"EPFNOSUPPORT", Const, 0}, + {"EPIPE", Const, 0}, + {"EPOLLERR", Const, 0}, + {"EPOLLET", Const, 0}, + {"EPOLLHUP", Const, 0}, + {"EPOLLIN", Const, 0}, + {"EPOLLMSG", Const, 0}, + {"EPOLLONESHOT", Const, 0}, + {"EPOLLOUT", Const, 0}, + {"EPOLLPRI", Const, 0}, + {"EPOLLRDBAND", Const, 0}, + {"EPOLLRDHUP", Const, 0}, + {"EPOLLRDNORM", Const, 0}, + {"EPOLLWRBAND", Const, 0}, + {"EPOLLWRNORM", Const, 0}, + {"EPOLL_CLOEXEC", Const, 0}, + {"EPOLL_CTL_ADD", Const, 0}, + {"EPOLL_CTL_DEL", Const, 0}, + {"EPOLL_CTL_MOD", Const, 0}, + {"EPOLL_NONBLOCK", Const, 0}, + {"EPROCLIM", Const, 0}, + {"EPROCUNAVAIL", Const, 0}, + {"EPROGMISMATCH", Const, 0}, + {"EPROGUNAVAIL", Const, 0}, + {"EPROTO", Const, 0}, + {"EPROTONOSUPPORT", Const, 0}, + {"EPROTOTYPE", Const, 0}, + {"EPWROFF", Const, 0}, + {"EQFULL", Const, 16}, + {"ERANGE", Const, 0}, + {"EREMCHG", Const, 0}, + {"EREMOTE", Const, 0}, + {"EREMOTEIO", Const, 0}, + {"ERESTART", Const, 0}, + {"ERFKILL", Const, 0}, + {"EROFS", Const, 0}, + {"ERPCMISMATCH", Const, 0}, + {"ERROR_ACCESS_DENIED", Const, 0}, + {"ERROR_ALREADY_EXISTS", Const, 0}, + {"ERROR_BROKEN_PIPE", Const, 0}, + {"ERROR_BUFFER_OVERFLOW", Const, 0}, + {"ERROR_DIR_NOT_EMPTY", Const, 8}, + {"ERROR_ENVVAR_NOT_FOUND", Const, 0}, + {"ERROR_FILE_EXISTS", Const, 0}, + {"ERROR_FILE_NOT_FOUND", Const, 0}, + {"ERROR_HANDLE_EOF", Const, 2}, + {"ERROR_INSUFFICIENT_BUFFER", Const, 0}, + {"ERROR_IO_PENDING", Const, 0}, + {"ERROR_MOD_NOT_FOUND", Const, 0}, + {"ERROR_MORE_DATA", Const, 3}, + {"ERROR_NETNAME_DELETED", Const, 3}, + {"ERROR_NOT_FOUND", Const, 1}, + {"ERROR_NO_MORE_FILES", Const, 0}, + {"ERROR_OPERATION_ABORTED", Const, 0}, + {"ERROR_PATH_NOT_FOUND", Const, 0}, + {"ERROR_PRIVILEGE_NOT_HELD", Const, 4}, + {"ERROR_PROC_NOT_FOUND", Const, 0}, + {"ESHLIBVERS", Const, 0}, + {"ESHUTDOWN", Const, 0}, + {"ESOCKTNOSUPPORT", Const, 0}, + {"ESPIPE", Const, 0}, + {"ESRCH", Const, 0}, + {"ESRMNT", Const, 0}, + {"ESTALE", Const, 0}, + {"ESTRPIPE", Const, 0}, + {"ETHERCAP_JUMBO_MTU", Const, 1}, + {"ETHERCAP_VLAN_HWTAGGING", Const, 1}, + {"ETHERCAP_VLAN_MTU", Const, 1}, + {"ETHERMIN", Const, 1}, + {"ETHERMTU", Const, 1}, + {"ETHERMTU_JUMBO", Const, 1}, + {"ETHERTYPE_8023", Const, 1}, + {"ETHERTYPE_AARP", Const, 1}, + {"ETHERTYPE_ACCTON", Const, 1}, + {"ETHERTYPE_AEONIC", Const, 1}, + {"ETHERTYPE_ALPHA", Const, 1}, + {"ETHERTYPE_AMBER", Const, 1}, + {"ETHERTYPE_AMOEBA", Const, 1}, + {"ETHERTYPE_AOE", Const, 1}, + {"ETHERTYPE_APOLLO", Const, 1}, + {"ETHERTYPE_APOLLODOMAIN", Const, 1}, + {"ETHERTYPE_APPLETALK", Const, 1}, + {"ETHERTYPE_APPLITEK", Const, 1}, + {"ETHERTYPE_ARGONAUT", Const, 1}, + {"ETHERTYPE_ARP", Const, 1}, + {"ETHERTYPE_AT", Const, 1}, + {"ETHERTYPE_ATALK", Const, 1}, + {"ETHERTYPE_ATOMIC", Const, 1}, + {"ETHERTYPE_ATT", Const, 1}, + {"ETHERTYPE_ATTSTANFORD", Const, 1}, + {"ETHERTYPE_AUTOPHON", Const, 1}, + {"ETHERTYPE_AXIS", Const, 1}, + {"ETHERTYPE_BCLOOP", Const, 1}, + {"ETHERTYPE_BOFL", Const, 1}, + {"ETHERTYPE_CABLETRON", Const, 1}, + {"ETHERTYPE_CHAOS", Const, 1}, + {"ETHERTYPE_COMDESIGN", Const, 1}, + {"ETHERTYPE_COMPUGRAPHIC", Const, 1}, + {"ETHERTYPE_COUNTERPOINT", Const, 1}, + {"ETHERTYPE_CRONUS", Const, 1}, + {"ETHERTYPE_CRONUSVLN", Const, 1}, + {"ETHERTYPE_DCA", Const, 1}, + {"ETHERTYPE_DDE", Const, 1}, + {"ETHERTYPE_DEBNI", Const, 1}, + {"ETHERTYPE_DECAM", Const, 1}, + {"ETHERTYPE_DECCUST", Const, 1}, + {"ETHERTYPE_DECDIAG", Const, 1}, + {"ETHERTYPE_DECDNS", Const, 1}, + {"ETHERTYPE_DECDTS", Const, 1}, + {"ETHERTYPE_DECEXPER", Const, 1}, + {"ETHERTYPE_DECLAST", Const, 1}, + {"ETHERTYPE_DECLTM", Const, 1}, + {"ETHERTYPE_DECMUMPS", Const, 1}, + {"ETHERTYPE_DECNETBIOS", Const, 1}, + {"ETHERTYPE_DELTACON", Const, 1}, + {"ETHERTYPE_DIDDLE", Const, 1}, + {"ETHERTYPE_DLOG1", Const, 1}, + {"ETHERTYPE_DLOG2", Const, 1}, + {"ETHERTYPE_DN", Const, 1}, + {"ETHERTYPE_DOGFIGHT", Const, 1}, + {"ETHERTYPE_DSMD", Const, 1}, + {"ETHERTYPE_ECMA", Const, 1}, + {"ETHERTYPE_ENCRYPT", Const, 1}, + {"ETHERTYPE_ES", Const, 1}, + {"ETHERTYPE_EXCELAN", Const, 1}, + {"ETHERTYPE_EXPERDATA", Const, 1}, + {"ETHERTYPE_FLIP", Const, 1}, + {"ETHERTYPE_FLOWCONTROL", Const, 1}, + {"ETHERTYPE_FRARP", Const, 1}, + {"ETHERTYPE_GENDYN", Const, 1}, + {"ETHERTYPE_HAYES", Const, 1}, + {"ETHERTYPE_HIPPI_FP", Const, 1}, + {"ETHERTYPE_HITACHI", Const, 1}, + {"ETHERTYPE_HP", Const, 1}, + {"ETHERTYPE_IEEEPUP", Const, 1}, + {"ETHERTYPE_IEEEPUPAT", Const, 1}, + {"ETHERTYPE_IMLBL", Const, 1}, + {"ETHERTYPE_IMLBLDIAG", Const, 1}, + {"ETHERTYPE_IP", Const, 1}, + {"ETHERTYPE_IPAS", Const, 1}, + {"ETHERTYPE_IPV6", Const, 1}, + {"ETHERTYPE_IPX", Const, 1}, + {"ETHERTYPE_IPXNEW", Const, 1}, + {"ETHERTYPE_KALPANA", Const, 1}, + {"ETHERTYPE_LANBRIDGE", Const, 1}, + {"ETHERTYPE_LANPROBE", Const, 1}, + {"ETHERTYPE_LAT", Const, 1}, + {"ETHERTYPE_LBACK", Const, 1}, + {"ETHERTYPE_LITTLE", Const, 1}, + {"ETHERTYPE_LLDP", Const, 1}, + {"ETHERTYPE_LOGICRAFT", Const, 1}, + {"ETHERTYPE_LOOPBACK", Const, 1}, + {"ETHERTYPE_MATRA", Const, 1}, + {"ETHERTYPE_MAX", Const, 1}, + {"ETHERTYPE_MERIT", Const, 1}, + {"ETHERTYPE_MICP", Const, 1}, + {"ETHERTYPE_MOPDL", Const, 1}, + {"ETHERTYPE_MOPRC", Const, 1}, + {"ETHERTYPE_MOTOROLA", Const, 1}, + {"ETHERTYPE_MPLS", Const, 1}, + {"ETHERTYPE_MPLS_MCAST", Const, 1}, + {"ETHERTYPE_MUMPS", Const, 1}, + {"ETHERTYPE_NBPCC", Const, 1}, + {"ETHERTYPE_NBPCLAIM", Const, 1}, + {"ETHERTYPE_NBPCLREQ", Const, 1}, + {"ETHERTYPE_NBPCLRSP", Const, 1}, + {"ETHERTYPE_NBPCREQ", Const, 1}, + {"ETHERTYPE_NBPCRSP", Const, 1}, + {"ETHERTYPE_NBPDG", Const, 1}, + {"ETHERTYPE_NBPDGB", Const, 1}, + {"ETHERTYPE_NBPDLTE", Const, 1}, + {"ETHERTYPE_NBPRAR", Const, 1}, + {"ETHERTYPE_NBPRAS", Const, 1}, + {"ETHERTYPE_NBPRST", Const, 1}, + {"ETHERTYPE_NBPSCD", Const, 1}, + {"ETHERTYPE_NBPVCD", Const, 1}, + {"ETHERTYPE_NBS", Const, 1}, + {"ETHERTYPE_NCD", Const, 1}, + {"ETHERTYPE_NESTAR", Const, 1}, + {"ETHERTYPE_NETBEUI", Const, 1}, + {"ETHERTYPE_NOVELL", Const, 1}, + {"ETHERTYPE_NS", Const, 1}, + {"ETHERTYPE_NSAT", Const, 1}, + {"ETHERTYPE_NSCOMPAT", Const, 1}, + {"ETHERTYPE_NTRAILER", Const, 1}, + {"ETHERTYPE_OS9", Const, 1}, + {"ETHERTYPE_OS9NET", Const, 1}, + {"ETHERTYPE_PACER", Const, 1}, + {"ETHERTYPE_PAE", Const, 1}, + {"ETHERTYPE_PCS", Const, 1}, + {"ETHERTYPE_PLANNING", Const, 1}, + {"ETHERTYPE_PPP", Const, 1}, + {"ETHERTYPE_PPPOE", Const, 1}, + {"ETHERTYPE_PPPOEDISC", Const, 1}, + {"ETHERTYPE_PRIMENTS", Const, 1}, + {"ETHERTYPE_PUP", Const, 1}, + {"ETHERTYPE_PUPAT", Const, 1}, + {"ETHERTYPE_QINQ", Const, 1}, + {"ETHERTYPE_RACAL", Const, 1}, + {"ETHERTYPE_RATIONAL", Const, 1}, + {"ETHERTYPE_RAWFR", Const, 1}, + {"ETHERTYPE_RCL", Const, 1}, + {"ETHERTYPE_RDP", Const, 1}, + {"ETHERTYPE_RETIX", Const, 1}, + {"ETHERTYPE_REVARP", Const, 1}, + {"ETHERTYPE_SCA", Const, 1}, + {"ETHERTYPE_SECTRA", Const, 1}, + {"ETHERTYPE_SECUREDATA", Const, 1}, + {"ETHERTYPE_SGITW", Const, 1}, + {"ETHERTYPE_SG_BOUNCE", Const, 1}, + {"ETHERTYPE_SG_DIAG", Const, 1}, + {"ETHERTYPE_SG_NETGAMES", Const, 1}, + {"ETHERTYPE_SG_RESV", Const, 1}, + {"ETHERTYPE_SIMNET", Const, 1}, + {"ETHERTYPE_SLOW", Const, 1}, + {"ETHERTYPE_SLOWPROTOCOLS", Const, 1}, + {"ETHERTYPE_SNA", Const, 1}, + {"ETHERTYPE_SNMP", Const, 1}, + {"ETHERTYPE_SONIX", Const, 1}, + {"ETHERTYPE_SPIDER", Const, 1}, + {"ETHERTYPE_SPRITE", Const, 1}, + {"ETHERTYPE_STP", Const, 1}, + {"ETHERTYPE_TALARIS", Const, 1}, + {"ETHERTYPE_TALARISMC", Const, 1}, + {"ETHERTYPE_TCPCOMP", Const, 1}, + {"ETHERTYPE_TCPSM", Const, 1}, + {"ETHERTYPE_TEC", Const, 1}, + {"ETHERTYPE_TIGAN", Const, 1}, + {"ETHERTYPE_TRAIL", Const, 1}, + {"ETHERTYPE_TRANSETHER", Const, 1}, + {"ETHERTYPE_TYMSHARE", Const, 1}, + {"ETHERTYPE_UBBST", Const, 1}, + {"ETHERTYPE_UBDEBUG", Const, 1}, + {"ETHERTYPE_UBDIAGLOOP", Const, 1}, + {"ETHERTYPE_UBDL", Const, 1}, + {"ETHERTYPE_UBNIU", Const, 1}, + {"ETHERTYPE_UBNMC", Const, 1}, + {"ETHERTYPE_VALID", Const, 1}, + {"ETHERTYPE_VARIAN", Const, 1}, + {"ETHERTYPE_VAXELN", Const, 1}, + {"ETHERTYPE_VEECO", Const, 1}, + {"ETHERTYPE_VEXP", Const, 1}, + {"ETHERTYPE_VGLAB", Const, 1}, + {"ETHERTYPE_VINES", Const, 1}, + {"ETHERTYPE_VINESECHO", Const, 1}, + {"ETHERTYPE_VINESLOOP", Const, 1}, + {"ETHERTYPE_VITAL", Const, 1}, + {"ETHERTYPE_VLAN", Const, 1}, + {"ETHERTYPE_VLTLMAN", Const, 1}, + {"ETHERTYPE_VPROD", Const, 1}, + {"ETHERTYPE_VURESERVED", Const, 1}, + {"ETHERTYPE_WATERLOO", Const, 1}, + {"ETHERTYPE_WELLFLEET", Const, 1}, + {"ETHERTYPE_X25", Const, 1}, + {"ETHERTYPE_X75", Const, 1}, + {"ETHERTYPE_XNSSM", Const, 1}, + {"ETHERTYPE_XTP", Const, 1}, + {"ETHER_ADDR_LEN", Const, 1}, + {"ETHER_ALIGN", Const, 1}, + {"ETHER_CRC_LEN", Const, 1}, + {"ETHER_CRC_POLY_BE", Const, 1}, + {"ETHER_CRC_POLY_LE", Const, 1}, + {"ETHER_HDR_LEN", Const, 1}, + {"ETHER_MAX_DIX_LEN", Const, 1}, + {"ETHER_MAX_LEN", Const, 1}, + {"ETHER_MAX_LEN_JUMBO", Const, 1}, + {"ETHER_MIN_LEN", Const, 1}, + {"ETHER_PPPOE_ENCAP_LEN", Const, 1}, + {"ETHER_TYPE_LEN", Const, 1}, + {"ETHER_VLAN_ENCAP_LEN", Const, 1}, + {"ETH_P_1588", Const, 0}, + {"ETH_P_8021Q", Const, 0}, + {"ETH_P_802_2", Const, 0}, + {"ETH_P_802_3", Const, 0}, + {"ETH_P_AARP", Const, 0}, + {"ETH_P_ALL", Const, 0}, + {"ETH_P_AOE", Const, 0}, + {"ETH_P_ARCNET", Const, 0}, + {"ETH_P_ARP", Const, 0}, + {"ETH_P_ATALK", Const, 0}, + {"ETH_P_ATMFATE", Const, 0}, + {"ETH_P_ATMMPOA", Const, 0}, + {"ETH_P_AX25", Const, 0}, + {"ETH_P_BPQ", Const, 0}, + {"ETH_P_CAIF", Const, 0}, + {"ETH_P_CAN", Const, 0}, + {"ETH_P_CONTROL", Const, 0}, + {"ETH_P_CUST", Const, 0}, + {"ETH_P_DDCMP", Const, 0}, + {"ETH_P_DEC", Const, 0}, + {"ETH_P_DIAG", Const, 0}, + {"ETH_P_DNA_DL", Const, 0}, + {"ETH_P_DNA_RC", Const, 0}, + {"ETH_P_DNA_RT", Const, 0}, + {"ETH_P_DSA", Const, 0}, + {"ETH_P_ECONET", Const, 0}, + {"ETH_P_EDSA", Const, 0}, + {"ETH_P_FCOE", Const, 0}, + {"ETH_P_FIP", Const, 0}, + {"ETH_P_HDLC", Const, 0}, + {"ETH_P_IEEE802154", Const, 0}, + {"ETH_P_IEEEPUP", Const, 0}, + {"ETH_P_IEEEPUPAT", Const, 0}, + {"ETH_P_IP", Const, 0}, + {"ETH_P_IPV6", Const, 0}, + {"ETH_P_IPX", Const, 0}, + {"ETH_P_IRDA", Const, 0}, + {"ETH_P_LAT", Const, 0}, + {"ETH_P_LINK_CTL", Const, 0}, + {"ETH_P_LOCALTALK", Const, 0}, + {"ETH_P_LOOP", Const, 0}, + {"ETH_P_MOBITEX", Const, 0}, + {"ETH_P_MPLS_MC", Const, 0}, + {"ETH_P_MPLS_UC", Const, 0}, + {"ETH_P_PAE", Const, 0}, + {"ETH_P_PAUSE", Const, 0}, + {"ETH_P_PHONET", Const, 0}, + {"ETH_P_PPPTALK", Const, 0}, + {"ETH_P_PPP_DISC", Const, 0}, + {"ETH_P_PPP_MP", Const, 0}, + {"ETH_P_PPP_SES", Const, 0}, + {"ETH_P_PUP", Const, 0}, + {"ETH_P_PUPAT", Const, 0}, + {"ETH_P_RARP", Const, 0}, + {"ETH_P_SCA", Const, 0}, + {"ETH_P_SLOW", Const, 0}, + {"ETH_P_SNAP", Const, 0}, + {"ETH_P_TEB", Const, 0}, + {"ETH_P_TIPC", Const, 0}, + {"ETH_P_TRAILER", Const, 0}, + {"ETH_P_TR_802_2", Const, 0}, + {"ETH_P_WAN_PPP", Const, 0}, + {"ETH_P_WCCP", Const, 0}, + {"ETH_P_X25", Const, 0}, + {"ETIME", Const, 0}, + {"ETIMEDOUT", Const, 0}, + {"ETOOMANYREFS", Const, 0}, + {"ETXTBSY", Const, 0}, + {"EUCLEAN", Const, 0}, + {"EUNATCH", Const, 0}, + {"EUSERS", Const, 0}, + {"EVFILT_AIO", Const, 0}, + {"EVFILT_FS", Const, 0}, + {"EVFILT_LIO", Const, 0}, + {"EVFILT_MACHPORT", Const, 0}, + {"EVFILT_PROC", Const, 0}, + {"EVFILT_READ", Const, 0}, + {"EVFILT_SIGNAL", Const, 0}, + {"EVFILT_SYSCOUNT", Const, 0}, + {"EVFILT_THREADMARKER", Const, 0}, + {"EVFILT_TIMER", Const, 0}, + {"EVFILT_USER", Const, 0}, + {"EVFILT_VM", Const, 0}, + {"EVFILT_VNODE", Const, 0}, + {"EVFILT_WRITE", Const, 0}, + {"EV_ADD", Const, 0}, + {"EV_CLEAR", Const, 0}, + {"EV_DELETE", Const, 0}, + {"EV_DISABLE", Const, 0}, + {"EV_DISPATCH", Const, 0}, + {"EV_DROP", Const, 3}, + {"EV_ENABLE", Const, 0}, + {"EV_EOF", Const, 0}, + {"EV_ERROR", Const, 0}, + {"EV_FLAG0", Const, 0}, + {"EV_FLAG1", Const, 0}, + {"EV_ONESHOT", Const, 0}, + {"EV_OOBAND", Const, 0}, + {"EV_POLL", Const, 0}, + {"EV_RECEIPT", Const, 0}, + {"EV_SYSFLAGS", Const, 0}, + {"EWINDOWS", Const, 0}, + {"EWOULDBLOCK", Const, 0}, + {"EXDEV", Const, 0}, + {"EXFULL", Const, 0}, + {"EXTA", Const, 0}, + {"EXTB", Const, 0}, + {"EXTPROC", Const, 0}, + {"Environ", Func, 0}, + {"EpollCreate", Func, 0}, + {"EpollCreate1", Func, 0}, + {"EpollCtl", Func, 0}, + {"EpollEvent", Type, 0}, + {"EpollEvent.Events", Field, 0}, + {"EpollEvent.Fd", Field, 0}, + {"EpollEvent.Pad", Field, 0}, + {"EpollEvent.PadFd", Field, 0}, + {"EpollWait", Func, 0}, + {"Errno", Type, 0}, + {"EscapeArg", Func, 0}, + {"Exchangedata", Func, 0}, + {"Exec", Func, 0}, + {"Exit", Func, 0}, + {"ExitProcess", Func, 0}, + {"FD_CLOEXEC", Const, 0}, + {"FD_SETSIZE", Const, 0}, + {"FILE_ACTION_ADDED", Const, 0}, + {"FILE_ACTION_MODIFIED", Const, 0}, + {"FILE_ACTION_REMOVED", Const, 0}, + {"FILE_ACTION_RENAMED_NEW_NAME", Const, 0}, + {"FILE_ACTION_RENAMED_OLD_NAME", Const, 0}, + {"FILE_APPEND_DATA", Const, 0}, + {"FILE_ATTRIBUTE_ARCHIVE", Const, 0}, + {"FILE_ATTRIBUTE_DIRECTORY", Const, 0}, + {"FILE_ATTRIBUTE_HIDDEN", Const, 0}, + {"FILE_ATTRIBUTE_NORMAL", Const, 0}, + {"FILE_ATTRIBUTE_READONLY", Const, 0}, + {"FILE_ATTRIBUTE_REPARSE_POINT", Const, 4}, + {"FILE_ATTRIBUTE_SYSTEM", Const, 0}, + {"FILE_BEGIN", Const, 0}, + {"FILE_CURRENT", Const, 0}, + {"FILE_END", Const, 0}, + {"FILE_FLAG_BACKUP_SEMANTICS", Const, 0}, + {"FILE_FLAG_OPEN_REPARSE_POINT", Const, 4}, + {"FILE_FLAG_OVERLAPPED", Const, 0}, + {"FILE_LIST_DIRECTORY", Const, 0}, + {"FILE_MAP_COPY", Const, 0}, + {"FILE_MAP_EXECUTE", Const, 0}, + {"FILE_MAP_READ", Const, 0}, + {"FILE_MAP_WRITE", Const, 0}, + {"FILE_NOTIFY_CHANGE_ATTRIBUTES", Const, 0}, + {"FILE_NOTIFY_CHANGE_CREATION", Const, 0}, + {"FILE_NOTIFY_CHANGE_DIR_NAME", Const, 0}, + {"FILE_NOTIFY_CHANGE_FILE_NAME", Const, 0}, + {"FILE_NOTIFY_CHANGE_LAST_ACCESS", Const, 0}, + {"FILE_NOTIFY_CHANGE_LAST_WRITE", Const, 0}, + {"FILE_NOTIFY_CHANGE_SIZE", Const, 0}, + {"FILE_SHARE_DELETE", Const, 0}, + {"FILE_SHARE_READ", Const, 0}, + {"FILE_SHARE_WRITE", Const, 0}, + {"FILE_SKIP_COMPLETION_PORT_ON_SUCCESS", Const, 2}, + {"FILE_SKIP_SET_EVENT_ON_HANDLE", Const, 2}, + {"FILE_TYPE_CHAR", Const, 0}, + {"FILE_TYPE_DISK", Const, 0}, + {"FILE_TYPE_PIPE", Const, 0}, + {"FILE_TYPE_REMOTE", Const, 0}, + {"FILE_TYPE_UNKNOWN", Const, 0}, + {"FILE_WRITE_ATTRIBUTES", Const, 0}, + {"FLUSHO", Const, 0}, + {"FORMAT_MESSAGE_ALLOCATE_BUFFER", Const, 0}, + {"FORMAT_MESSAGE_ARGUMENT_ARRAY", Const, 0}, + {"FORMAT_MESSAGE_FROM_HMODULE", Const, 0}, + {"FORMAT_MESSAGE_FROM_STRING", Const, 0}, + {"FORMAT_MESSAGE_FROM_SYSTEM", Const, 0}, + {"FORMAT_MESSAGE_IGNORE_INSERTS", Const, 0}, + {"FORMAT_MESSAGE_MAX_WIDTH_MASK", Const, 0}, + {"FSCTL_GET_REPARSE_POINT", Const, 4}, + {"F_ADDFILESIGS", Const, 0}, + {"F_ADDSIGS", Const, 0}, + {"F_ALLOCATEALL", Const, 0}, + {"F_ALLOCATECONTIG", Const, 0}, + {"F_CANCEL", Const, 0}, + {"F_CHKCLEAN", Const, 0}, + {"F_CLOSEM", Const, 1}, + {"F_DUP2FD", Const, 0}, + {"F_DUP2FD_CLOEXEC", Const, 1}, + {"F_DUPFD", Const, 0}, + {"F_DUPFD_CLOEXEC", Const, 0}, + {"F_EXLCK", Const, 0}, + {"F_FINDSIGS", Const, 16}, + {"F_FLUSH_DATA", Const, 0}, + {"F_FREEZE_FS", Const, 0}, + {"F_FSCTL", Const, 1}, + {"F_FSDIRMASK", Const, 1}, + {"F_FSIN", Const, 1}, + {"F_FSINOUT", Const, 1}, + {"F_FSOUT", Const, 1}, + {"F_FSPRIV", Const, 1}, + {"F_FSVOID", Const, 1}, + {"F_FULLFSYNC", Const, 0}, + {"F_GETCODEDIR", Const, 16}, + {"F_GETFD", Const, 0}, + {"F_GETFL", Const, 0}, + {"F_GETLEASE", Const, 0}, + {"F_GETLK", Const, 0}, + {"F_GETLK64", Const, 0}, + {"F_GETLKPID", Const, 0}, + {"F_GETNOSIGPIPE", Const, 0}, + {"F_GETOWN", Const, 0}, + {"F_GETOWN_EX", Const, 0}, + {"F_GETPATH", Const, 0}, + {"F_GETPATH_MTMINFO", Const, 0}, + {"F_GETPIPE_SZ", Const, 0}, + {"F_GETPROTECTIONCLASS", Const, 0}, + {"F_GETPROTECTIONLEVEL", Const, 16}, + {"F_GETSIG", Const, 0}, + {"F_GLOBAL_NOCACHE", Const, 0}, + {"F_LOCK", Const, 0}, + {"F_LOG2PHYS", Const, 0}, + {"F_LOG2PHYS_EXT", Const, 0}, + {"F_MARKDEPENDENCY", Const, 0}, + {"F_MAXFD", Const, 1}, + {"F_NOCACHE", Const, 0}, + {"F_NODIRECT", Const, 0}, + {"F_NOTIFY", Const, 0}, + {"F_OGETLK", Const, 0}, + {"F_OK", Const, 0}, + {"F_OSETLK", Const, 0}, + {"F_OSETLKW", Const, 0}, + {"F_PARAM_MASK", Const, 1}, + {"F_PARAM_MAX", Const, 1}, + {"F_PATHPKG_CHECK", Const, 0}, + {"F_PEOFPOSMODE", Const, 0}, + {"F_PREALLOCATE", Const, 0}, + {"F_RDADVISE", Const, 0}, + {"F_RDAHEAD", Const, 0}, + {"F_RDLCK", Const, 0}, + {"F_READAHEAD", Const, 0}, + {"F_READBOOTSTRAP", Const, 0}, + {"F_SETBACKINGSTORE", Const, 0}, + {"F_SETFD", Const, 0}, + {"F_SETFL", Const, 0}, + {"F_SETLEASE", Const, 0}, + {"F_SETLK", Const, 0}, + {"F_SETLK64", Const, 0}, + {"F_SETLKW", Const, 0}, + {"F_SETLKW64", Const, 0}, + {"F_SETLKWTIMEOUT", Const, 16}, + {"F_SETLK_REMOTE", Const, 0}, + {"F_SETNOSIGPIPE", Const, 0}, + {"F_SETOWN", Const, 0}, + {"F_SETOWN_EX", Const, 0}, + {"F_SETPIPE_SZ", Const, 0}, + {"F_SETPROTECTIONCLASS", Const, 0}, + {"F_SETSIG", Const, 0}, + {"F_SETSIZE", Const, 0}, + {"F_SHLCK", Const, 0}, + {"F_SINGLE_WRITER", Const, 16}, + {"F_TEST", Const, 0}, + {"F_THAW_FS", Const, 0}, + {"F_TLOCK", Const, 0}, + {"F_TRANSCODEKEY", Const, 16}, + {"F_ULOCK", Const, 0}, + {"F_UNLCK", Const, 0}, + {"F_UNLCKSYS", Const, 0}, + {"F_VOLPOSMODE", Const, 0}, + {"F_WRITEBOOTSTRAP", Const, 0}, + {"F_WRLCK", Const, 0}, + {"Faccessat", Func, 0}, + {"Fallocate", Func, 0}, + {"Fbootstraptransfer_t", Type, 0}, + {"Fbootstraptransfer_t.Buffer", Field, 0}, + {"Fbootstraptransfer_t.Length", Field, 0}, + {"Fbootstraptransfer_t.Offset", Field, 0}, + {"Fchdir", Func, 0}, + {"Fchflags", Func, 0}, + {"Fchmod", Func, 0}, + {"Fchmodat", Func, 0}, + {"Fchown", Func, 0}, + {"Fchownat", Func, 0}, + {"FcntlFlock", Func, 3}, + {"FdSet", Type, 0}, + {"FdSet.Bits", Field, 0}, + {"FdSet.X__fds_bits", Field, 0}, + {"Fdatasync", Func, 0}, + {"FileNotifyInformation", Type, 0}, + {"FileNotifyInformation.Action", Field, 0}, + {"FileNotifyInformation.FileName", Field, 0}, + {"FileNotifyInformation.FileNameLength", Field, 0}, + {"FileNotifyInformation.NextEntryOffset", Field, 0}, + {"Filetime", Type, 0}, + {"Filetime.HighDateTime", Field, 0}, + {"Filetime.LowDateTime", Field, 0}, + {"FindClose", Func, 0}, + {"FindFirstFile", Func, 0}, + {"FindNextFile", Func, 0}, + {"Flock", Func, 0}, + {"Flock_t", Type, 0}, + {"Flock_t.Len", Field, 0}, + {"Flock_t.Pad_cgo_0", Field, 0}, + {"Flock_t.Pad_cgo_1", Field, 3}, + {"Flock_t.Pid", Field, 0}, + {"Flock_t.Start", Field, 0}, + {"Flock_t.Sysid", Field, 0}, + {"Flock_t.Type", Field, 0}, + {"Flock_t.Whence", Field, 0}, + {"FlushBpf", Func, 0}, + {"FlushFileBuffers", Func, 0}, + {"FlushViewOfFile", Func, 0}, + {"ForkExec", Func, 0}, + {"ForkLock", Var, 0}, + {"FormatMessage", Func, 0}, + {"Fpathconf", Func, 0}, + {"FreeAddrInfoW", Func, 1}, + {"FreeEnvironmentStrings", Func, 0}, + {"FreeLibrary", Func, 0}, + {"Fsid", Type, 0}, + {"Fsid.Val", Field, 0}, + {"Fsid.X__fsid_val", Field, 2}, + {"Fsid.X__val", Field, 0}, + {"Fstat", Func, 0}, + {"Fstatat", Func, 12}, + {"Fstatfs", Func, 0}, + {"Fstore_t", Type, 0}, + {"Fstore_t.Bytesalloc", Field, 0}, + {"Fstore_t.Flags", Field, 0}, + {"Fstore_t.Length", Field, 0}, + {"Fstore_t.Offset", Field, 0}, + {"Fstore_t.Posmode", Field, 0}, + {"Fsync", Func, 0}, + {"Ftruncate", Func, 0}, + {"FullPath", Func, 4}, + {"Futimes", Func, 0}, + {"Futimesat", Func, 0}, + {"GENERIC_ALL", Const, 0}, + {"GENERIC_EXECUTE", Const, 0}, + {"GENERIC_READ", Const, 0}, + {"GENERIC_WRITE", Const, 0}, + {"GUID", Type, 1}, + {"GUID.Data1", Field, 1}, + {"GUID.Data2", Field, 1}, + {"GUID.Data3", Field, 1}, + {"GUID.Data4", Field, 1}, + {"GetAcceptExSockaddrs", Func, 0}, + {"GetAdaptersInfo", Func, 0}, + {"GetAddrInfoW", Func, 1}, + {"GetCommandLine", Func, 0}, + {"GetComputerName", Func, 0}, + {"GetConsoleMode", Func, 1}, + {"GetCurrentDirectory", Func, 0}, + {"GetCurrentProcess", Func, 0}, + {"GetEnvironmentStrings", Func, 0}, + {"GetEnvironmentVariable", Func, 0}, + {"GetExitCodeProcess", Func, 0}, + {"GetFileAttributes", Func, 0}, + {"GetFileAttributesEx", Func, 0}, + {"GetFileExInfoStandard", Const, 0}, + {"GetFileExMaxInfoLevel", Const, 0}, + {"GetFileInformationByHandle", Func, 0}, + {"GetFileType", Func, 0}, + {"GetFullPathName", Func, 0}, + {"GetHostByName", Func, 0}, + {"GetIfEntry", Func, 0}, + {"GetLastError", Func, 0}, + {"GetLengthSid", Func, 0}, + {"GetLongPathName", Func, 0}, + {"GetProcAddress", Func, 0}, + {"GetProcessTimes", Func, 0}, + {"GetProtoByName", Func, 0}, + {"GetQueuedCompletionStatus", Func, 0}, + {"GetServByName", Func, 0}, + {"GetShortPathName", Func, 0}, + {"GetStartupInfo", Func, 0}, + {"GetStdHandle", Func, 0}, + {"GetSystemTimeAsFileTime", Func, 0}, + {"GetTempPath", Func, 0}, + {"GetTimeZoneInformation", Func, 0}, + {"GetTokenInformation", Func, 0}, + {"GetUserNameEx", Func, 0}, + {"GetUserProfileDirectory", Func, 0}, + {"GetVersion", Func, 0}, + {"Getcwd", Func, 0}, + {"Getdents", Func, 0}, + {"Getdirentries", Func, 0}, + {"Getdtablesize", Func, 0}, + {"Getegid", Func, 0}, + {"Getenv", Func, 0}, + {"Geteuid", Func, 0}, + {"Getfsstat", Func, 0}, + {"Getgid", Func, 0}, + {"Getgroups", Func, 0}, + {"Getpagesize", Func, 0}, + {"Getpeername", Func, 0}, + {"Getpgid", Func, 0}, + {"Getpgrp", Func, 0}, + {"Getpid", Func, 0}, + {"Getppid", Func, 0}, + {"Getpriority", Func, 0}, + {"Getrlimit", Func, 0}, + {"Getrusage", Func, 0}, + {"Getsid", Func, 0}, + {"Getsockname", Func, 0}, + {"Getsockopt", Func, 1}, + {"GetsockoptByte", Func, 0}, + {"GetsockoptICMPv6Filter", Func, 2}, + {"GetsockoptIPMreq", Func, 0}, + {"GetsockoptIPMreqn", Func, 0}, + {"GetsockoptIPv6MTUInfo", Func, 2}, + {"GetsockoptIPv6Mreq", Func, 0}, + {"GetsockoptInet4Addr", Func, 0}, + {"GetsockoptInt", Func, 0}, + {"GetsockoptUcred", Func, 1}, + {"Gettid", Func, 0}, + {"Gettimeofday", Func, 0}, + {"Getuid", Func, 0}, + {"Getwd", Func, 0}, + {"Getxattr", Func, 1}, + {"HANDLE_FLAG_INHERIT", Const, 0}, + {"HKEY_CLASSES_ROOT", Const, 0}, + {"HKEY_CURRENT_CONFIG", Const, 0}, + {"HKEY_CURRENT_USER", Const, 0}, + {"HKEY_DYN_DATA", Const, 0}, + {"HKEY_LOCAL_MACHINE", Const, 0}, + {"HKEY_PERFORMANCE_DATA", Const, 0}, + {"HKEY_USERS", Const, 0}, + {"HUPCL", Const, 0}, + {"Handle", Type, 0}, + {"Hostent", Type, 0}, + {"Hostent.AddrList", Field, 0}, + {"Hostent.AddrType", Field, 0}, + {"Hostent.Aliases", Field, 0}, + {"Hostent.Length", Field, 0}, + {"Hostent.Name", Field, 0}, + {"ICANON", Const, 0}, + {"ICMP6_FILTER", Const, 2}, + {"ICMPV6_FILTER", Const, 2}, + {"ICMPv6Filter", Type, 2}, + {"ICMPv6Filter.Data", Field, 2}, + {"ICMPv6Filter.Filt", Field, 2}, + {"ICRNL", Const, 0}, + {"IEXTEN", Const, 0}, + {"IFAN_ARRIVAL", Const, 1}, + {"IFAN_DEPARTURE", Const, 1}, + {"IFA_ADDRESS", Const, 0}, + {"IFA_ANYCAST", Const, 0}, + {"IFA_BROADCAST", Const, 0}, + {"IFA_CACHEINFO", Const, 0}, + {"IFA_F_DADFAILED", Const, 0}, + {"IFA_F_DEPRECATED", Const, 0}, + {"IFA_F_HOMEADDRESS", Const, 0}, + {"IFA_F_NODAD", Const, 0}, + {"IFA_F_OPTIMISTIC", Const, 0}, + {"IFA_F_PERMANENT", Const, 0}, + {"IFA_F_SECONDARY", Const, 0}, + {"IFA_F_TEMPORARY", Const, 0}, + {"IFA_F_TENTATIVE", Const, 0}, + {"IFA_LABEL", Const, 0}, + {"IFA_LOCAL", Const, 0}, + {"IFA_MAX", Const, 0}, + {"IFA_MULTICAST", Const, 0}, + {"IFA_ROUTE", Const, 1}, + {"IFA_UNSPEC", Const, 0}, + {"IFF_ALLMULTI", Const, 0}, + {"IFF_ALTPHYS", Const, 0}, + {"IFF_AUTOMEDIA", Const, 0}, + {"IFF_BROADCAST", Const, 0}, + {"IFF_CANTCHANGE", Const, 0}, + {"IFF_CANTCONFIG", Const, 1}, + {"IFF_DEBUG", Const, 0}, + {"IFF_DRV_OACTIVE", Const, 0}, + {"IFF_DRV_RUNNING", Const, 0}, + {"IFF_DYING", Const, 0}, + {"IFF_DYNAMIC", Const, 0}, + {"IFF_LINK0", Const, 0}, + {"IFF_LINK1", Const, 0}, + {"IFF_LINK2", Const, 0}, + {"IFF_LOOPBACK", Const, 0}, + {"IFF_MASTER", Const, 0}, + {"IFF_MONITOR", Const, 0}, + {"IFF_MULTICAST", Const, 0}, + {"IFF_NOARP", Const, 0}, + {"IFF_NOTRAILERS", Const, 0}, + {"IFF_NO_PI", Const, 0}, + {"IFF_OACTIVE", Const, 0}, + {"IFF_ONE_QUEUE", Const, 0}, + {"IFF_POINTOPOINT", Const, 0}, + {"IFF_POINTTOPOINT", Const, 0}, + {"IFF_PORTSEL", Const, 0}, + {"IFF_PPROMISC", Const, 0}, + {"IFF_PROMISC", Const, 0}, + {"IFF_RENAMING", Const, 0}, + {"IFF_RUNNING", Const, 0}, + {"IFF_SIMPLEX", Const, 0}, + {"IFF_SLAVE", Const, 0}, + {"IFF_SMART", Const, 0}, + {"IFF_STATICARP", Const, 0}, + {"IFF_TAP", Const, 0}, + {"IFF_TUN", Const, 0}, + {"IFF_TUN_EXCL", Const, 0}, + {"IFF_UP", Const, 0}, + {"IFF_VNET_HDR", Const, 0}, + {"IFLA_ADDRESS", Const, 0}, + {"IFLA_BROADCAST", Const, 0}, + {"IFLA_COST", Const, 0}, + {"IFLA_IFALIAS", Const, 0}, + {"IFLA_IFNAME", Const, 0}, + {"IFLA_LINK", Const, 0}, + {"IFLA_LINKINFO", Const, 0}, + {"IFLA_LINKMODE", Const, 0}, + {"IFLA_MAP", Const, 0}, + {"IFLA_MASTER", Const, 0}, + {"IFLA_MAX", Const, 0}, + {"IFLA_MTU", Const, 0}, + {"IFLA_NET_NS_PID", Const, 0}, + {"IFLA_OPERSTATE", Const, 0}, + {"IFLA_PRIORITY", Const, 0}, + {"IFLA_PROTINFO", Const, 0}, + {"IFLA_QDISC", Const, 0}, + {"IFLA_STATS", Const, 0}, + {"IFLA_TXQLEN", Const, 0}, + {"IFLA_UNSPEC", Const, 0}, + {"IFLA_WEIGHT", Const, 0}, + {"IFLA_WIRELESS", Const, 0}, + {"IFNAMSIZ", Const, 0}, + {"IFT_1822", Const, 0}, + {"IFT_A12MPPSWITCH", Const, 0}, + {"IFT_AAL2", Const, 0}, + {"IFT_AAL5", Const, 0}, + {"IFT_ADSL", Const, 0}, + {"IFT_AFLANE8023", Const, 0}, + {"IFT_AFLANE8025", Const, 0}, + {"IFT_ARAP", Const, 0}, + {"IFT_ARCNET", Const, 0}, + {"IFT_ARCNETPLUS", Const, 0}, + {"IFT_ASYNC", Const, 0}, + {"IFT_ATM", Const, 0}, + {"IFT_ATMDXI", Const, 0}, + {"IFT_ATMFUNI", Const, 0}, + {"IFT_ATMIMA", Const, 0}, + {"IFT_ATMLOGICAL", Const, 0}, + {"IFT_ATMRADIO", Const, 0}, + {"IFT_ATMSUBINTERFACE", Const, 0}, + {"IFT_ATMVCIENDPT", Const, 0}, + {"IFT_ATMVIRTUAL", Const, 0}, + {"IFT_BGPPOLICYACCOUNTING", Const, 0}, + {"IFT_BLUETOOTH", Const, 1}, + {"IFT_BRIDGE", Const, 0}, + {"IFT_BSC", Const, 0}, + {"IFT_CARP", Const, 0}, + {"IFT_CCTEMUL", Const, 0}, + {"IFT_CELLULAR", Const, 0}, + {"IFT_CEPT", Const, 0}, + {"IFT_CES", Const, 0}, + {"IFT_CHANNEL", Const, 0}, + {"IFT_CNR", Const, 0}, + {"IFT_COFFEE", Const, 0}, + {"IFT_COMPOSITELINK", Const, 0}, + {"IFT_DCN", Const, 0}, + {"IFT_DIGITALPOWERLINE", Const, 0}, + {"IFT_DIGITALWRAPPEROVERHEADCHANNEL", Const, 0}, + {"IFT_DLSW", Const, 0}, + {"IFT_DOCSCABLEDOWNSTREAM", Const, 0}, + {"IFT_DOCSCABLEMACLAYER", Const, 0}, + {"IFT_DOCSCABLEUPSTREAM", Const, 0}, + {"IFT_DOCSCABLEUPSTREAMCHANNEL", Const, 1}, + {"IFT_DS0", Const, 0}, + {"IFT_DS0BUNDLE", Const, 0}, + {"IFT_DS1FDL", Const, 0}, + {"IFT_DS3", Const, 0}, + {"IFT_DTM", Const, 0}, + {"IFT_DUMMY", Const, 1}, + {"IFT_DVBASILN", Const, 0}, + {"IFT_DVBASIOUT", Const, 0}, + {"IFT_DVBRCCDOWNSTREAM", Const, 0}, + {"IFT_DVBRCCMACLAYER", Const, 0}, + {"IFT_DVBRCCUPSTREAM", Const, 0}, + {"IFT_ECONET", Const, 1}, + {"IFT_ENC", Const, 0}, + {"IFT_EON", Const, 0}, + {"IFT_EPLRS", Const, 0}, + {"IFT_ESCON", Const, 0}, + {"IFT_ETHER", Const, 0}, + {"IFT_FAITH", Const, 0}, + {"IFT_FAST", Const, 0}, + {"IFT_FASTETHER", Const, 0}, + {"IFT_FASTETHERFX", Const, 0}, + {"IFT_FDDI", Const, 0}, + {"IFT_FIBRECHANNEL", Const, 0}, + {"IFT_FRAMERELAYINTERCONNECT", Const, 0}, + {"IFT_FRAMERELAYMPI", Const, 0}, + {"IFT_FRDLCIENDPT", Const, 0}, + {"IFT_FRELAY", Const, 0}, + {"IFT_FRELAYDCE", Const, 0}, + {"IFT_FRF16MFRBUNDLE", Const, 0}, + {"IFT_FRFORWARD", Const, 0}, + {"IFT_G703AT2MB", Const, 0}, + {"IFT_G703AT64K", Const, 0}, + {"IFT_GIF", Const, 0}, + {"IFT_GIGABITETHERNET", Const, 0}, + {"IFT_GR303IDT", Const, 0}, + {"IFT_GR303RDT", Const, 0}, + {"IFT_H323GATEKEEPER", Const, 0}, + {"IFT_H323PROXY", Const, 0}, + {"IFT_HDH1822", Const, 0}, + {"IFT_HDLC", Const, 0}, + {"IFT_HDSL2", Const, 0}, + {"IFT_HIPERLAN2", Const, 0}, + {"IFT_HIPPI", Const, 0}, + {"IFT_HIPPIINTERFACE", Const, 0}, + {"IFT_HOSTPAD", Const, 0}, + {"IFT_HSSI", Const, 0}, + {"IFT_HY", Const, 0}, + {"IFT_IBM370PARCHAN", Const, 0}, + {"IFT_IDSL", Const, 0}, + {"IFT_IEEE1394", Const, 0}, + {"IFT_IEEE80211", Const, 0}, + {"IFT_IEEE80212", Const, 0}, + {"IFT_IEEE8023ADLAG", Const, 0}, + {"IFT_IFGSN", Const, 0}, + {"IFT_IMT", Const, 0}, + {"IFT_INFINIBAND", Const, 1}, + {"IFT_INTERLEAVE", Const, 0}, + {"IFT_IP", Const, 0}, + {"IFT_IPFORWARD", Const, 0}, + {"IFT_IPOVERATM", Const, 0}, + {"IFT_IPOVERCDLC", Const, 0}, + {"IFT_IPOVERCLAW", Const, 0}, + {"IFT_IPSWITCH", Const, 0}, + {"IFT_IPXIP", Const, 0}, + {"IFT_ISDN", Const, 0}, + {"IFT_ISDNBASIC", Const, 0}, + {"IFT_ISDNPRIMARY", Const, 0}, + {"IFT_ISDNS", Const, 0}, + {"IFT_ISDNU", Const, 0}, + {"IFT_ISO88022LLC", Const, 0}, + {"IFT_ISO88023", Const, 0}, + {"IFT_ISO88024", Const, 0}, + {"IFT_ISO88025", Const, 0}, + {"IFT_ISO88025CRFPINT", Const, 0}, + {"IFT_ISO88025DTR", Const, 0}, + {"IFT_ISO88025FIBER", Const, 0}, + {"IFT_ISO88026", Const, 0}, + {"IFT_ISUP", Const, 0}, + {"IFT_L2VLAN", Const, 0}, + {"IFT_L3IPVLAN", Const, 0}, + {"IFT_L3IPXVLAN", Const, 0}, + {"IFT_LAPB", Const, 0}, + {"IFT_LAPD", Const, 0}, + {"IFT_LAPF", Const, 0}, + {"IFT_LINEGROUP", Const, 1}, + {"IFT_LOCALTALK", Const, 0}, + {"IFT_LOOP", Const, 0}, + {"IFT_MEDIAMAILOVERIP", Const, 0}, + {"IFT_MFSIGLINK", Const, 0}, + {"IFT_MIOX25", Const, 0}, + {"IFT_MODEM", Const, 0}, + {"IFT_MPC", Const, 0}, + {"IFT_MPLS", Const, 0}, + {"IFT_MPLSTUNNEL", Const, 0}, + {"IFT_MSDSL", Const, 0}, + {"IFT_MVL", Const, 0}, + {"IFT_MYRINET", Const, 0}, + {"IFT_NFAS", Const, 0}, + {"IFT_NSIP", Const, 0}, + {"IFT_OPTICALCHANNEL", Const, 0}, + {"IFT_OPTICALTRANSPORT", Const, 0}, + {"IFT_OTHER", Const, 0}, + {"IFT_P10", Const, 0}, + {"IFT_P80", Const, 0}, + {"IFT_PARA", Const, 0}, + {"IFT_PDP", Const, 0}, + {"IFT_PFLOG", Const, 0}, + {"IFT_PFLOW", Const, 1}, + {"IFT_PFSYNC", Const, 0}, + {"IFT_PLC", Const, 0}, + {"IFT_PON155", Const, 1}, + {"IFT_PON622", Const, 1}, + {"IFT_POS", Const, 0}, + {"IFT_PPP", Const, 0}, + {"IFT_PPPMULTILINKBUNDLE", Const, 0}, + {"IFT_PROPATM", Const, 1}, + {"IFT_PROPBWAP2MP", Const, 0}, + {"IFT_PROPCNLS", Const, 0}, + {"IFT_PROPDOCSWIRELESSDOWNSTREAM", Const, 0}, + {"IFT_PROPDOCSWIRELESSMACLAYER", Const, 0}, + {"IFT_PROPDOCSWIRELESSUPSTREAM", Const, 0}, + {"IFT_PROPMUX", Const, 0}, + {"IFT_PROPVIRTUAL", Const, 0}, + {"IFT_PROPWIRELESSP2P", Const, 0}, + {"IFT_PTPSERIAL", Const, 0}, + {"IFT_PVC", Const, 0}, + {"IFT_Q2931", Const, 1}, + {"IFT_QLLC", Const, 0}, + {"IFT_RADIOMAC", Const, 0}, + {"IFT_RADSL", Const, 0}, + {"IFT_REACHDSL", Const, 0}, + {"IFT_RFC1483", Const, 0}, + {"IFT_RS232", Const, 0}, + {"IFT_RSRB", Const, 0}, + {"IFT_SDLC", Const, 0}, + {"IFT_SDSL", Const, 0}, + {"IFT_SHDSL", Const, 0}, + {"IFT_SIP", Const, 0}, + {"IFT_SIPSIG", Const, 1}, + {"IFT_SIPTG", Const, 1}, + {"IFT_SLIP", Const, 0}, + {"IFT_SMDSDXI", Const, 0}, + {"IFT_SMDSICIP", Const, 0}, + {"IFT_SONET", Const, 0}, + {"IFT_SONETOVERHEADCHANNEL", Const, 0}, + {"IFT_SONETPATH", Const, 0}, + {"IFT_SONETVT", Const, 0}, + {"IFT_SRP", Const, 0}, + {"IFT_SS7SIGLINK", Const, 0}, + {"IFT_STACKTOSTACK", Const, 0}, + {"IFT_STARLAN", Const, 0}, + {"IFT_STF", Const, 0}, + {"IFT_T1", Const, 0}, + {"IFT_TDLC", Const, 0}, + {"IFT_TELINK", Const, 1}, + {"IFT_TERMPAD", Const, 0}, + {"IFT_TR008", Const, 0}, + {"IFT_TRANSPHDLC", Const, 0}, + {"IFT_TUNNEL", Const, 0}, + {"IFT_ULTRA", Const, 0}, + {"IFT_USB", Const, 0}, + {"IFT_V11", Const, 0}, + {"IFT_V35", Const, 0}, + {"IFT_V36", Const, 0}, + {"IFT_V37", Const, 0}, + {"IFT_VDSL", Const, 0}, + {"IFT_VIRTUALIPADDRESS", Const, 0}, + {"IFT_VIRTUALTG", Const, 1}, + {"IFT_VOICEDID", Const, 1}, + {"IFT_VOICEEM", Const, 0}, + {"IFT_VOICEEMFGD", Const, 1}, + {"IFT_VOICEENCAP", Const, 0}, + {"IFT_VOICEFGDEANA", Const, 1}, + {"IFT_VOICEFXO", Const, 0}, + {"IFT_VOICEFXS", Const, 0}, + {"IFT_VOICEOVERATM", Const, 0}, + {"IFT_VOICEOVERCABLE", Const, 1}, + {"IFT_VOICEOVERFRAMERELAY", Const, 0}, + {"IFT_VOICEOVERIP", Const, 0}, + {"IFT_X213", Const, 0}, + {"IFT_X25", Const, 0}, + {"IFT_X25DDN", Const, 0}, + {"IFT_X25HUNTGROUP", Const, 0}, + {"IFT_X25MLP", Const, 0}, + {"IFT_X25PLE", Const, 0}, + {"IFT_XETHER", Const, 0}, + {"IGNBRK", Const, 0}, + {"IGNCR", Const, 0}, + {"IGNORE", Const, 0}, + {"IGNPAR", Const, 0}, + {"IMAXBEL", Const, 0}, + {"INFINITE", Const, 0}, + {"INLCR", Const, 0}, + {"INPCK", Const, 0}, + {"INVALID_FILE_ATTRIBUTES", Const, 0}, + {"IN_ACCESS", Const, 0}, + {"IN_ALL_EVENTS", Const, 0}, + {"IN_ATTRIB", Const, 0}, + {"IN_CLASSA_HOST", Const, 0}, + {"IN_CLASSA_MAX", Const, 0}, + {"IN_CLASSA_NET", Const, 0}, + {"IN_CLASSA_NSHIFT", Const, 0}, + {"IN_CLASSB_HOST", Const, 0}, + {"IN_CLASSB_MAX", Const, 0}, + {"IN_CLASSB_NET", Const, 0}, + {"IN_CLASSB_NSHIFT", Const, 0}, + {"IN_CLASSC_HOST", Const, 0}, + {"IN_CLASSC_NET", Const, 0}, + {"IN_CLASSC_NSHIFT", Const, 0}, + {"IN_CLASSD_HOST", Const, 0}, + {"IN_CLASSD_NET", Const, 0}, + {"IN_CLASSD_NSHIFT", Const, 0}, + {"IN_CLOEXEC", Const, 0}, + {"IN_CLOSE", Const, 0}, + {"IN_CLOSE_NOWRITE", Const, 0}, + {"IN_CLOSE_WRITE", Const, 0}, + {"IN_CREATE", Const, 0}, + {"IN_DELETE", Const, 0}, + {"IN_DELETE_SELF", Const, 0}, + {"IN_DONT_FOLLOW", Const, 0}, + {"IN_EXCL_UNLINK", Const, 0}, + {"IN_IGNORED", Const, 0}, + {"IN_ISDIR", Const, 0}, + {"IN_LINKLOCALNETNUM", Const, 0}, + {"IN_LOOPBACKNET", Const, 0}, + {"IN_MASK_ADD", Const, 0}, + {"IN_MODIFY", Const, 0}, + {"IN_MOVE", Const, 0}, + {"IN_MOVED_FROM", Const, 0}, + {"IN_MOVED_TO", Const, 0}, + {"IN_MOVE_SELF", Const, 0}, + {"IN_NONBLOCK", Const, 0}, + {"IN_ONESHOT", Const, 0}, + {"IN_ONLYDIR", Const, 0}, + {"IN_OPEN", Const, 0}, + {"IN_Q_OVERFLOW", Const, 0}, + {"IN_RFC3021_HOST", Const, 1}, + {"IN_RFC3021_MASK", Const, 1}, + {"IN_RFC3021_NET", Const, 1}, + {"IN_RFC3021_NSHIFT", Const, 1}, + {"IN_UNMOUNT", Const, 0}, + {"IOC_IN", Const, 1}, + {"IOC_INOUT", Const, 1}, + {"IOC_OUT", Const, 1}, + {"IOC_VENDOR", Const, 3}, + {"IOC_WS2", Const, 1}, + {"IO_REPARSE_TAG_SYMLINK", Const, 4}, + {"IPMreq", Type, 0}, + {"IPMreq.Interface", Field, 0}, + {"IPMreq.Multiaddr", Field, 0}, + {"IPMreqn", Type, 0}, + {"IPMreqn.Address", Field, 0}, + {"IPMreqn.Ifindex", Field, 0}, + {"IPMreqn.Multiaddr", Field, 0}, + {"IPPROTO_3PC", Const, 0}, + {"IPPROTO_ADFS", Const, 0}, + {"IPPROTO_AH", Const, 0}, + {"IPPROTO_AHIP", Const, 0}, + {"IPPROTO_APES", Const, 0}, + {"IPPROTO_ARGUS", Const, 0}, + {"IPPROTO_AX25", Const, 0}, + {"IPPROTO_BHA", Const, 0}, + {"IPPROTO_BLT", Const, 0}, + {"IPPROTO_BRSATMON", Const, 0}, + {"IPPROTO_CARP", Const, 0}, + {"IPPROTO_CFTP", Const, 0}, + {"IPPROTO_CHAOS", Const, 0}, + {"IPPROTO_CMTP", Const, 0}, + {"IPPROTO_COMP", Const, 0}, + {"IPPROTO_CPHB", Const, 0}, + {"IPPROTO_CPNX", Const, 0}, + {"IPPROTO_DCCP", Const, 0}, + {"IPPROTO_DDP", Const, 0}, + {"IPPROTO_DGP", Const, 0}, + {"IPPROTO_DIVERT", Const, 0}, + {"IPPROTO_DIVERT_INIT", Const, 3}, + {"IPPROTO_DIVERT_RESP", Const, 3}, + {"IPPROTO_DONE", Const, 0}, + {"IPPROTO_DSTOPTS", Const, 0}, + {"IPPROTO_EGP", Const, 0}, + {"IPPROTO_EMCON", Const, 0}, + {"IPPROTO_ENCAP", Const, 0}, + {"IPPROTO_EON", Const, 0}, + {"IPPROTO_ESP", Const, 0}, + {"IPPROTO_ETHERIP", Const, 0}, + {"IPPROTO_FRAGMENT", Const, 0}, + {"IPPROTO_GGP", Const, 0}, + {"IPPROTO_GMTP", Const, 0}, + {"IPPROTO_GRE", Const, 0}, + {"IPPROTO_HELLO", Const, 0}, + {"IPPROTO_HMP", Const, 0}, + {"IPPROTO_HOPOPTS", Const, 0}, + {"IPPROTO_ICMP", Const, 0}, + {"IPPROTO_ICMPV6", Const, 0}, + {"IPPROTO_IDP", Const, 0}, + {"IPPROTO_IDPR", Const, 0}, + {"IPPROTO_IDRP", Const, 0}, + {"IPPROTO_IGMP", Const, 0}, + {"IPPROTO_IGP", Const, 0}, + {"IPPROTO_IGRP", Const, 0}, + {"IPPROTO_IL", Const, 0}, + {"IPPROTO_INLSP", Const, 0}, + {"IPPROTO_INP", Const, 0}, + {"IPPROTO_IP", Const, 0}, + {"IPPROTO_IPCOMP", Const, 0}, + {"IPPROTO_IPCV", Const, 0}, + {"IPPROTO_IPEIP", Const, 0}, + {"IPPROTO_IPIP", Const, 0}, + {"IPPROTO_IPPC", Const, 0}, + {"IPPROTO_IPV4", Const, 0}, + {"IPPROTO_IPV6", Const, 0}, + {"IPPROTO_IPV6_ICMP", Const, 1}, + {"IPPROTO_IRTP", Const, 0}, + {"IPPROTO_KRYPTOLAN", Const, 0}, + {"IPPROTO_LARP", Const, 0}, + {"IPPROTO_LEAF1", Const, 0}, + {"IPPROTO_LEAF2", Const, 0}, + {"IPPROTO_MAX", Const, 0}, + {"IPPROTO_MAXID", Const, 0}, + {"IPPROTO_MEAS", Const, 0}, + {"IPPROTO_MH", Const, 1}, + {"IPPROTO_MHRP", Const, 0}, + {"IPPROTO_MICP", Const, 0}, + {"IPPROTO_MOBILE", Const, 0}, + {"IPPROTO_MPLS", Const, 1}, + {"IPPROTO_MTP", Const, 0}, + {"IPPROTO_MUX", Const, 0}, + {"IPPROTO_ND", Const, 0}, + {"IPPROTO_NHRP", Const, 0}, + {"IPPROTO_NONE", Const, 0}, + {"IPPROTO_NSP", Const, 0}, + {"IPPROTO_NVPII", Const, 0}, + {"IPPROTO_OLD_DIVERT", Const, 0}, + {"IPPROTO_OSPFIGP", Const, 0}, + {"IPPROTO_PFSYNC", Const, 0}, + {"IPPROTO_PGM", Const, 0}, + {"IPPROTO_PIGP", Const, 0}, + {"IPPROTO_PIM", Const, 0}, + {"IPPROTO_PRM", Const, 0}, + {"IPPROTO_PUP", Const, 0}, + {"IPPROTO_PVP", Const, 0}, + {"IPPROTO_RAW", Const, 0}, + {"IPPROTO_RCCMON", Const, 0}, + {"IPPROTO_RDP", Const, 0}, + {"IPPROTO_ROUTING", Const, 0}, + {"IPPROTO_RSVP", Const, 0}, + {"IPPROTO_RVD", Const, 0}, + {"IPPROTO_SATEXPAK", Const, 0}, + {"IPPROTO_SATMON", Const, 0}, + {"IPPROTO_SCCSP", Const, 0}, + {"IPPROTO_SCTP", Const, 0}, + {"IPPROTO_SDRP", Const, 0}, + {"IPPROTO_SEND", Const, 1}, + {"IPPROTO_SEP", Const, 0}, + {"IPPROTO_SKIP", Const, 0}, + {"IPPROTO_SPACER", Const, 0}, + {"IPPROTO_SRPC", Const, 0}, + {"IPPROTO_ST", Const, 0}, + {"IPPROTO_SVMTP", Const, 0}, + {"IPPROTO_SWIPE", Const, 0}, + {"IPPROTO_TCF", Const, 0}, + {"IPPROTO_TCP", Const, 0}, + {"IPPROTO_TLSP", Const, 0}, + {"IPPROTO_TP", Const, 0}, + {"IPPROTO_TPXX", Const, 0}, + {"IPPROTO_TRUNK1", Const, 0}, + {"IPPROTO_TRUNK2", Const, 0}, + {"IPPROTO_TTP", Const, 0}, + {"IPPROTO_UDP", Const, 0}, + {"IPPROTO_UDPLITE", Const, 0}, + {"IPPROTO_VINES", Const, 0}, + {"IPPROTO_VISA", Const, 0}, + {"IPPROTO_VMTP", Const, 0}, + {"IPPROTO_VRRP", Const, 1}, + {"IPPROTO_WBEXPAK", Const, 0}, + {"IPPROTO_WBMON", Const, 0}, + {"IPPROTO_WSN", Const, 0}, + {"IPPROTO_XNET", Const, 0}, + {"IPPROTO_XTP", Const, 0}, + {"IPV6_2292DSTOPTS", Const, 0}, + {"IPV6_2292HOPLIMIT", Const, 0}, + {"IPV6_2292HOPOPTS", Const, 0}, + {"IPV6_2292NEXTHOP", Const, 0}, + {"IPV6_2292PKTINFO", Const, 0}, + {"IPV6_2292PKTOPTIONS", Const, 0}, + {"IPV6_2292RTHDR", Const, 0}, + {"IPV6_ADDRFORM", Const, 0}, + {"IPV6_ADD_MEMBERSHIP", Const, 0}, + {"IPV6_AUTHHDR", Const, 0}, + {"IPV6_AUTH_LEVEL", Const, 1}, + {"IPV6_AUTOFLOWLABEL", Const, 0}, + {"IPV6_BINDANY", Const, 0}, + {"IPV6_BINDV6ONLY", Const, 0}, + {"IPV6_BOUND_IF", Const, 0}, + {"IPV6_CHECKSUM", Const, 0}, + {"IPV6_DEFAULT_MULTICAST_HOPS", Const, 0}, + {"IPV6_DEFAULT_MULTICAST_LOOP", Const, 0}, + {"IPV6_DEFHLIM", Const, 0}, + {"IPV6_DONTFRAG", Const, 0}, + {"IPV6_DROP_MEMBERSHIP", Const, 0}, + {"IPV6_DSTOPTS", Const, 0}, + {"IPV6_ESP_NETWORK_LEVEL", Const, 1}, + {"IPV6_ESP_TRANS_LEVEL", Const, 1}, + {"IPV6_FAITH", Const, 0}, + {"IPV6_FLOWINFO_MASK", Const, 0}, + {"IPV6_FLOWLABEL_MASK", Const, 0}, + {"IPV6_FRAGTTL", Const, 0}, + {"IPV6_FW_ADD", Const, 0}, + {"IPV6_FW_DEL", Const, 0}, + {"IPV6_FW_FLUSH", Const, 0}, + {"IPV6_FW_GET", Const, 0}, + {"IPV6_FW_ZERO", Const, 0}, + {"IPV6_HLIMDEC", Const, 0}, + {"IPV6_HOPLIMIT", Const, 0}, + {"IPV6_HOPOPTS", Const, 0}, + {"IPV6_IPCOMP_LEVEL", Const, 1}, + {"IPV6_IPSEC_POLICY", Const, 0}, + {"IPV6_JOIN_ANYCAST", Const, 0}, + {"IPV6_JOIN_GROUP", Const, 0}, + {"IPV6_LEAVE_ANYCAST", Const, 0}, + {"IPV6_LEAVE_GROUP", Const, 0}, + {"IPV6_MAXHLIM", Const, 0}, + {"IPV6_MAXOPTHDR", Const, 0}, + {"IPV6_MAXPACKET", Const, 0}, + {"IPV6_MAX_GROUP_SRC_FILTER", Const, 0}, + {"IPV6_MAX_MEMBERSHIPS", Const, 0}, + {"IPV6_MAX_SOCK_SRC_FILTER", Const, 0}, + {"IPV6_MIN_MEMBERSHIPS", Const, 0}, + {"IPV6_MMTU", Const, 0}, + {"IPV6_MSFILTER", Const, 0}, + {"IPV6_MTU", Const, 0}, + {"IPV6_MTU_DISCOVER", Const, 0}, + {"IPV6_MULTICAST_HOPS", Const, 0}, + {"IPV6_MULTICAST_IF", Const, 0}, + {"IPV6_MULTICAST_LOOP", Const, 0}, + {"IPV6_NEXTHOP", Const, 0}, + {"IPV6_OPTIONS", Const, 1}, + {"IPV6_PATHMTU", Const, 0}, + {"IPV6_PIPEX", Const, 1}, + {"IPV6_PKTINFO", Const, 0}, + {"IPV6_PMTUDISC_DO", Const, 0}, + {"IPV6_PMTUDISC_DONT", Const, 0}, + {"IPV6_PMTUDISC_PROBE", Const, 0}, + {"IPV6_PMTUDISC_WANT", Const, 0}, + {"IPV6_PORTRANGE", Const, 0}, + {"IPV6_PORTRANGE_DEFAULT", Const, 0}, + {"IPV6_PORTRANGE_HIGH", Const, 0}, + {"IPV6_PORTRANGE_LOW", Const, 0}, + {"IPV6_PREFER_TEMPADDR", Const, 0}, + {"IPV6_RECVDSTOPTS", Const, 0}, + {"IPV6_RECVDSTPORT", Const, 3}, + {"IPV6_RECVERR", Const, 0}, + {"IPV6_RECVHOPLIMIT", Const, 0}, + {"IPV6_RECVHOPOPTS", Const, 0}, + {"IPV6_RECVPATHMTU", Const, 0}, + {"IPV6_RECVPKTINFO", Const, 0}, + {"IPV6_RECVRTHDR", Const, 0}, + {"IPV6_RECVTCLASS", Const, 0}, + {"IPV6_ROUTER_ALERT", Const, 0}, + {"IPV6_RTABLE", Const, 1}, + {"IPV6_RTHDR", Const, 0}, + {"IPV6_RTHDRDSTOPTS", Const, 0}, + {"IPV6_RTHDR_LOOSE", Const, 0}, + {"IPV6_RTHDR_STRICT", Const, 0}, + {"IPV6_RTHDR_TYPE_0", Const, 0}, + {"IPV6_RXDSTOPTS", Const, 0}, + {"IPV6_RXHOPOPTS", Const, 0}, + {"IPV6_SOCKOPT_RESERVED1", Const, 0}, + {"IPV6_TCLASS", Const, 0}, + {"IPV6_UNICAST_HOPS", Const, 0}, + {"IPV6_USE_MIN_MTU", Const, 0}, + {"IPV6_V6ONLY", Const, 0}, + {"IPV6_VERSION", Const, 0}, + {"IPV6_VERSION_MASK", Const, 0}, + {"IPV6_XFRM_POLICY", Const, 0}, + {"IP_ADD_MEMBERSHIP", Const, 0}, + {"IP_ADD_SOURCE_MEMBERSHIP", Const, 0}, + {"IP_AUTH_LEVEL", Const, 1}, + {"IP_BINDANY", Const, 0}, + {"IP_BLOCK_SOURCE", Const, 0}, + {"IP_BOUND_IF", Const, 0}, + {"IP_DEFAULT_MULTICAST_LOOP", Const, 0}, + {"IP_DEFAULT_MULTICAST_TTL", Const, 0}, + {"IP_DF", Const, 0}, + {"IP_DIVERTFL", Const, 3}, + {"IP_DONTFRAG", Const, 0}, + {"IP_DROP_MEMBERSHIP", Const, 0}, + {"IP_DROP_SOURCE_MEMBERSHIP", Const, 0}, + {"IP_DUMMYNET3", Const, 0}, + {"IP_DUMMYNET_CONFIGURE", Const, 0}, + {"IP_DUMMYNET_DEL", Const, 0}, + {"IP_DUMMYNET_FLUSH", Const, 0}, + {"IP_DUMMYNET_GET", Const, 0}, + {"IP_EF", Const, 1}, + {"IP_ERRORMTU", Const, 1}, + {"IP_ESP_NETWORK_LEVEL", Const, 1}, + {"IP_ESP_TRANS_LEVEL", Const, 1}, + {"IP_FAITH", Const, 0}, + {"IP_FREEBIND", Const, 0}, + {"IP_FW3", Const, 0}, + {"IP_FW_ADD", Const, 0}, + {"IP_FW_DEL", Const, 0}, + {"IP_FW_FLUSH", Const, 0}, + {"IP_FW_GET", Const, 0}, + {"IP_FW_NAT_CFG", Const, 0}, + {"IP_FW_NAT_DEL", Const, 0}, + {"IP_FW_NAT_GET_CONFIG", Const, 0}, + {"IP_FW_NAT_GET_LOG", Const, 0}, + {"IP_FW_RESETLOG", Const, 0}, + {"IP_FW_TABLE_ADD", Const, 0}, + {"IP_FW_TABLE_DEL", Const, 0}, + {"IP_FW_TABLE_FLUSH", Const, 0}, + {"IP_FW_TABLE_GETSIZE", Const, 0}, + {"IP_FW_TABLE_LIST", Const, 0}, + {"IP_FW_ZERO", Const, 0}, + {"IP_HDRINCL", Const, 0}, + {"IP_IPCOMP_LEVEL", Const, 1}, + {"IP_IPSECFLOWINFO", Const, 1}, + {"IP_IPSEC_LOCAL_AUTH", Const, 1}, + {"IP_IPSEC_LOCAL_CRED", Const, 1}, + {"IP_IPSEC_LOCAL_ID", Const, 1}, + {"IP_IPSEC_POLICY", Const, 0}, + {"IP_IPSEC_REMOTE_AUTH", Const, 1}, + {"IP_IPSEC_REMOTE_CRED", Const, 1}, + {"IP_IPSEC_REMOTE_ID", Const, 1}, + {"IP_MAXPACKET", Const, 0}, + {"IP_MAX_GROUP_SRC_FILTER", Const, 0}, + {"IP_MAX_MEMBERSHIPS", Const, 0}, + {"IP_MAX_SOCK_MUTE_FILTER", Const, 0}, + {"IP_MAX_SOCK_SRC_FILTER", Const, 0}, + {"IP_MAX_SOURCE_FILTER", Const, 0}, + {"IP_MF", Const, 0}, + {"IP_MINFRAGSIZE", Const, 1}, + {"IP_MINTTL", Const, 0}, + {"IP_MIN_MEMBERSHIPS", Const, 0}, + {"IP_MSFILTER", Const, 0}, + {"IP_MSS", Const, 0}, + {"IP_MTU", Const, 0}, + {"IP_MTU_DISCOVER", Const, 0}, + {"IP_MULTICAST_IF", Const, 0}, + {"IP_MULTICAST_IFINDEX", Const, 0}, + {"IP_MULTICAST_LOOP", Const, 0}, + {"IP_MULTICAST_TTL", Const, 0}, + {"IP_MULTICAST_VIF", Const, 0}, + {"IP_NAT__XXX", Const, 0}, + {"IP_OFFMASK", Const, 0}, + {"IP_OLD_FW_ADD", Const, 0}, + {"IP_OLD_FW_DEL", Const, 0}, + {"IP_OLD_FW_FLUSH", Const, 0}, + {"IP_OLD_FW_GET", Const, 0}, + {"IP_OLD_FW_RESETLOG", Const, 0}, + {"IP_OLD_FW_ZERO", Const, 0}, + {"IP_ONESBCAST", Const, 0}, + {"IP_OPTIONS", Const, 0}, + {"IP_ORIGDSTADDR", Const, 0}, + {"IP_PASSSEC", Const, 0}, + {"IP_PIPEX", Const, 1}, + {"IP_PKTINFO", Const, 0}, + {"IP_PKTOPTIONS", Const, 0}, + {"IP_PMTUDISC", Const, 0}, + {"IP_PMTUDISC_DO", Const, 0}, + {"IP_PMTUDISC_DONT", Const, 0}, + {"IP_PMTUDISC_PROBE", Const, 0}, + {"IP_PMTUDISC_WANT", Const, 0}, + {"IP_PORTRANGE", Const, 0}, + {"IP_PORTRANGE_DEFAULT", Const, 0}, + {"IP_PORTRANGE_HIGH", Const, 0}, + {"IP_PORTRANGE_LOW", Const, 0}, + {"IP_RECVDSTADDR", Const, 0}, + {"IP_RECVDSTPORT", Const, 1}, + {"IP_RECVERR", Const, 0}, + {"IP_RECVIF", Const, 0}, + {"IP_RECVOPTS", Const, 0}, + {"IP_RECVORIGDSTADDR", Const, 0}, + {"IP_RECVPKTINFO", Const, 0}, + {"IP_RECVRETOPTS", Const, 0}, + {"IP_RECVRTABLE", Const, 1}, + {"IP_RECVTOS", Const, 0}, + {"IP_RECVTTL", Const, 0}, + {"IP_RETOPTS", Const, 0}, + {"IP_RF", Const, 0}, + {"IP_ROUTER_ALERT", Const, 0}, + {"IP_RSVP_OFF", Const, 0}, + {"IP_RSVP_ON", Const, 0}, + {"IP_RSVP_VIF_OFF", Const, 0}, + {"IP_RSVP_VIF_ON", Const, 0}, + {"IP_RTABLE", Const, 1}, + {"IP_SENDSRCADDR", Const, 0}, + {"IP_STRIPHDR", Const, 0}, + {"IP_TOS", Const, 0}, + {"IP_TRAFFIC_MGT_BACKGROUND", Const, 0}, + {"IP_TRANSPARENT", Const, 0}, + {"IP_TTL", Const, 0}, + {"IP_UNBLOCK_SOURCE", Const, 0}, + {"IP_XFRM_POLICY", Const, 0}, + {"IPv6MTUInfo", Type, 2}, + {"IPv6MTUInfo.Addr", Field, 2}, + {"IPv6MTUInfo.Mtu", Field, 2}, + {"IPv6Mreq", Type, 0}, + {"IPv6Mreq.Interface", Field, 0}, + {"IPv6Mreq.Multiaddr", Field, 0}, + {"ISIG", Const, 0}, + {"ISTRIP", Const, 0}, + {"IUCLC", Const, 0}, + {"IUTF8", Const, 0}, + {"IXANY", Const, 0}, + {"IXOFF", Const, 0}, + {"IXON", Const, 0}, + {"IfAddrmsg", Type, 0}, + {"IfAddrmsg.Family", Field, 0}, + {"IfAddrmsg.Flags", Field, 0}, + {"IfAddrmsg.Index", Field, 0}, + {"IfAddrmsg.Prefixlen", Field, 0}, + {"IfAddrmsg.Scope", Field, 0}, + {"IfAnnounceMsghdr", Type, 1}, + {"IfAnnounceMsghdr.Hdrlen", Field, 2}, + {"IfAnnounceMsghdr.Index", Field, 1}, + {"IfAnnounceMsghdr.Msglen", Field, 1}, + {"IfAnnounceMsghdr.Name", Field, 1}, + {"IfAnnounceMsghdr.Type", Field, 1}, + {"IfAnnounceMsghdr.Version", Field, 1}, + {"IfAnnounceMsghdr.What", Field, 1}, + {"IfData", Type, 0}, + {"IfData.Addrlen", Field, 0}, + {"IfData.Baudrate", Field, 0}, + {"IfData.Capabilities", Field, 2}, + {"IfData.Collisions", Field, 0}, + {"IfData.Datalen", Field, 0}, + {"IfData.Epoch", Field, 0}, + {"IfData.Hdrlen", Field, 0}, + {"IfData.Hwassist", Field, 0}, + {"IfData.Ibytes", Field, 0}, + {"IfData.Ierrors", Field, 0}, + {"IfData.Imcasts", Field, 0}, + {"IfData.Ipackets", Field, 0}, + {"IfData.Iqdrops", Field, 0}, + {"IfData.Lastchange", Field, 0}, + {"IfData.Link_state", Field, 0}, + {"IfData.Mclpool", Field, 2}, + {"IfData.Metric", Field, 0}, + {"IfData.Mtu", Field, 0}, + {"IfData.Noproto", Field, 0}, + {"IfData.Obytes", Field, 0}, + {"IfData.Oerrors", Field, 0}, + {"IfData.Omcasts", Field, 0}, + {"IfData.Opackets", Field, 0}, + {"IfData.Pad", Field, 2}, + {"IfData.Pad_cgo_0", Field, 2}, + {"IfData.Pad_cgo_1", Field, 2}, + {"IfData.Physical", Field, 0}, + {"IfData.Recvquota", Field, 0}, + {"IfData.Recvtiming", Field, 0}, + {"IfData.Reserved1", Field, 0}, + {"IfData.Reserved2", Field, 0}, + {"IfData.Spare_char1", Field, 0}, + {"IfData.Spare_char2", Field, 0}, + {"IfData.Type", Field, 0}, + {"IfData.Typelen", Field, 0}, + {"IfData.Unused1", Field, 0}, + {"IfData.Unused2", Field, 0}, + {"IfData.Xmitquota", Field, 0}, + {"IfData.Xmittiming", Field, 0}, + {"IfInfomsg", Type, 0}, + {"IfInfomsg.Change", Field, 0}, + {"IfInfomsg.Family", Field, 0}, + {"IfInfomsg.Flags", Field, 0}, + {"IfInfomsg.Index", Field, 0}, + {"IfInfomsg.Type", Field, 0}, + {"IfInfomsg.X__ifi_pad", Field, 0}, + {"IfMsghdr", Type, 0}, + {"IfMsghdr.Addrs", Field, 0}, + {"IfMsghdr.Data", Field, 0}, + {"IfMsghdr.Flags", Field, 0}, + {"IfMsghdr.Hdrlen", Field, 2}, + {"IfMsghdr.Index", Field, 0}, + {"IfMsghdr.Msglen", Field, 0}, + {"IfMsghdr.Pad1", Field, 2}, + {"IfMsghdr.Pad2", Field, 2}, + {"IfMsghdr.Pad_cgo_0", Field, 0}, + {"IfMsghdr.Pad_cgo_1", Field, 2}, + {"IfMsghdr.Tableid", Field, 2}, + {"IfMsghdr.Type", Field, 0}, + {"IfMsghdr.Version", Field, 0}, + {"IfMsghdr.Xflags", Field, 2}, + {"IfaMsghdr", Type, 0}, + {"IfaMsghdr.Addrs", Field, 0}, + {"IfaMsghdr.Flags", Field, 0}, + {"IfaMsghdr.Hdrlen", Field, 2}, + {"IfaMsghdr.Index", Field, 0}, + {"IfaMsghdr.Metric", Field, 0}, + {"IfaMsghdr.Msglen", Field, 0}, + {"IfaMsghdr.Pad1", Field, 2}, + {"IfaMsghdr.Pad2", Field, 2}, + {"IfaMsghdr.Pad_cgo_0", Field, 0}, + {"IfaMsghdr.Tableid", Field, 2}, + {"IfaMsghdr.Type", Field, 0}, + {"IfaMsghdr.Version", Field, 0}, + {"IfmaMsghdr", Type, 0}, + {"IfmaMsghdr.Addrs", Field, 0}, + {"IfmaMsghdr.Flags", Field, 0}, + {"IfmaMsghdr.Index", Field, 0}, + {"IfmaMsghdr.Msglen", Field, 0}, + {"IfmaMsghdr.Pad_cgo_0", Field, 0}, + {"IfmaMsghdr.Type", Field, 0}, + {"IfmaMsghdr.Version", Field, 0}, + {"IfmaMsghdr2", Type, 0}, + {"IfmaMsghdr2.Addrs", Field, 0}, + {"IfmaMsghdr2.Flags", Field, 0}, + {"IfmaMsghdr2.Index", Field, 0}, + {"IfmaMsghdr2.Msglen", Field, 0}, + {"IfmaMsghdr2.Pad_cgo_0", Field, 0}, + {"IfmaMsghdr2.Refcount", Field, 0}, + {"IfmaMsghdr2.Type", Field, 0}, + {"IfmaMsghdr2.Version", Field, 0}, + {"ImplementsGetwd", Const, 0}, + {"Inet4Pktinfo", Type, 0}, + {"Inet4Pktinfo.Addr", Field, 0}, + {"Inet4Pktinfo.Ifindex", Field, 0}, + {"Inet4Pktinfo.Spec_dst", Field, 0}, + {"Inet6Pktinfo", Type, 0}, + {"Inet6Pktinfo.Addr", Field, 0}, + {"Inet6Pktinfo.Ifindex", Field, 0}, + {"InotifyAddWatch", Func, 0}, + {"InotifyEvent", Type, 0}, + {"InotifyEvent.Cookie", Field, 0}, + {"InotifyEvent.Len", Field, 0}, + {"InotifyEvent.Mask", Field, 0}, + {"InotifyEvent.Name", Field, 0}, + {"InotifyEvent.Wd", Field, 0}, + {"InotifyInit", Func, 0}, + {"InotifyInit1", Func, 0}, + {"InotifyRmWatch", Func, 0}, + {"InterfaceAddrMessage", Type, 0}, + {"InterfaceAddrMessage.Data", Field, 0}, + {"InterfaceAddrMessage.Header", Field, 0}, + {"InterfaceAnnounceMessage", Type, 1}, + {"InterfaceAnnounceMessage.Header", Field, 1}, + {"InterfaceInfo", Type, 0}, + {"InterfaceInfo.Address", Field, 0}, + {"InterfaceInfo.BroadcastAddress", Field, 0}, + {"InterfaceInfo.Flags", Field, 0}, + {"InterfaceInfo.Netmask", Field, 0}, + {"InterfaceMessage", Type, 0}, + {"InterfaceMessage.Data", Field, 0}, + {"InterfaceMessage.Header", Field, 0}, + {"InterfaceMulticastAddrMessage", Type, 0}, + {"InterfaceMulticastAddrMessage.Data", Field, 0}, + {"InterfaceMulticastAddrMessage.Header", Field, 0}, + {"InvalidHandle", Const, 0}, + {"Ioperm", Func, 0}, + {"Iopl", Func, 0}, + {"Iovec", Type, 0}, + {"Iovec.Base", Field, 0}, + {"Iovec.Len", Field, 0}, + {"IpAdapterInfo", Type, 0}, + {"IpAdapterInfo.AdapterName", Field, 0}, + {"IpAdapterInfo.Address", Field, 0}, + {"IpAdapterInfo.AddressLength", Field, 0}, + {"IpAdapterInfo.ComboIndex", Field, 0}, + {"IpAdapterInfo.CurrentIpAddress", Field, 0}, + {"IpAdapterInfo.Description", Field, 0}, + {"IpAdapterInfo.DhcpEnabled", Field, 0}, + {"IpAdapterInfo.DhcpServer", Field, 0}, + {"IpAdapterInfo.GatewayList", Field, 0}, + {"IpAdapterInfo.HaveWins", Field, 0}, + {"IpAdapterInfo.Index", Field, 0}, + {"IpAdapterInfo.IpAddressList", Field, 0}, + {"IpAdapterInfo.LeaseExpires", Field, 0}, + {"IpAdapterInfo.LeaseObtained", Field, 0}, + {"IpAdapterInfo.Next", Field, 0}, + {"IpAdapterInfo.PrimaryWinsServer", Field, 0}, + {"IpAdapterInfo.SecondaryWinsServer", Field, 0}, + {"IpAdapterInfo.Type", Field, 0}, + {"IpAddrString", Type, 0}, + {"IpAddrString.Context", Field, 0}, + {"IpAddrString.IpAddress", Field, 0}, + {"IpAddrString.IpMask", Field, 0}, + {"IpAddrString.Next", Field, 0}, + {"IpAddressString", Type, 0}, + {"IpAddressString.String", Field, 0}, + {"IpMaskString", Type, 0}, + {"IpMaskString.String", Field, 2}, + {"Issetugid", Func, 0}, + {"KEY_ALL_ACCESS", Const, 0}, + {"KEY_CREATE_LINK", Const, 0}, + {"KEY_CREATE_SUB_KEY", Const, 0}, + {"KEY_ENUMERATE_SUB_KEYS", Const, 0}, + {"KEY_EXECUTE", Const, 0}, + {"KEY_NOTIFY", Const, 0}, + {"KEY_QUERY_VALUE", Const, 0}, + {"KEY_READ", Const, 0}, + {"KEY_SET_VALUE", Const, 0}, + {"KEY_WOW64_32KEY", Const, 0}, + {"KEY_WOW64_64KEY", Const, 0}, + {"KEY_WRITE", Const, 0}, + {"Kevent", Func, 0}, + {"Kevent_t", Type, 0}, + {"Kevent_t.Data", Field, 0}, + {"Kevent_t.Fflags", Field, 0}, + {"Kevent_t.Filter", Field, 0}, + {"Kevent_t.Flags", Field, 0}, + {"Kevent_t.Ident", Field, 0}, + {"Kevent_t.Pad_cgo_0", Field, 2}, + {"Kevent_t.Udata", Field, 0}, + {"Kill", Func, 0}, + {"Klogctl", Func, 0}, + {"Kqueue", Func, 0}, + {"LANG_ENGLISH", Const, 0}, + {"LAYERED_PROTOCOL", Const, 2}, + {"LCNT_OVERLOAD_FLUSH", Const, 1}, + {"LINUX_REBOOT_CMD_CAD_OFF", Const, 0}, + {"LINUX_REBOOT_CMD_CAD_ON", Const, 0}, + {"LINUX_REBOOT_CMD_HALT", Const, 0}, + {"LINUX_REBOOT_CMD_KEXEC", Const, 0}, + {"LINUX_REBOOT_CMD_POWER_OFF", Const, 0}, + {"LINUX_REBOOT_CMD_RESTART", Const, 0}, + {"LINUX_REBOOT_CMD_RESTART2", Const, 0}, + {"LINUX_REBOOT_CMD_SW_SUSPEND", Const, 0}, + {"LINUX_REBOOT_MAGIC1", Const, 0}, + {"LINUX_REBOOT_MAGIC2", Const, 0}, + {"LOCK_EX", Const, 0}, + {"LOCK_NB", Const, 0}, + {"LOCK_SH", Const, 0}, + {"LOCK_UN", Const, 0}, + {"LazyDLL", Type, 0}, + {"LazyDLL.Name", Field, 0}, + {"LazyProc", Type, 0}, + {"LazyProc.Name", Field, 0}, + {"Lchown", Func, 0}, + {"Linger", Type, 0}, + {"Linger.Linger", Field, 0}, + {"Linger.Onoff", Field, 0}, + {"Link", Func, 0}, + {"Listen", Func, 0}, + {"Listxattr", Func, 1}, + {"LoadCancelIoEx", Func, 1}, + {"LoadConnectEx", Func, 1}, + {"LoadCreateSymbolicLink", Func, 4}, + {"LoadDLL", Func, 0}, + {"LoadGetAddrInfo", Func, 1}, + {"LoadLibrary", Func, 0}, + {"LoadSetFileCompletionNotificationModes", Func, 2}, + {"LocalFree", Func, 0}, + {"Log2phys_t", Type, 0}, + {"Log2phys_t.Contigbytes", Field, 0}, + {"Log2phys_t.Devoffset", Field, 0}, + {"Log2phys_t.Flags", Field, 0}, + {"LookupAccountName", Func, 0}, + {"LookupAccountSid", Func, 0}, + {"LookupSID", Func, 0}, + {"LsfJump", Func, 0}, + {"LsfSocket", Func, 0}, + {"LsfStmt", Func, 0}, + {"Lstat", Func, 0}, + {"MADV_AUTOSYNC", Const, 1}, + {"MADV_CAN_REUSE", Const, 0}, + {"MADV_CORE", Const, 1}, + {"MADV_DOFORK", Const, 0}, + {"MADV_DONTFORK", Const, 0}, + {"MADV_DONTNEED", Const, 0}, + {"MADV_FREE", Const, 0}, + {"MADV_FREE_REUSABLE", Const, 0}, + {"MADV_FREE_REUSE", Const, 0}, + {"MADV_HUGEPAGE", Const, 0}, + {"MADV_HWPOISON", Const, 0}, + {"MADV_MERGEABLE", Const, 0}, + {"MADV_NOCORE", Const, 1}, + {"MADV_NOHUGEPAGE", Const, 0}, + {"MADV_NORMAL", Const, 0}, + {"MADV_NOSYNC", Const, 1}, + {"MADV_PROTECT", Const, 1}, + {"MADV_RANDOM", Const, 0}, + {"MADV_REMOVE", Const, 0}, + {"MADV_SEQUENTIAL", Const, 0}, + {"MADV_SPACEAVAIL", Const, 3}, + {"MADV_UNMERGEABLE", Const, 0}, + {"MADV_WILLNEED", Const, 0}, + {"MADV_ZERO_WIRED_PAGES", Const, 0}, + {"MAP_32BIT", Const, 0}, + {"MAP_ALIGNED_SUPER", Const, 3}, + {"MAP_ALIGNMENT_16MB", Const, 3}, + {"MAP_ALIGNMENT_1TB", Const, 3}, + {"MAP_ALIGNMENT_256TB", Const, 3}, + {"MAP_ALIGNMENT_4GB", Const, 3}, + {"MAP_ALIGNMENT_64KB", Const, 3}, + {"MAP_ALIGNMENT_64PB", Const, 3}, + {"MAP_ALIGNMENT_MASK", Const, 3}, + {"MAP_ALIGNMENT_SHIFT", Const, 3}, + {"MAP_ANON", Const, 0}, + {"MAP_ANONYMOUS", Const, 0}, + {"MAP_COPY", Const, 0}, + {"MAP_DENYWRITE", Const, 0}, + {"MAP_EXECUTABLE", Const, 0}, + {"MAP_FILE", Const, 0}, + {"MAP_FIXED", Const, 0}, + {"MAP_FLAGMASK", Const, 3}, + {"MAP_GROWSDOWN", Const, 0}, + {"MAP_HASSEMAPHORE", Const, 0}, + {"MAP_HUGETLB", Const, 0}, + {"MAP_INHERIT", Const, 3}, + {"MAP_INHERIT_COPY", Const, 3}, + {"MAP_INHERIT_DEFAULT", Const, 3}, + {"MAP_INHERIT_DONATE_COPY", Const, 3}, + {"MAP_INHERIT_NONE", Const, 3}, + {"MAP_INHERIT_SHARE", Const, 3}, + {"MAP_JIT", Const, 0}, + {"MAP_LOCKED", Const, 0}, + {"MAP_NOCACHE", Const, 0}, + {"MAP_NOCORE", Const, 1}, + {"MAP_NOEXTEND", Const, 0}, + {"MAP_NONBLOCK", Const, 0}, + {"MAP_NORESERVE", Const, 0}, + {"MAP_NOSYNC", Const, 1}, + {"MAP_POPULATE", Const, 0}, + {"MAP_PREFAULT_READ", Const, 1}, + {"MAP_PRIVATE", Const, 0}, + {"MAP_RENAME", Const, 0}, + {"MAP_RESERVED0080", Const, 0}, + {"MAP_RESERVED0100", Const, 1}, + {"MAP_SHARED", Const, 0}, + {"MAP_STACK", Const, 0}, + {"MAP_TRYFIXED", Const, 3}, + {"MAP_TYPE", Const, 0}, + {"MAP_WIRED", Const, 3}, + {"MAXIMUM_REPARSE_DATA_BUFFER_SIZE", Const, 4}, + {"MAXLEN_IFDESCR", Const, 0}, + {"MAXLEN_PHYSADDR", Const, 0}, + {"MAX_ADAPTER_ADDRESS_LENGTH", Const, 0}, + {"MAX_ADAPTER_DESCRIPTION_LENGTH", Const, 0}, + {"MAX_ADAPTER_NAME_LENGTH", Const, 0}, + {"MAX_COMPUTERNAME_LENGTH", Const, 0}, + {"MAX_INTERFACE_NAME_LEN", Const, 0}, + {"MAX_LONG_PATH", Const, 0}, + {"MAX_PATH", Const, 0}, + {"MAX_PROTOCOL_CHAIN", Const, 2}, + {"MCL_CURRENT", Const, 0}, + {"MCL_FUTURE", Const, 0}, + {"MNT_DETACH", Const, 0}, + {"MNT_EXPIRE", Const, 0}, + {"MNT_FORCE", Const, 0}, + {"MSG_BCAST", Const, 1}, + {"MSG_CMSG_CLOEXEC", Const, 0}, + {"MSG_COMPAT", Const, 0}, + {"MSG_CONFIRM", Const, 0}, + {"MSG_CONTROLMBUF", Const, 1}, + {"MSG_CTRUNC", Const, 0}, + {"MSG_DONTROUTE", Const, 0}, + {"MSG_DONTWAIT", Const, 0}, + {"MSG_EOF", Const, 0}, + {"MSG_EOR", Const, 0}, + {"MSG_ERRQUEUE", Const, 0}, + {"MSG_FASTOPEN", Const, 1}, + {"MSG_FIN", Const, 0}, + {"MSG_FLUSH", Const, 0}, + {"MSG_HAVEMORE", Const, 0}, + {"MSG_HOLD", Const, 0}, + {"MSG_IOVUSRSPACE", Const, 1}, + {"MSG_LENUSRSPACE", Const, 1}, + {"MSG_MCAST", Const, 1}, + {"MSG_MORE", Const, 0}, + {"MSG_NAMEMBUF", Const, 1}, + {"MSG_NBIO", Const, 0}, + {"MSG_NEEDSA", Const, 0}, + {"MSG_NOSIGNAL", Const, 0}, + {"MSG_NOTIFICATION", Const, 0}, + {"MSG_OOB", Const, 0}, + {"MSG_PEEK", Const, 0}, + {"MSG_PROXY", Const, 0}, + {"MSG_RCVMORE", Const, 0}, + {"MSG_RST", Const, 0}, + {"MSG_SEND", Const, 0}, + {"MSG_SYN", Const, 0}, + {"MSG_TRUNC", Const, 0}, + {"MSG_TRYHARD", Const, 0}, + {"MSG_USERFLAGS", Const, 1}, + {"MSG_WAITALL", Const, 0}, + {"MSG_WAITFORONE", Const, 0}, + {"MSG_WAITSTREAM", Const, 0}, + {"MS_ACTIVE", Const, 0}, + {"MS_ASYNC", Const, 0}, + {"MS_BIND", Const, 0}, + {"MS_DEACTIVATE", Const, 0}, + {"MS_DIRSYNC", Const, 0}, + {"MS_INVALIDATE", Const, 0}, + {"MS_I_VERSION", Const, 0}, + {"MS_KERNMOUNT", Const, 0}, + {"MS_KILLPAGES", Const, 0}, + {"MS_MANDLOCK", Const, 0}, + {"MS_MGC_MSK", Const, 0}, + {"MS_MGC_VAL", Const, 0}, + {"MS_MOVE", Const, 0}, + {"MS_NOATIME", Const, 0}, + {"MS_NODEV", Const, 0}, + {"MS_NODIRATIME", Const, 0}, + {"MS_NOEXEC", Const, 0}, + {"MS_NOSUID", Const, 0}, + {"MS_NOUSER", Const, 0}, + {"MS_POSIXACL", Const, 0}, + {"MS_PRIVATE", Const, 0}, + {"MS_RDONLY", Const, 0}, + {"MS_REC", Const, 0}, + {"MS_RELATIME", Const, 0}, + {"MS_REMOUNT", Const, 0}, + {"MS_RMT_MASK", Const, 0}, + {"MS_SHARED", Const, 0}, + {"MS_SILENT", Const, 0}, + {"MS_SLAVE", Const, 0}, + {"MS_STRICTATIME", Const, 0}, + {"MS_SYNC", Const, 0}, + {"MS_SYNCHRONOUS", Const, 0}, + {"MS_UNBINDABLE", Const, 0}, + {"Madvise", Func, 0}, + {"MapViewOfFile", Func, 0}, + {"MaxTokenInfoClass", Const, 0}, + {"Mclpool", Type, 2}, + {"Mclpool.Alive", Field, 2}, + {"Mclpool.Cwm", Field, 2}, + {"Mclpool.Grown", Field, 2}, + {"Mclpool.Hwm", Field, 2}, + {"Mclpool.Lwm", Field, 2}, + {"MibIfRow", Type, 0}, + {"MibIfRow.AdminStatus", Field, 0}, + {"MibIfRow.Descr", Field, 0}, + {"MibIfRow.DescrLen", Field, 0}, + {"MibIfRow.InDiscards", Field, 0}, + {"MibIfRow.InErrors", Field, 0}, + {"MibIfRow.InNUcastPkts", Field, 0}, + {"MibIfRow.InOctets", Field, 0}, + {"MibIfRow.InUcastPkts", Field, 0}, + {"MibIfRow.InUnknownProtos", Field, 0}, + {"MibIfRow.Index", Field, 0}, + {"MibIfRow.LastChange", Field, 0}, + {"MibIfRow.Mtu", Field, 0}, + {"MibIfRow.Name", Field, 0}, + {"MibIfRow.OperStatus", Field, 0}, + {"MibIfRow.OutDiscards", Field, 0}, + {"MibIfRow.OutErrors", Field, 0}, + {"MibIfRow.OutNUcastPkts", Field, 0}, + {"MibIfRow.OutOctets", Field, 0}, + {"MibIfRow.OutQLen", Field, 0}, + {"MibIfRow.OutUcastPkts", Field, 0}, + {"MibIfRow.PhysAddr", Field, 0}, + {"MibIfRow.PhysAddrLen", Field, 0}, + {"MibIfRow.Speed", Field, 0}, + {"MibIfRow.Type", Field, 0}, + {"Mkdir", Func, 0}, + {"Mkdirat", Func, 0}, + {"Mkfifo", Func, 0}, + {"Mknod", Func, 0}, + {"Mknodat", Func, 0}, + {"Mlock", Func, 0}, + {"Mlockall", Func, 0}, + {"Mmap", Func, 0}, + {"Mount", Func, 0}, + {"MoveFile", Func, 0}, + {"Mprotect", Func, 0}, + {"Msghdr", Type, 0}, + {"Msghdr.Control", Field, 0}, + {"Msghdr.Controllen", Field, 0}, + {"Msghdr.Flags", Field, 0}, + {"Msghdr.Iov", Field, 0}, + {"Msghdr.Iovlen", Field, 0}, + {"Msghdr.Name", Field, 0}, + {"Msghdr.Namelen", Field, 0}, + {"Msghdr.Pad_cgo_0", Field, 0}, + {"Msghdr.Pad_cgo_1", Field, 0}, + {"Munlock", Func, 0}, + {"Munlockall", Func, 0}, + {"Munmap", Func, 0}, + {"MustLoadDLL", Func, 0}, + {"NAME_MAX", Const, 0}, + {"NETLINK_ADD_MEMBERSHIP", Const, 0}, + {"NETLINK_AUDIT", Const, 0}, + {"NETLINK_BROADCAST_ERROR", Const, 0}, + {"NETLINK_CONNECTOR", Const, 0}, + {"NETLINK_DNRTMSG", Const, 0}, + {"NETLINK_DROP_MEMBERSHIP", Const, 0}, + {"NETLINK_ECRYPTFS", Const, 0}, + {"NETLINK_FIB_LOOKUP", Const, 0}, + {"NETLINK_FIREWALL", Const, 0}, + {"NETLINK_GENERIC", Const, 0}, + {"NETLINK_INET_DIAG", Const, 0}, + {"NETLINK_IP6_FW", Const, 0}, + {"NETLINK_ISCSI", Const, 0}, + {"NETLINK_KOBJECT_UEVENT", Const, 0}, + {"NETLINK_NETFILTER", Const, 0}, + {"NETLINK_NFLOG", Const, 0}, + {"NETLINK_NO_ENOBUFS", Const, 0}, + {"NETLINK_PKTINFO", Const, 0}, + {"NETLINK_RDMA", Const, 0}, + {"NETLINK_ROUTE", Const, 0}, + {"NETLINK_SCSITRANSPORT", Const, 0}, + {"NETLINK_SELINUX", Const, 0}, + {"NETLINK_UNUSED", Const, 0}, + {"NETLINK_USERSOCK", Const, 0}, + {"NETLINK_XFRM", Const, 0}, + {"NET_RT_DUMP", Const, 0}, + {"NET_RT_DUMP2", Const, 0}, + {"NET_RT_FLAGS", Const, 0}, + {"NET_RT_IFLIST", Const, 0}, + {"NET_RT_IFLIST2", Const, 0}, + {"NET_RT_IFLISTL", Const, 1}, + {"NET_RT_IFMALIST", Const, 0}, + {"NET_RT_MAXID", Const, 0}, + {"NET_RT_OIFLIST", Const, 1}, + {"NET_RT_OOIFLIST", Const, 1}, + {"NET_RT_STAT", Const, 0}, + {"NET_RT_STATS", Const, 1}, + {"NET_RT_TABLE", Const, 1}, + {"NET_RT_TRASH", Const, 0}, + {"NLA_ALIGNTO", Const, 0}, + {"NLA_F_NESTED", Const, 0}, + {"NLA_F_NET_BYTEORDER", Const, 0}, + {"NLA_HDRLEN", Const, 0}, + {"NLMSG_ALIGNTO", Const, 0}, + {"NLMSG_DONE", Const, 0}, + {"NLMSG_ERROR", Const, 0}, + {"NLMSG_HDRLEN", Const, 0}, + {"NLMSG_MIN_TYPE", Const, 0}, + {"NLMSG_NOOP", Const, 0}, + {"NLMSG_OVERRUN", Const, 0}, + {"NLM_F_ACK", Const, 0}, + {"NLM_F_APPEND", Const, 0}, + {"NLM_F_ATOMIC", Const, 0}, + {"NLM_F_CREATE", Const, 0}, + {"NLM_F_DUMP", Const, 0}, + {"NLM_F_ECHO", Const, 0}, + {"NLM_F_EXCL", Const, 0}, + {"NLM_F_MATCH", Const, 0}, + {"NLM_F_MULTI", Const, 0}, + {"NLM_F_REPLACE", Const, 0}, + {"NLM_F_REQUEST", Const, 0}, + {"NLM_F_ROOT", Const, 0}, + {"NOFLSH", Const, 0}, + {"NOTE_ABSOLUTE", Const, 0}, + {"NOTE_ATTRIB", Const, 0}, + {"NOTE_BACKGROUND", Const, 16}, + {"NOTE_CHILD", Const, 0}, + {"NOTE_CRITICAL", Const, 16}, + {"NOTE_DELETE", Const, 0}, + {"NOTE_EOF", Const, 1}, + {"NOTE_EXEC", Const, 0}, + {"NOTE_EXIT", Const, 0}, + {"NOTE_EXITSTATUS", Const, 0}, + {"NOTE_EXIT_CSERROR", Const, 16}, + {"NOTE_EXIT_DECRYPTFAIL", Const, 16}, + {"NOTE_EXIT_DETAIL", Const, 16}, + {"NOTE_EXIT_DETAIL_MASK", Const, 16}, + {"NOTE_EXIT_MEMORY", Const, 16}, + {"NOTE_EXIT_REPARENTED", Const, 16}, + {"NOTE_EXTEND", Const, 0}, + {"NOTE_FFAND", Const, 0}, + {"NOTE_FFCOPY", Const, 0}, + {"NOTE_FFCTRLMASK", Const, 0}, + {"NOTE_FFLAGSMASK", Const, 0}, + {"NOTE_FFNOP", Const, 0}, + {"NOTE_FFOR", Const, 0}, + {"NOTE_FORK", Const, 0}, + {"NOTE_LEEWAY", Const, 16}, + {"NOTE_LINK", Const, 0}, + {"NOTE_LOWAT", Const, 0}, + {"NOTE_NONE", Const, 0}, + {"NOTE_NSECONDS", Const, 0}, + {"NOTE_PCTRLMASK", Const, 0}, + {"NOTE_PDATAMASK", Const, 0}, + {"NOTE_REAP", Const, 0}, + {"NOTE_RENAME", Const, 0}, + {"NOTE_RESOURCEEND", Const, 0}, + {"NOTE_REVOKE", Const, 0}, + {"NOTE_SECONDS", Const, 0}, + {"NOTE_SIGNAL", Const, 0}, + {"NOTE_TRACK", Const, 0}, + {"NOTE_TRACKERR", Const, 0}, + {"NOTE_TRIGGER", Const, 0}, + {"NOTE_TRUNCATE", Const, 1}, + {"NOTE_USECONDS", Const, 0}, + {"NOTE_VM_ERROR", Const, 0}, + {"NOTE_VM_PRESSURE", Const, 0}, + {"NOTE_VM_PRESSURE_SUDDEN_TERMINATE", Const, 0}, + {"NOTE_VM_PRESSURE_TERMINATE", Const, 0}, + {"NOTE_WRITE", Const, 0}, + {"NameCanonical", Const, 0}, + {"NameCanonicalEx", Const, 0}, + {"NameDisplay", Const, 0}, + {"NameDnsDomain", Const, 0}, + {"NameFullyQualifiedDN", Const, 0}, + {"NameSamCompatible", Const, 0}, + {"NameServicePrincipal", Const, 0}, + {"NameUniqueId", Const, 0}, + {"NameUnknown", Const, 0}, + {"NameUserPrincipal", Const, 0}, + {"Nanosleep", Func, 0}, + {"NetApiBufferFree", Func, 0}, + {"NetGetJoinInformation", Func, 2}, + {"NetSetupDomainName", Const, 2}, + {"NetSetupUnjoined", Const, 2}, + {"NetSetupUnknownStatus", Const, 2}, + {"NetSetupWorkgroupName", Const, 2}, + {"NetUserGetInfo", Func, 0}, + {"NetlinkMessage", Type, 0}, + {"NetlinkMessage.Data", Field, 0}, + {"NetlinkMessage.Header", Field, 0}, + {"NetlinkRIB", Func, 0}, + {"NetlinkRouteAttr", Type, 0}, + {"NetlinkRouteAttr.Attr", Field, 0}, + {"NetlinkRouteAttr.Value", Field, 0}, + {"NetlinkRouteRequest", Type, 0}, + {"NetlinkRouteRequest.Data", Field, 0}, + {"NetlinkRouteRequest.Header", Field, 0}, + {"NewCallback", Func, 0}, + {"NewCallbackCDecl", Func, 3}, + {"NewLazyDLL", Func, 0}, + {"NlAttr", Type, 0}, + {"NlAttr.Len", Field, 0}, + {"NlAttr.Type", Field, 0}, + {"NlMsgerr", Type, 0}, + {"NlMsgerr.Error", Field, 0}, + {"NlMsgerr.Msg", Field, 0}, + {"NlMsghdr", Type, 0}, + {"NlMsghdr.Flags", Field, 0}, + {"NlMsghdr.Len", Field, 0}, + {"NlMsghdr.Pid", Field, 0}, + {"NlMsghdr.Seq", Field, 0}, + {"NlMsghdr.Type", Field, 0}, + {"NsecToFiletime", Func, 0}, + {"NsecToTimespec", Func, 0}, + {"NsecToTimeval", Func, 0}, + {"Ntohs", Func, 0}, + {"OCRNL", Const, 0}, + {"OFDEL", Const, 0}, + {"OFILL", Const, 0}, + {"OFIOGETBMAP", Const, 1}, + {"OID_PKIX_KP_SERVER_AUTH", Var, 0}, + {"OID_SERVER_GATED_CRYPTO", Var, 0}, + {"OID_SGC_NETSCAPE", Var, 0}, + {"OLCUC", Const, 0}, + {"ONLCR", Const, 0}, + {"ONLRET", Const, 0}, + {"ONOCR", Const, 0}, + {"ONOEOT", Const, 1}, + {"OPEN_ALWAYS", Const, 0}, + {"OPEN_EXISTING", Const, 0}, + {"OPOST", Const, 0}, + {"O_ACCMODE", Const, 0}, + {"O_ALERT", Const, 0}, + {"O_ALT_IO", Const, 1}, + {"O_APPEND", Const, 0}, + {"O_ASYNC", Const, 0}, + {"O_CLOEXEC", Const, 0}, + {"O_CREAT", Const, 0}, + {"O_DIRECT", Const, 0}, + {"O_DIRECTORY", Const, 0}, + {"O_DP_GETRAWENCRYPTED", Const, 16}, + {"O_DSYNC", Const, 0}, + {"O_EVTONLY", Const, 0}, + {"O_EXCL", Const, 0}, + {"O_EXEC", Const, 0}, + {"O_EXLOCK", Const, 0}, + {"O_FSYNC", Const, 0}, + {"O_LARGEFILE", Const, 0}, + {"O_NDELAY", Const, 0}, + {"O_NOATIME", Const, 0}, + {"O_NOCTTY", Const, 0}, + {"O_NOFOLLOW", Const, 0}, + {"O_NONBLOCK", Const, 0}, + {"O_NOSIGPIPE", Const, 1}, + {"O_POPUP", Const, 0}, + {"O_RDONLY", Const, 0}, + {"O_RDWR", Const, 0}, + {"O_RSYNC", Const, 0}, + {"O_SHLOCK", Const, 0}, + {"O_SYMLINK", Const, 0}, + {"O_SYNC", Const, 0}, + {"O_TRUNC", Const, 0}, + {"O_TTY_INIT", Const, 0}, + {"O_WRONLY", Const, 0}, + {"Open", Func, 0}, + {"OpenCurrentProcessToken", Func, 0}, + {"OpenProcess", Func, 0}, + {"OpenProcessToken", Func, 0}, + {"Openat", Func, 0}, + {"Overlapped", Type, 0}, + {"Overlapped.HEvent", Field, 0}, + {"Overlapped.Internal", Field, 0}, + {"Overlapped.InternalHigh", Field, 0}, + {"Overlapped.Offset", Field, 0}, + {"Overlapped.OffsetHigh", Field, 0}, + {"PACKET_ADD_MEMBERSHIP", Const, 0}, + {"PACKET_BROADCAST", Const, 0}, + {"PACKET_DROP_MEMBERSHIP", Const, 0}, + {"PACKET_FASTROUTE", Const, 0}, + {"PACKET_HOST", Const, 0}, + {"PACKET_LOOPBACK", Const, 0}, + {"PACKET_MR_ALLMULTI", Const, 0}, + {"PACKET_MR_MULTICAST", Const, 0}, + {"PACKET_MR_PROMISC", Const, 0}, + {"PACKET_MULTICAST", Const, 0}, + {"PACKET_OTHERHOST", Const, 0}, + {"PACKET_OUTGOING", Const, 0}, + {"PACKET_RECV_OUTPUT", Const, 0}, + {"PACKET_RX_RING", Const, 0}, + {"PACKET_STATISTICS", Const, 0}, + {"PAGE_EXECUTE_READ", Const, 0}, + {"PAGE_EXECUTE_READWRITE", Const, 0}, + {"PAGE_EXECUTE_WRITECOPY", Const, 0}, + {"PAGE_READONLY", Const, 0}, + {"PAGE_READWRITE", Const, 0}, + {"PAGE_WRITECOPY", Const, 0}, + {"PARENB", Const, 0}, + {"PARMRK", Const, 0}, + {"PARODD", Const, 0}, + {"PENDIN", Const, 0}, + {"PFL_HIDDEN", Const, 2}, + {"PFL_MATCHES_PROTOCOL_ZERO", Const, 2}, + {"PFL_MULTIPLE_PROTO_ENTRIES", Const, 2}, + {"PFL_NETWORKDIRECT_PROVIDER", Const, 2}, + {"PFL_RECOMMENDED_PROTO_ENTRY", Const, 2}, + {"PF_FLUSH", Const, 1}, + {"PKCS_7_ASN_ENCODING", Const, 0}, + {"PMC5_PIPELINE_FLUSH", Const, 1}, + {"PRIO_PGRP", Const, 2}, + {"PRIO_PROCESS", Const, 2}, + {"PRIO_USER", Const, 2}, + {"PRI_IOFLUSH", Const, 1}, + {"PROCESS_QUERY_INFORMATION", Const, 0}, + {"PROCESS_TERMINATE", Const, 2}, + {"PROT_EXEC", Const, 0}, + {"PROT_GROWSDOWN", Const, 0}, + {"PROT_GROWSUP", Const, 0}, + {"PROT_NONE", Const, 0}, + {"PROT_READ", Const, 0}, + {"PROT_WRITE", Const, 0}, + {"PROV_DH_SCHANNEL", Const, 0}, + {"PROV_DSS", Const, 0}, + {"PROV_DSS_DH", Const, 0}, + {"PROV_EC_ECDSA_FULL", Const, 0}, + {"PROV_EC_ECDSA_SIG", Const, 0}, + {"PROV_EC_ECNRA_FULL", Const, 0}, + {"PROV_EC_ECNRA_SIG", Const, 0}, + {"PROV_FORTEZZA", Const, 0}, + {"PROV_INTEL_SEC", Const, 0}, + {"PROV_MS_EXCHANGE", Const, 0}, + {"PROV_REPLACE_OWF", Const, 0}, + {"PROV_RNG", Const, 0}, + {"PROV_RSA_AES", Const, 0}, + {"PROV_RSA_FULL", Const, 0}, + {"PROV_RSA_SCHANNEL", Const, 0}, + {"PROV_RSA_SIG", Const, 0}, + {"PROV_SPYRUS_LYNKS", Const, 0}, + {"PROV_SSL", Const, 0}, + {"PR_CAPBSET_DROP", Const, 0}, + {"PR_CAPBSET_READ", Const, 0}, + {"PR_CLEAR_SECCOMP_FILTER", Const, 0}, + {"PR_ENDIAN_BIG", Const, 0}, + {"PR_ENDIAN_LITTLE", Const, 0}, + {"PR_ENDIAN_PPC_LITTLE", Const, 0}, + {"PR_FPEMU_NOPRINT", Const, 0}, + {"PR_FPEMU_SIGFPE", Const, 0}, + {"PR_FP_EXC_ASYNC", Const, 0}, + {"PR_FP_EXC_DISABLED", Const, 0}, + {"PR_FP_EXC_DIV", Const, 0}, + {"PR_FP_EXC_INV", Const, 0}, + {"PR_FP_EXC_NONRECOV", Const, 0}, + {"PR_FP_EXC_OVF", Const, 0}, + {"PR_FP_EXC_PRECISE", Const, 0}, + {"PR_FP_EXC_RES", Const, 0}, + {"PR_FP_EXC_SW_ENABLE", Const, 0}, + {"PR_FP_EXC_UND", Const, 0}, + {"PR_GET_DUMPABLE", Const, 0}, + {"PR_GET_ENDIAN", Const, 0}, + {"PR_GET_FPEMU", Const, 0}, + {"PR_GET_FPEXC", Const, 0}, + {"PR_GET_KEEPCAPS", Const, 0}, + {"PR_GET_NAME", Const, 0}, + {"PR_GET_PDEATHSIG", Const, 0}, + {"PR_GET_SECCOMP", Const, 0}, + {"PR_GET_SECCOMP_FILTER", Const, 0}, + {"PR_GET_SECUREBITS", Const, 0}, + {"PR_GET_TIMERSLACK", Const, 0}, + {"PR_GET_TIMING", Const, 0}, + {"PR_GET_TSC", Const, 0}, + {"PR_GET_UNALIGN", Const, 0}, + {"PR_MCE_KILL", Const, 0}, + {"PR_MCE_KILL_CLEAR", Const, 0}, + {"PR_MCE_KILL_DEFAULT", Const, 0}, + {"PR_MCE_KILL_EARLY", Const, 0}, + {"PR_MCE_KILL_GET", Const, 0}, + {"PR_MCE_KILL_LATE", Const, 0}, + {"PR_MCE_KILL_SET", Const, 0}, + {"PR_SECCOMP_FILTER_EVENT", Const, 0}, + {"PR_SECCOMP_FILTER_SYSCALL", Const, 0}, + {"PR_SET_DUMPABLE", Const, 0}, + {"PR_SET_ENDIAN", Const, 0}, + {"PR_SET_FPEMU", Const, 0}, + {"PR_SET_FPEXC", Const, 0}, + {"PR_SET_KEEPCAPS", Const, 0}, + {"PR_SET_NAME", Const, 0}, + {"PR_SET_PDEATHSIG", Const, 0}, + {"PR_SET_PTRACER", Const, 0}, + {"PR_SET_SECCOMP", Const, 0}, + {"PR_SET_SECCOMP_FILTER", Const, 0}, + {"PR_SET_SECUREBITS", Const, 0}, + {"PR_SET_TIMERSLACK", Const, 0}, + {"PR_SET_TIMING", Const, 0}, + {"PR_SET_TSC", Const, 0}, + {"PR_SET_UNALIGN", Const, 0}, + {"PR_TASK_PERF_EVENTS_DISABLE", Const, 0}, + {"PR_TASK_PERF_EVENTS_ENABLE", Const, 0}, + {"PR_TIMING_STATISTICAL", Const, 0}, + {"PR_TIMING_TIMESTAMP", Const, 0}, + {"PR_TSC_ENABLE", Const, 0}, + {"PR_TSC_SIGSEGV", Const, 0}, + {"PR_UNALIGN_NOPRINT", Const, 0}, + {"PR_UNALIGN_SIGBUS", Const, 0}, + {"PTRACE_ARCH_PRCTL", Const, 0}, + {"PTRACE_ATTACH", Const, 0}, + {"PTRACE_CONT", Const, 0}, + {"PTRACE_DETACH", Const, 0}, + {"PTRACE_EVENT_CLONE", Const, 0}, + {"PTRACE_EVENT_EXEC", Const, 0}, + {"PTRACE_EVENT_EXIT", Const, 0}, + {"PTRACE_EVENT_FORK", Const, 0}, + {"PTRACE_EVENT_VFORK", Const, 0}, + {"PTRACE_EVENT_VFORK_DONE", Const, 0}, + {"PTRACE_GETCRUNCHREGS", Const, 0}, + {"PTRACE_GETEVENTMSG", Const, 0}, + {"PTRACE_GETFPREGS", Const, 0}, + {"PTRACE_GETFPXREGS", Const, 0}, + {"PTRACE_GETHBPREGS", Const, 0}, + {"PTRACE_GETREGS", Const, 0}, + {"PTRACE_GETREGSET", Const, 0}, + {"PTRACE_GETSIGINFO", Const, 0}, + {"PTRACE_GETVFPREGS", Const, 0}, + {"PTRACE_GETWMMXREGS", Const, 0}, + {"PTRACE_GET_THREAD_AREA", Const, 0}, + {"PTRACE_KILL", Const, 0}, + {"PTRACE_OLDSETOPTIONS", Const, 0}, + {"PTRACE_O_MASK", Const, 0}, + {"PTRACE_O_TRACECLONE", Const, 0}, + {"PTRACE_O_TRACEEXEC", Const, 0}, + {"PTRACE_O_TRACEEXIT", Const, 0}, + {"PTRACE_O_TRACEFORK", Const, 0}, + {"PTRACE_O_TRACESYSGOOD", Const, 0}, + {"PTRACE_O_TRACEVFORK", Const, 0}, + {"PTRACE_O_TRACEVFORKDONE", Const, 0}, + {"PTRACE_PEEKDATA", Const, 0}, + {"PTRACE_PEEKTEXT", Const, 0}, + {"PTRACE_PEEKUSR", Const, 0}, + {"PTRACE_POKEDATA", Const, 0}, + {"PTRACE_POKETEXT", Const, 0}, + {"PTRACE_POKEUSR", Const, 0}, + {"PTRACE_SETCRUNCHREGS", Const, 0}, + {"PTRACE_SETFPREGS", Const, 0}, + {"PTRACE_SETFPXREGS", Const, 0}, + {"PTRACE_SETHBPREGS", Const, 0}, + {"PTRACE_SETOPTIONS", Const, 0}, + {"PTRACE_SETREGS", Const, 0}, + {"PTRACE_SETREGSET", Const, 0}, + {"PTRACE_SETSIGINFO", Const, 0}, + {"PTRACE_SETVFPREGS", Const, 0}, + {"PTRACE_SETWMMXREGS", Const, 0}, + {"PTRACE_SET_SYSCALL", Const, 0}, + {"PTRACE_SET_THREAD_AREA", Const, 0}, + {"PTRACE_SINGLEBLOCK", Const, 0}, + {"PTRACE_SINGLESTEP", Const, 0}, + {"PTRACE_SYSCALL", Const, 0}, + {"PTRACE_SYSEMU", Const, 0}, + {"PTRACE_SYSEMU_SINGLESTEP", Const, 0}, + {"PTRACE_TRACEME", Const, 0}, + {"PT_ATTACH", Const, 0}, + {"PT_ATTACHEXC", Const, 0}, + {"PT_CONTINUE", Const, 0}, + {"PT_DATA_ADDR", Const, 0}, + {"PT_DENY_ATTACH", Const, 0}, + {"PT_DETACH", Const, 0}, + {"PT_FIRSTMACH", Const, 0}, + {"PT_FORCEQUOTA", Const, 0}, + {"PT_KILL", Const, 0}, + {"PT_MASK", Const, 1}, + {"PT_READ_D", Const, 0}, + {"PT_READ_I", Const, 0}, + {"PT_READ_U", Const, 0}, + {"PT_SIGEXC", Const, 0}, + {"PT_STEP", Const, 0}, + {"PT_TEXT_ADDR", Const, 0}, + {"PT_TEXT_END_ADDR", Const, 0}, + {"PT_THUPDATE", Const, 0}, + {"PT_TRACE_ME", Const, 0}, + {"PT_WRITE_D", Const, 0}, + {"PT_WRITE_I", Const, 0}, + {"PT_WRITE_U", Const, 0}, + {"ParseDirent", Func, 0}, + {"ParseNetlinkMessage", Func, 0}, + {"ParseNetlinkRouteAttr", Func, 0}, + {"ParseRoutingMessage", Func, 0}, + {"ParseRoutingSockaddr", Func, 0}, + {"ParseSocketControlMessage", Func, 0}, + {"ParseUnixCredentials", Func, 0}, + {"ParseUnixRights", Func, 0}, + {"PathMax", Const, 0}, + {"Pathconf", Func, 0}, + {"Pause", Func, 0}, + {"Pipe", Func, 0}, + {"Pipe2", Func, 1}, + {"PivotRoot", Func, 0}, + {"Pointer", Type, 11}, + {"PostQueuedCompletionStatus", Func, 0}, + {"Pread", Func, 0}, + {"Proc", Type, 0}, + {"Proc.Dll", Field, 0}, + {"Proc.Name", Field, 0}, + {"ProcAttr", Type, 0}, + {"ProcAttr.Dir", Field, 0}, + {"ProcAttr.Env", Field, 0}, + {"ProcAttr.Files", Field, 0}, + {"ProcAttr.Sys", Field, 0}, + {"Process32First", Func, 4}, + {"Process32Next", Func, 4}, + {"ProcessEntry32", Type, 4}, + {"ProcessEntry32.DefaultHeapID", Field, 4}, + {"ProcessEntry32.ExeFile", Field, 4}, + {"ProcessEntry32.Flags", Field, 4}, + {"ProcessEntry32.ModuleID", Field, 4}, + {"ProcessEntry32.ParentProcessID", Field, 4}, + {"ProcessEntry32.PriClassBase", Field, 4}, + {"ProcessEntry32.ProcessID", Field, 4}, + {"ProcessEntry32.Size", Field, 4}, + {"ProcessEntry32.Threads", Field, 4}, + {"ProcessEntry32.Usage", Field, 4}, + {"ProcessInformation", Type, 0}, + {"ProcessInformation.Process", Field, 0}, + {"ProcessInformation.ProcessId", Field, 0}, + {"ProcessInformation.Thread", Field, 0}, + {"ProcessInformation.ThreadId", Field, 0}, + {"Protoent", Type, 0}, + {"Protoent.Aliases", Field, 0}, + {"Protoent.Name", Field, 0}, + {"Protoent.Proto", Field, 0}, + {"PtraceAttach", Func, 0}, + {"PtraceCont", Func, 0}, + {"PtraceDetach", Func, 0}, + {"PtraceGetEventMsg", Func, 0}, + {"PtraceGetRegs", Func, 0}, + {"PtracePeekData", Func, 0}, + {"PtracePeekText", Func, 0}, + {"PtracePokeData", Func, 0}, + {"PtracePokeText", Func, 0}, + {"PtraceRegs", Type, 0}, + {"PtraceRegs.Cs", Field, 0}, + {"PtraceRegs.Ds", Field, 0}, + {"PtraceRegs.Eax", Field, 0}, + {"PtraceRegs.Ebp", Field, 0}, + {"PtraceRegs.Ebx", Field, 0}, + {"PtraceRegs.Ecx", Field, 0}, + {"PtraceRegs.Edi", Field, 0}, + {"PtraceRegs.Edx", Field, 0}, + {"PtraceRegs.Eflags", Field, 0}, + {"PtraceRegs.Eip", Field, 0}, + {"PtraceRegs.Es", Field, 0}, + {"PtraceRegs.Esi", Field, 0}, + {"PtraceRegs.Esp", Field, 0}, + {"PtraceRegs.Fs", Field, 0}, + {"PtraceRegs.Fs_base", Field, 0}, + {"PtraceRegs.Gs", Field, 0}, + {"PtraceRegs.Gs_base", Field, 0}, + {"PtraceRegs.Orig_eax", Field, 0}, + {"PtraceRegs.Orig_rax", Field, 0}, + {"PtraceRegs.R10", Field, 0}, + {"PtraceRegs.R11", Field, 0}, + {"PtraceRegs.R12", Field, 0}, + {"PtraceRegs.R13", Field, 0}, + {"PtraceRegs.R14", Field, 0}, + {"PtraceRegs.R15", Field, 0}, + {"PtraceRegs.R8", Field, 0}, + {"PtraceRegs.R9", Field, 0}, + {"PtraceRegs.Rax", Field, 0}, + {"PtraceRegs.Rbp", Field, 0}, + {"PtraceRegs.Rbx", Field, 0}, + {"PtraceRegs.Rcx", Field, 0}, + {"PtraceRegs.Rdi", Field, 0}, + {"PtraceRegs.Rdx", Field, 0}, + {"PtraceRegs.Rip", Field, 0}, + {"PtraceRegs.Rsi", Field, 0}, + {"PtraceRegs.Rsp", Field, 0}, + {"PtraceRegs.Ss", Field, 0}, + {"PtraceRegs.Uregs", Field, 0}, + {"PtraceRegs.Xcs", Field, 0}, + {"PtraceRegs.Xds", Field, 0}, + {"PtraceRegs.Xes", Field, 0}, + {"PtraceRegs.Xfs", Field, 0}, + {"PtraceRegs.Xgs", Field, 0}, + {"PtraceRegs.Xss", Field, 0}, + {"PtraceSetOptions", Func, 0}, + {"PtraceSetRegs", Func, 0}, + {"PtraceSingleStep", Func, 0}, + {"PtraceSyscall", Func, 1}, + {"Pwrite", Func, 0}, + {"REG_BINARY", Const, 0}, + {"REG_DWORD", Const, 0}, + {"REG_DWORD_BIG_ENDIAN", Const, 0}, + {"REG_DWORD_LITTLE_ENDIAN", Const, 0}, + {"REG_EXPAND_SZ", Const, 0}, + {"REG_FULL_RESOURCE_DESCRIPTOR", Const, 0}, + {"REG_LINK", Const, 0}, + {"REG_MULTI_SZ", Const, 0}, + {"REG_NONE", Const, 0}, + {"REG_QWORD", Const, 0}, + {"REG_QWORD_LITTLE_ENDIAN", Const, 0}, + {"REG_RESOURCE_LIST", Const, 0}, + {"REG_RESOURCE_REQUIREMENTS_LIST", Const, 0}, + {"REG_SZ", Const, 0}, + {"RLIMIT_AS", Const, 0}, + {"RLIMIT_CORE", Const, 0}, + {"RLIMIT_CPU", Const, 0}, + {"RLIMIT_CPU_USAGE_MONITOR", Const, 16}, + {"RLIMIT_DATA", Const, 0}, + {"RLIMIT_FSIZE", Const, 0}, + {"RLIMIT_NOFILE", Const, 0}, + {"RLIMIT_STACK", Const, 0}, + {"RLIM_INFINITY", Const, 0}, + {"RTAX_ADVMSS", Const, 0}, + {"RTAX_AUTHOR", Const, 0}, + {"RTAX_BRD", Const, 0}, + {"RTAX_CWND", Const, 0}, + {"RTAX_DST", Const, 0}, + {"RTAX_FEATURES", Const, 0}, + {"RTAX_FEATURE_ALLFRAG", Const, 0}, + {"RTAX_FEATURE_ECN", Const, 0}, + {"RTAX_FEATURE_SACK", Const, 0}, + {"RTAX_FEATURE_TIMESTAMP", Const, 0}, + {"RTAX_GATEWAY", Const, 0}, + {"RTAX_GENMASK", Const, 0}, + {"RTAX_HOPLIMIT", Const, 0}, + {"RTAX_IFA", Const, 0}, + {"RTAX_IFP", Const, 0}, + {"RTAX_INITCWND", Const, 0}, + {"RTAX_INITRWND", Const, 0}, + {"RTAX_LABEL", Const, 1}, + {"RTAX_LOCK", Const, 0}, + {"RTAX_MAX", Const, 0}, + {"RTAX_MTU", Const, 0}, + {"RTAX_NETMASK", Const, 0}, + {"RTAX_REORDERING", Const, 0}, + {"RTAX_RTO_MIN", Const, 0}, + {"RTAX_RTT", Const, 0}, + {"RTAX_RTTVAR", Const, 0}, + {"RTAX_SRC", Const, 1}, + {"RTAX_SRCMASK", Const, 1}, + {"RTAX_SSTHRESH", Const, 0}, + {"RTAX_TAG", Const, 1}, + {"RTAX_UNSPEC", Const, 0}, + {"RTAX_WINDOW", Const, 0}, + {"RTA_ALIGNTO", Const, 0}, + {"RTA_AUTHOR", Const, 0}, + {"RTA_BRD", Const, 0}, + {"RTA_CACHEINFO", Const, 0}, + {"RTA_DST", Const, 0}, + {"RTA_FLOW", Const, 0}, + {"RTA_GATEWAY", Const, 0}, + {"RTA_GENMASK", Const, 0}, + {"RTA_IFA", Const, 0}, + {"RTA_IFP", Const, 0}, + {"RTA_IIF", Const, 0}, + {"RTA_LABEL", Const, 1}, + {"RTA_MAX", Const, 0}, + {"RTA_METRICS", Const, 0}, + {"RTA_MULTIPATH", Const, 0}, + {"RTA_NETMASK", Const, 0}, + {"RTA_OIF", Const, 0}, + {"RTA_PREFSRC", Const, 0}, + {"RTA_PRIORITY", Const, 0}, + {"RTA_SRC", Const, 0}, + {"RTA_SRCMASK", Const, 1}, + {"RTA_TABLE", Const, 0}, + {"RTA_TAG", Const, 1}, + {"RTA_UNSPEC", Const, 0}, + {"RTCF_DIRECTSRC", Const, 0}, + {"RTCF_DOREDIRECT", Const, 0}, + {"RTCF_LOG", Const, 0}, + {"RTCF_MASQ", Const, 0}, + {"RTCF_NAT", Const, 0}, + {"RTCF_VALVE", Const, 0}, + {"RTF_ADDRCLASSMASK", Const, 0}, + {"RTF_ADDRCONF", Const, 0}, + {"RTF_ALLONLINK", Const, 0}, + {"RTF_ANNOUNCE", Const, 1}, + {"RTF_BLACKHOLE", Const, 0}, + {"RTF_BROADCAST", Const, 0}, + {"RTF_CACHE", Const, 0}, + {"RTF_CLONED", Const, 1}, + {"RTF_CLONING", Const, 0}, + {"RTF_CONDEMNED", Const, 0}, + {"RTF_DEFAULT", Const, 0}, + {"RTF_DELCLONE", Const, 0}, + {"RTF_DONE", Const, 0}, + {"RTF_DYNAMIC", Const, 0}, + {"RTF_FLOW", Const, 0}, + {"RTF_FMASK", Const, 0}, + {"RTF_GATEWAY", Const, 0}, + {"RTF_GWFLAG_COMPAT", Const, 3}, + {"RTF_HOST", Const, 0}, + {"RTF_IFREF", Const, 0}, + {"RTF_IFSCOPE", Const, 0}, + {"RTF_INTERFACE", Const, 0}, + {"RTF_IRTT", Const, 0}, + {"RTF_LINKRT", Const, 0}, + {"RTF_LLDATA", Const, 0}, + {"RTF_LLINFO", Const, 0}, + {"RTF_LOCAL", Const, 0}, + {"RTF_MASK", Const, 1}, + {"RTF_MODIFIED", Const, 0}, + {"RTF_MPATH", Const, 1}, + {"RTF_MPLS", Const, 1}, + {"RTF_MSS", Const, 0}, + {"RTF_MTU", Const, 0}, + {"RTF_MULTICAST", Const, 0}, + {"RTF_NAT", Const, 0}, + {"RTF_NOFORWARD", Const, 0}, + {"RTF_NONEXTHOP", Const, 0}, + {"RTF_NOPMTUDISC", Const, 0}, + {"RTF_PERMANENT_ARP", Const, 1}, + {"RTF_PINNED", Const, 0}, + {"RTF_POLICY", Const, 0}, + {"RTF_PRCLONING", Const, 0}, + {"RTF_PROTO1", Const, 0}, + {"RTF_PROTO2", Const, 0}, + {"RTF_PROTO3", Const, 0}, + {"RTF_PROXY", Const, 16}, + {"RTF_REINSTATE", Const, 0}, + {"RTF_REJECT", Const, 0}, + {"RTF_RNH_LOCKED", Const, 0}, + {"RTF_ROUTER", Const, 16}, + {"RTF_SOURCE", Const, 1}, + {"RTF_SRC", Const, 1}, + {"RTF_STATIC", Const, 0}, + {"RTF_STICKY", Const, 0}, + {"RTF_THROW", Const, 0}, + {"RTF_TUNNEL", Const, 1}, + {"RTF_UP", Const, 0}, + {"RTF_USETRAILERS", Const, 1}, + {"RTF_WASCLONED", Const, 0}, + {"RTF_WINDOW", Const, 0}, + {"RTF_XRESOLVE", Const, 0}, + {"RTM_ADD", Const, 0}, + {"RTM_BASE", Const, 0}, + {"RTM_CHANGE", Const, 0}, + {"RTM_CHGADDR", Const, 1}, + {"RTM_DELACTION", Const, 0}, + {"RTM_DELADDR", Const, 0}, + {"RTM_DELADDRLABEL", Const, 0}, + {"RTM_DELETE", Const, 0}, + {"RTM_DELLINK", Const, 0}, + {"RTM_DELMADDR", Const, 0}, + {"RTM_DELNEIGH", Const, 0}, + {"RTM_DELQDISC", Const, 0}, + {"RTM_DELROUTE", Const, 0}, + {"RTM_DELRULE", Const, 0}, + {"RTM_DELTCLASS", Const, 0}, + {"RTM_DELTFILTER", Const, 0}, + {"RTM_DESYNC", Const, 1}, + {"RTM_F_CLONED", Const, 0}, + {"RTM_F_EQUALIZE", Const, 0}, + {"RTM_F_NOTIFY", Const, 0}, + {"RTM_F_PREFIX", Const, 0}, + {"RTM_GET", Const, 0}, + {"RTM_GET2", Const, 0}, + {"RTM_GETACTION", Const, 0}, + {"RTM_GETADDR", Const, 0}, + {"RTM_GETADDRLABEL", Const, 0}, + {"RTM_GETANYCAST", Const, 0}, + {"RTM_GETDCB", Const, 0}, + {"RTM_GETLINK", Const, 0}, + {"RTM_GETMULTICAST", Const, 0}, + {"RTM_GETNEIGH", Const, 0}, + {"RTM_GETNEIGHTBL", Const, 0}, + {"RTM_GETQDISC", Const, 0}, + {"RTM_GETROUTE", Const, 0}, + {"RTM_GETRULE", Const, 0}, + {"RTM_GETTCLASS", Const, 0}, + {"RTM_GETTFILTER", Const, 0}, + {"RTM_IEEE80211", Const, 0}, + {"RTM_IFANNOUNCE", Const, 0}, + {"RTM_IFINFO", Const, 0}, + {"RTM_IFINFO2", Const, 0}, + {"RTM_LLINFO_UPD", Const, 1}, + {"RTM_LOCK", Const, 0}, + {"RTM_LOSING", Const, 0}, + {"RTM_MAX", Const, 0}, + {"RTM_MAXSIZE", Const, 1}, + {"RTM_MISS", Const, 0}, + {"RTM_NEWACTION", Const, 0}, + {"RTM_NEWADDR", Const, 0}, + {"RTM_NEWADDRLABEL", Const, 0}, + {"RTM_NEWLINK", Const, 0}, + {"RTM_NEWMADDR", Const, 0}, + {"RTM_NEWMADDR2", Const, 0}, + {"RTM_NEWNDUSEROPT", Const, 0}, + {"RTM_NEWNEIGH", Const, 0}, + {"RTM_NEWNEIGHTBL", Const, 0}, + {"RTM_NEWPREFIX", Const, 0}, + {"RTM_NEWQDISC", Const, 0}, + {"RTM_NEWROUTE", Const, 0}, + {"RTM_NEWRULE", Const, 0}, + {"RTM_NEWTCLASS", Const, 0}, + {"RTM_NEWTFILTER", Const, 0}, + {"RTM_NR_FAMILIES", Const, 0}, + {"RTM_NR_MSGTYPES", Const, 0}, + {"RTM_OIFINFO", Const, 1}, + {"RTM_OLDADD", Const, 0}, + {"RTM_OLDDEL", Const, 0}, + {"RTM_OOIFINFO", Const, 1}, + {"RTM_REDIRECT", Const, 0}, + {"RTM_RESOLVE", Const, 0}, + {"RTM_RTTUNIT", Const, 0}, + {"RTM_SETDCB", Const, 0}, + {"RTM_SETGATE", Const, 1}, + {"RTM_SETLINK", Const, 0}, + {"RTM_SETNEIGHTBL", Const, 0}, + {"RTM_VERSION", Const, 0}, + {"RTNH_ALIGNTO", Const, 0}, + {"RTNH_F_DEAD", Const, 0}, + {"RTNH_F_ONLINK", Const, 0}, + {"RTNH_F_PERVASIVE", Const, 0}, + {"RTNLGRP_IPV4_IFADDR", Const, 1}, + {"RTNLGRP_IPV4_MROUTE", Const, 1}, + {"RTNLGRP_IPV4_ROUTE", Const, 1}, + {"RTNLGRP_IPV4_RULE", Const, 1}, + {"RTNLGRP_IPV6_IFADDR", Const, 1}, + {"RTNLGRP_IPV6_IFINFO", Const, 1}, + {"RTNLGRP_IPV6_MROUTE", Const, 1}, + {"RTNLGRP_IPV6_PREFIX", Const, 1}, + {"RTNLGRP_IPV6_ROUTE", Const, 1}, + {"RTNLGRP_IPV6_RULE", Const, 1}, + {"RTNLGRP_LINK", Const, 1}, + {"RTNLGRP_ND_USEROPT", Const, 1}, + {"RTNLGRP_NEIGH", Const, 1}, + {"RTNLGRP_NONE", Const, 1}, + {"RTNLGRP_NOTIFY", Const, 1}, + {"RTNLGRP_TC", Const, 1}, + {"RTN_ANYCAST", Const, 0}, + {"RTN_BLACKHOLE", Const, 0}, + {"RTN_BROADCAST", Const, 0}, + {"RTN_LOCAL", Const, 0}, + {"RTN_MAX", Const, 0}, + {"RTN_MULTICAST", Const, 0}, + {"RTN_NAT", Const, 0}, + {"RTN_PROHIBIT", Const, 0}, + {"RTN_THROW", Const, 0}, + {"RTN_UNICAST", Const, 0}, + {"RTN_UNREACHABLE", Const, 0}, + {"RTN_UNSPEC", Const, 0}, + {"RTN_XRESOLVE", Const, 0}, + {"RTPROT_BIRD", Const, 0}, + {"RTPROT_BOOT", Const, 0}, + {"RTPROT_DHCP", Const, 0}, + {"RTPROT_DNROUTED", Const, 0}, + {"RTPROT_GATED", Const, 0}, + {"RTPROT_KERNEL", Const, 0}, + {"RTPROT_MRT", Const, 0}, + {"RTPROT_NTK", Const, 0}, + {"RTPROT_RA", Const, 0}, + {"RTPROT_REDIRECT", Const, 0}, + {"RTPROT_STATIC", Const, 0}, + {"RTPROT_UNSPEC", Const, 0}, + {"RTPROT_XORP", Const, 0}, + {"RTPROT_ZEBRA", Const, 0}, + {"RTV_EXPIRE", Const, 0}, + {"RTV_HOPCOUNT", Const, 0}, + {"RTV_MTU", Const, 0}, + {"RTV_RPIPE", Const, 0}, + {"RTV_RTT", Const, 0}, + {"RTV_RTTVAR", Const, 0}, + {"RTV_SPIPE", Const, 0}, + {"RTV_SSTHRESH", Const, 0}, + {"RTV_WEIGHT", Const, 0}, + {"RT_CACHING_CONTEXT", Const, 1}, + {"RT_CLASS_DEFAULT", Const, 0}, + {"RT_CLASS_LOCAL", Const, 0}, + {"RT_CLASS_MAIN", Const, 0}, + {"RT_CLASS_MAX", Const, 0}, + {"RT_CLASS_UNSPEC", Const, 0}, + {"RT_DEFAULT_FIB", Const, 1}, + {"RT_NORTREF", Const, 1}, + {"RT_SCOPE_HOST", Const, 0}, + {"RT_SCOPE_LINK", Const, 0}, + {"RT_SCOPE_NOWHERE", Const, 0}, + {"RT_SCOPE_SITE", Const, 0}, + {"RT_SCOPE_UNIVERSE", Const, 0}, + {"RT_TABLEID_MAX", Const, 1}, + {"RT_TABLE_COMPAT", Const, 0}, + {"RT_TABLE_DEFAULT", Const, 0}, + {"RT_TABLE_LOCAL", Const, 0}, + {"RT_TABLE_MAIN", Const, 0}, + {"RT_TABLE_MAX", Const, 0}, + {"RT_TABLE_UNSPEC", Const, 0}, + {"RUSAGE_CHILDREN", Const, 0}, + {"RUSAGE_SELF", Const, 0}, + {"RUSAGE_THREAD", Const, 0}, + {"Radvisory_t", Type, 0}, + {"Radvisory_t.Count", Field, 0}, + {"Radvisory_t.Offset", Field, 0}, + {"Radvisory_t.Pad_cgo_0", Field, 0}, + {"RawConn", Type, 9}, + {"RawSockaddr", Type, 0}, + {"RawSockaddr.Data", Field, 0}, + {"RawSockaddr.Family", Field, 0}, + {"RawSockaddr.Len", Field, 0}, + {"RawSockaddrAny", Type, 0}, + {"RawSockaddrAny.Addr", Field, 0}, + {"RawSockaddrAny.Pad", Field, 0}, + {"RawSockaddrDatalink", Type, 0}, + {"RawSockaddrDatalink.Alen", Field, 0}, + {"RawSockaddrDatalink.Data", Field, 0}, + {"RawSockaddrDatalink.Family", Field, 0}, + {"RawSockaddrDatalink.Index", Field, 0}, + {"RawSockaddrDatalink.Len", Field, 0}, + {"RawSockaddrDatalink.Nlen", Field, 0}, + {"RawSockaddrDatalink.Pad_cgo_0", Field, 2}, + {"RawSockaddrDatalink.Slen", Field, 0}, + {"RawSockaddrDatalink.Type", Field, 0}, + {"RawSockaddrInet4", Type, 0}, + {"RawSockaddrInet4.Addr", Field, 0}, + {"RawSockaddrInet4.Family", Field, 0}, + {"RawSockaddrInet4.Len", Field, 0}, + {"RawSockaddrInet4.Port", Field, 0}, + {"RawSockaddrInet4.Zero", Field, 0}, + {"RawSockaddrInet6", Type, 0}, + {"RawSockaddrInet6.Addr", Field, 0}, + {"RawSockaddrInet6.Family", Field, 0}, + {"RawSockaddrInet6.Flowinfo", Field, 0}, + {"RawSockaddrInet6.Len", Field, 0}, + {"RawSockaddrInet6.Port", Field, 0}, + {"RawSockaddrInet6.Scope_id", Field, 0}, + {"RawSockaddrLinklayer", Type, 0}, + {"RawSockaddrLinklayer.Addr", Field, 0}, + {"RawSockaddrLinklayer.Family", Field, 0}, + {"RawSockaddrLinklayer.Halen", Field, 0}, + {"RawSockaddrLinklayer.Hatype", Field, 0}, + {"RawSockaddrLinklayer.Ifindex", Field, 0}, + {"RawSockaddrLinklayer.Pkttype", Field, 0}, + {"RawSockaddrLinklayer.Protocol", Field, 0}, + {"RawSockaddrNetlink", Type, 0}, + {"RawSockaddrNetlink.Family", Field, 0}, + {"RawSockaddrNetlink.Groups", Field, 0}, + {"RawSockaddrNetlink.Pad", Field, 0}, + {"RawSockaddrNetlink.Pid", Field, 0}, + {"RawSockaddrUnix", Type, 0}, + {"RawSockaddrUnix.Family", Field, 0}, + {"RawSockaddrUnix.Len", Field, 0}, + {"RawSockaddrUnix.Pad_cgo_0", Field, 2}, + {"RawSockaddrUnix.Path", Field, 0}, + {"RawSyscall", Func, 0}, + {"RawSyscall6", Func, 0}, + {"Read", Func, 0}, + {"ReadConsole", Func, 1}, + {"ReadDirectoryChanges", Func, 0}, + {"ReadDirent", Func, 0}, + {"ReadFile", Func, 0}, + {"Readlink", Func, 0}, + {"Reboot", Func, 0}, + {"Recvfrom", Func, 0}, + {"Recvmsg", Func, 0}, + {"RegCloseKey", Func, 0}, + {"RegEnumKeyEx", Func, 0}, + {"RegOpenKeyEx", Func, 0}, + {"RegQueryInfoKey", Func, 0}, + {"RegQueryValueEx", Func, 0}, + {"RemoveDirectory", Func, 0}, + {"Removexattr", Func, 1}, + {"Rename", Func, 0}, + {"Renameat", Func, 0}, + {"Revoke", Func, 0}, + {"Rlimit", Type, 0}, + {"Rlimit.Cur", Field, 0}, + {"Rlimit.Max", Field, 0}, + {"Rmdir", Func, 0}, + {"RouteMessage", Type, 0}, + {"RouteMessage.Data", Field, 0}, + {"RouteMessage.Header", Field, 0}, + {"RouteRIB", Func, 0}, + {"RoutingMessage", Type, 0}, + {"RtAttr", Type, 0}, + {"RtAttr.Len", Field, 0}, + {"RtAttr.Type", Field, 0}, + {"RtGenmsg", Type, 0}, + {"RtGenmsg.Family", Field, 0}, + {"RtMetrics", Type, 0}, + {"RtMetrics.Expire", Field, 0}, + {"RtMetrics.Filler", Field, 0}, + {"RtMetrics.Hopcount", Field, 0}, + {"RtMetrics.Locks", Field, 0}, + {"RtMetrics.Mtu", Field, 0}, + {"RtMetrics.Pad", Field, 3}, + {"RtMetrics.Pksent", Field, 0}, + {"RtMetrics.Recvpipe", Field, 0}, + {"RtMetrics.Refcnt", Field, 2}, + {"RtMetrics.Rtt", Field, 0}, + {"RtMetrics.Rttvar", Field, 0}, + {"RtMetrics.Sendpipe", Field, 0}, + {"RtMetrics.Ssthresh", Field, 0}, + {"RtMetrics.Weight", Field, 0}, + {"RtMsg", Type, 0}, + {"RtMsg.Dst_len", Field, 0}, + {"RtMsg.Family", Field, 0}, + {"RtMsg.Flags", Field, 0}, + {"RtMsg.Protocol", Field, 0}, + {"RtMsg.Scope", Field, 0}, + {"RtMsg.Src_len", Field, 0}, + {"RtMsg.Table", Field, 0}, + {"RtMsg.Tos", Field, 0}, + {"RtMsg.Type", Field, 0}, + {"RtMsghdr", Type, 0}, + {"RtMsghdr.Addrs", Field, 0}, + {"RtMsghdr.Errno", Field, 0}, + {"RtMsghdr.Flags", Field, 0}, + {"RtMsghdr.Fmask", Field, 0}, + {"RtMsghdr.Hdrlen", Field, 2}, + {"RtMsghdr.Index", Field, 0}, + {"RtMsghdr.Inits", Field, 0}, + {"RtMsghdr.Mpls", Field, 2}, + {"RtMsghdr.Msglen", Field, 0}, + {"RtMsghdr.Pad_cgo_0", Field, 0}, + {"RtMsghdr.Pad_cgo_1", Field, 2}, + {"RtMsghdr.Pid", Field, 0}, + {"RtMsghdr.Priority", Field, 2}, + {"RtMsghdr.Rmx", Field, 0}, + {"RtMsghdr.Seq", Field, 0}, + {"RtMsghdr.Tableid", Field, 2}, + {"RtMsghdr.Type", Field, 0}, + {"RtMsghdr.Use", Field, 0}, + {"RtMsghdr.Version", Field, 0}, + {"RtNexthop", Type, 0}, + {"RtNexthop.Flags", Field, 0}, + {"RtNexthop.Hops", Field, 0}, + {"RtNexthop.Ifindex", Field, 0}, + {"RtNexthop.Len", Field, 0}, + {"Rusage", Type, 0}, + {"Rusage.CreationTime", Field, 0}, + {"Rusage.ExitTime", Field, 0}, + {"Rusage.Idrss", Field, 0}, + {"Rusage.Inblock", Field, 0}, + {"Rusage.Isrss", Field, 0}, + {"Rusage.Ixrss", Field, 0}, + {"Rusage.KernelTime", Field, 0}, + {"Rusage.Majflt", Field, 0}, + {"Rusage.Maxrss", Field, 0}, + {"Rusage.Minflt", Field, 0}, + {"Rusage.Msgrcv", Field, 0}, + {"Rusage.Msgsnd", Field, 0}, + {"Rusage.Nivcsw", Field, 0}, + {"Rusage.Nsignals", Field, 0}, + {"Rusage.Nswap", Field, 0}, + {"Rusage.Nvcsw", Field, 0}, + {"Rusage.Oublock", Field, 0}, + {"Rusage.Stime", Field, 0}, + {"Rusage.UserTime", Field, 0}, + {"Rusage.Utime", Field, 0}, + {"SCM_BINTIME", Const, 0}, + {"SCM_CREDENTIALS", Const, 0}, + {"SCM_CREDS", Const, 0}, + {"SCM_RIGHTS", Const, 0}, + {"SCM_TIMESTAMP", Const, 0}, + {"SCM_TIMESTAMPING", Const, 0}, + {"SCM_TIMESTAMPNS", Const, 0}, + {"SCM_TIMESTAMP_MONOTONIC", Const, 0}, + {"SHUT_RD", Const, 0}, + {"SHUT_RDWR", Const, 0}, + {"SHUT_WR", Const, 0}, + {"SID", Type, 0}, + {"SIDAndAttributes", Type, 0}, + {"SIDAndAttributes.Attributes", Field, 0}, + {"SIDAndAttributes.Sid", Field, 0}, + {"SIGABRT", Const, 0}, + {"SIGALRM", Const, 0}, + {"SIGBUS", Const, 0}, + {"SIGCHLD", Const, 0}, + {"SIGCLD", Const, 0}, + {"SIGCONT", Const, 0}, + {"SIGEMT", Const, 0}, + {"SIGFPE", Const, 0}, + {"SIGHUP", Const, 0}, + {"SIGILL", Const, 0}, + {"SIGINFO", Const, 0}, + {"SIGINT", Const, 0}, + {"SIGIO", Const, 0}, + {"SIGIOT", Const, 0}, + {"SIGKILL", Const, 0}, + {"SIGLIBRT", Const, 1}, + {"SIGLWP", Const, 0}, + {"SIGPIPE", Const, 0}, + {"SIGPOLL", Const, 0}, + {"SIGPROF", Const, 0}, + {"SIGPWR", Const, 0}, + {"SIGQUIT", Const, 0}, + {"SIGSEGV", Const, 0}, + {"SIGSTKFLT", Const, 0}, + {"SIGSTOP", Const, 0}, + {"SIGSYS", Const, 0}, + {"SIGTERM", Const, 0}, + {"SIGTHR", Const, 0}, + {"SIGTRAP", Const, 0}, + {"SIGTSTP", Const, 0}, + {"SIGTTIN", Const, 0}, + {"SIGTTOU", Const, 0}, + {"SIGUNUSED", Const, 0}, + {"SIGURG", Const, 0}, + {"SIGUSR1", Const, 0}, + {"SIGUSR2", Const, 0}, + {"SIGVTALRM", Const, 0}, + {"SIGWINCH", Const, 0}, + {"SIGXCPU", Const, 0}, + {"SIGXFSZ", Const, 0}, + {"SIOCADDDLCI", Const, 0}, + {"SIOCADDMULTI", Const, 0}, + {"SIOCADDRT", Const, 0}, + {"SIOCAIFADDR", Const, 0}, + {"SIOCAIFGROUP", Const, 0}, + {"SIOCALIFADDR", Const, 0}, + {"SIOCARPIPLL", Const, 0}, + {"SIOCATMARK", Const, 0}, + {"SIOCAUTOADDR", Const, 0}, + {"SIOCAUTONETMASK", Const, 0}, + {"SIOCBRDGADD", Const, 1}, + {"SIOCBRDGADDS", Const, 1}, + {"SIOCBRDGARL", Const, 1}, + {"SIOCBRDGDADDR", Const, 1}, + {"SIOCBRDGDEL", Const, 1}, + {"SIOCBRDGDELS", Const, 1}, + {"SIOCBRDGFLUSH", Const, 1}, + {"SIOCBRDGFRL", Const, 1}, + {"SIOCBRDGGCACHE", Const, 1}, + {"SIOCBRDGGFD", Const, 1}, + {"SIOCBRDGGHT", Const, 1}, + {"SIOCBRDGGIFFLGS", Const, 1}, + {"SIOCBRDGGMA", Const, 1}, + {"SIOCBRDGGPARAM", Const, 1}, + {"SIOCBRDGGPRI", Const, 1}, + {"SIOCBRDGGRL", Const, 1}, + {"SIOCBRDGGSIFS", Const, 1}, + {"SIOCBRDGGTO", Const, 1}, + {"SIOCBRDGIFS", Const, 1}, + {"SIOCBRDGRTS", Const, 1}, + {"SIOCBRDGSADDR", Const, 1}, + {"SIOCBRDGSCACHE", Const, 1}, + {"SIOCBRDGSFD", Const, 1}, + {"SIOCBRDGSHT", Const, 1}, + {"SIOCBRDGSIFCOST", Const, 1}, + {"SIOCBRDGSIFFLGS", Const, 1}, + {"SIOCBRDGSIFPRIO", Const, 1}, + {"SIOCBRDGSMA", Const, 1}, + {"SIOCBRDGSPRI", Const, 1}, + {"SIOCBRDGSPROTO", Const, 1}, + {"SIOCBRDGSTO", Const, 1}, + {"SIOCBRDGSTXHC", Const, 1}, + {"SIOCDARP", Const, 0}, + {"SIOCDELDLCI", Const, 0}, + {"SIOCDELMULTI", Const, 0}, + {"SIOCDELRT", Const, 0}, + {"SIOCDEVPRIVATE", Const, 0}, + {"SIOCDIFADDR", Const, 0}, + {"SIOCDIFGROUP", Const, 0}, + {"SIOCDIFPHYADDR", Const, 0}, + {"SIOCDLIFADDR", Const, 0}, + {"SIOCDRARP", Const, 0}, + {"SIOCGARP", Const, 0}, + {"SIOCGDRVSPEC", Const, 0}, + {"SIOCGETKALIVE", Const, 1}, + {"SIOCGETLABEL", Const, 1}, + {"SIOCGETPFLOW", Const, 1}, + {"SIOCGETPFSYNC", Const, 1}, + {"SIOCGETSGCNT", Const, 0}, + {"SIOCGETVIFCNT", Const, 0}, + {"SIOCGETVLAN", Const, 0}, + {"SIOCGHIWAT", Const, 0}, + {"SIOCGIFADDR", Const, 0}, + {"SIOCGIFADDRPREF", Const, 1}, + {"SIOCGIFALIAS", Const, 1}, + {"SIOCGIFALTMTU", Const, 0}, + {"SIOCGIFASYNCMAP", Const, 0}, + {"SIOCGIFBOND", Const, 0}, + {"SIOCGIFBR", Const, 0}, + {"SIOCGIFBRDADDR", Const, 0}, + {"SIOCGIFCAP", Const, 0}, + {"SIOCGIFCONF", Const, 0}, + {"SIOCGIFCOUNT", Const, 0}, + {"SIOCGIFDATA", Const, 1}, + {"SIOCGIFDESCR", Const, 0}, + {"SIOCGIFDEVMTU", Const, 0}, + {"SIOCGIFDLT", Const, 1}, + {"SIOCGIFDSTADDR", Const, 0}, + {"SIOCGIFENCAP", Const, 0}, + {"SIOCGIFFIB", Const, 1}, + {"SIOCGIFFLAGS", Const, 0}, + {"SIOCGIFGATTR", Const, 1}, + {"SIOCGIFGENERIC", Const, 0}, + {"SIOCGIFGMEMB", Const, 0}, + {"SIOCGIFGROUP", Const, 0}, + {"SIOCGIFHARDMTU", Const, 3}, + {"SIOCGIFHWADDR", Const, 0}, + {"SIOCGIFINDEX", Const, 0}, + {"SIOCGIFKPI", Const, 0}, + {"SIOCGIFMAC", Const, 0}, + {"SIOCGIFMAP", Const, 0}, + {"SIOCGIFMEDIA", Const, 0}, + {"SIOCGIFMEM", Const, 0}, + {"SIOCGIFMETRIC", Const, 0}, + {"SIOCGIFMTU", Const, 0}, + {"SIOCGIFNAME", Const, 0}, + {"SIOCGIFNETMASK", Const, 0}, + {"SIOCGIFPDSTADDR", Const, 0}, + {"SIOCGIFPFLAGS", Const, 0}, + {"SIOCGIFPHYS", Const, 0}, + {"SIOCGIFPRIORITY", Const, 1}, + {"SIOCGIFPSRCADDR", Const, 0}, + {"SIOCGIFRDOMAIN", Const, 1}, + {"SIOCGIFRTLABEL", Const, 1}, + {"SIOCGIFSLAVE", Const, 0}, + {"SIOCGIFSTATUS", Const, 0}, + {"SIOCGIFTIMESLOT", Const, 1}, + {"SIOCGIFTXQLEN", Const, 0}, + {"SIOCGIFVLAN", Const, 0}, + {"SIOCGIFWAKEFLAGS", Const, 0}, + {"SIOCGIFXFLAGS", Const, 1}, + {"SIOCGLIFADDR", Const, 0}, + {"SIOCGLIFPHYADDR", Const, 0}, + {"SIOCGLIFPHYRTABLE", Const, 1}, + {"SIOCGLIFPHYTTL", Const, 3}, + {"SIOCGLINKSTR", Const, 1}, + {"SIOCGLOWAT", Const, 0}, + {"SIOCGPGRP", Const, 0}, + {"SIOCGPRIVATE_0", Const, 0}, + {"SIOCGPRIVATE_1", Const, 0}, + {"SIOCGRARP", Const, 0}, + {"SIOCGSPPPPARAMS", Const, 3}, + {"SIOCGSTAMP", Const, 0}, + {"SIOCGSTAMPNS", Const, 0}, + {"SIOCGVH", Const, 1}, + {"SIOCGVNETID", Const, 3}, + {"SIOCIFCREATE", Const, 0}, + {"SIOCIFCREATE2", Const, 0}, + {"SIOCIFDESTROY", Const, 0}, + {"SIOCIFGCLONERS", Const, 0}, + {"SIOCINITIFADDR", Const, 1}, + {"SIOCPROTOPRIVATE", Const, 0}, + {"SIOCRSLVMULTI", Const, 0}, + {"SIOCRTMSG", Const, 0}, + {"SIOCSARP", Const, 0}, + {"SIOCSDRVSPEC", Const, 0}, + {"SIOCSETKALIVE", Const, 1}, + {"SIOCSETLABEL", Const, 1}, + {"SIOCSETPFLOW", Const, 1}, + {"SIOCSETPFSYNC", Const, 1}, + {"SIOCSETVLAN", Const, 0}, + {"SIOCSHIWAT", Const, 0}, + {"SIOCSIFADDR", Const, 0}, + {"SIOCSIFADDRPREF", Const, 1}, + {"SIOCSIFALTMTU", Const, 0}, + {"SIOCSIFASYNCMAP", Const, 0}, + {"SIOCSIFBOND", Const, 0}, + {"SIOCSIFBR", Const, 0}, + {"SIOCSIFBRDADDR", Const, 0}, + {"SIOCSIFCAP", Const, 0}, + {"SIOCSIFDESCR", Const, 0}, + {"SIOCSIFDSTADDR", Const, 0}, + {"SIOCSIFENCAP", Const, 0}, + {"SIOCSIFFIB", Const, 1}, + {"SIOCSIFFLAGS", Const, 0}, + {"SIOCSIFGATTR", Const, 1}, + {"SIOCSIFGENERIC", Const, 0}, + {"SIOCSIFHWADDR", Const, 0}, + {"SIOCSIFHWBROADCAST", Const, 0}, + {"SIOCSIFKPI", Const, 0}, + {"SIOCSIFLINK", Const, 0}, + {"SIOCSIFLLADDR", Const, 0}, + {"SIOCSIFMAC", Const, 0}, + {"SIOCSIFMAP", Const, 0}, + {"SIOCSIFMEDIA", Const, 0}, + {"SIOCSIFMEM", Const, 0}, + {"SIOCSIFMETRIC", Const, 0}, + {"SIOCSIFMTU", Const, 0}, + {"SIOCSIFNAME", Const, 0}, + {"SIOCSIFNETMASK", Const, 0}, + {"SIOCSIFPFLAGS", Const, 0}, + {"SIOCSIFPHYADDR", Const, 0}, + {"SIOCSIFPHYS", Const, 0}, + {"SIOCSIFPRIORITY", Const, 1}, + {"SIOCSIFRDOMAIN", Const, 1}, + {"SIOCSIFRTLABEL", Const, 1}, + {"SIOCSIFRVNET", Const, 0}, + {"SIOCSIFSLAVE", Const, 0}, + {"SIOCSIFTIMESLOT", Const, 1}, + {"SIOCSIFTXQLEN", Const, 0}, + {"SIOCSIFVLAN", Const, 0}, + {"SIOCSIFVNET", Const, 0}, + {"SIOCSIFXFLAGS", Const, 1}, + {"SIOCSLIFPHYADDR", Const, 0}, + {"SIOCSLIFPHYRTABLE", Const, 1}, + {"SIOCSLIFPHYTTL", Const, 3}, + {"SIOCSLINKSTR", Const, 1}, + {"SIOCSLOWAT", Const, 0}, + {"SIOCSPGRP", Const, 0}, + {"SIOCSRARP", Const, 0}, + {"SIOCSSPPPPARAMS", Const, 3}, + {"SIOCSVH", Const, 1}, + {"SIOCSVNETID", Const, 3}, + {"SIOCZIFDATA", Const, 1}, + {"SIO_GET_EXTENSION_FUNCTION_POINTER", Const, 1}, + {"SIO_GET_INTERFACE_LIST", Const, 0}, + {"SIO_KEEPALIVE_VALS", Const, 3}, + {"SIO_UDP_CONNRESET", Const, 4}, + {"SOCK_CLOEXEC", Const, 0}, + {"SOCK_DCCP", Const, 0}, + {"SOCK_DGRAM", Const, 0}, + {"SOCK_FLAGS_MASK", Const, 1}, + {"SOCK_MAXADDRLEN", Const, 0}, + {"SOCK_NONBLOCK", Const, 0}, + {"SOCK_NOSIGPIPE", Const, 1}, + {"SOCK_PACKET", Const, 0}, + {"SOCK_RAW", Const, 0}, + {"SOCK_RDM", Const, 0}, + {"SOCK_SEQPACKET", Const, 0}, + {"SOCK_STREAM", Const, 0}, + {"SOL_AAL", Const, 0}, + {"SOL_ATM", Const, 0}, + {"SOL_DECNET", Const, 0}, + {"SOL_ICMPV6", Const, 0}, + {"SOL_IP", Const, 0}, + {"SOL_IPV6", Const, 0}, + {"SOL_IRDA", Const, 0}, + {"SOL_PACKET", Const, 0}, + {"SOL_RAW", Const, 0}, + {"SOL_SOCKET", Const, 0}, + {"SOL_TCP", Const, 0}, + {"SOL_X25", Const, 0}, + {"SOMAXCONN", Const, 0}, + {"SO_ACCEPTCONN", Const, 0}, + {"SO_ACCEPTFILTER", Const, 0}, + {"SO_ATTACH_FILTER", Const, 0}, + {"SO_BINDANY", Const, 1}, + {"SO_BINDTODEVICE", Const, 0}, + {"SO_BINTIME", Const, 0}, + {"SO_BROADCAST", Const, 0}, + {"SO_BSDCOMPAT", Const, 0}, + {"SO_DEBUG", Const, 0}, + {"SO_DETACH_FILTER", Const, 0}, + {"SO_DOMAIN", Const, 0}, + {"SO_DONTROUTE", Const, 0}, + {"SO_DONTTRUNC", Const, 0}, + {"SO_ERROR", Const, 0}, + {"SO_KEEPALIVE", Const, 0}, + {"SO_LABEL", Const, 0}, + {"SO_LINGER", Const, 0}, + {"SO_LINGER_SEC", Const, 0}, + {"SO_LISTENINCQLEN", Const, 0}, + {"SO_LISTENQLEN", Const, 0}, + {"SO_LISTENQLIMIT", Const, 0}, + {"SO_MARK", Const, 0}, + {"SO_NETPROC", Const, 1}, + {"SO_NKE", Const, 0}, + {"SO_NOADDRERR", Const, 0}, + {"SO_NOHEADER", Const, 1}, + {"SO_NOSIGPIPE", Const, 0}, + {"SO_NOTIFYCONFLICT", Const, 0}, + {"SO_NO_CHECK", Const, 0}, + {"SO_NO_DDP", Const, 0}, + {"SO_NO_OFFLOAD", Const, 0}, + {"SO_NP_EXTENSIONS", Const, 0}, + {"SO_NREAD", Const, 0}, + {"SO_NUMRCVPKT", Const, 16}, + {"SO_NWRITE", Const, 0}, + {"SO_OOBINLINE", Const, 0}, + {"SO_OVERFLOWED", Const, 1}, + {"SO_PASSCRED", Const, 0}, + {"SO_PASSSEC", Const, 0}, + {"SO_PEERCRED", Const, 0}, + {"SO_PEERLABEL", Const, 0}, + {"SO_PEERNAME", Const, 0}, + {"SO_PEERSEC", Const, 0}, + {"SO_PRIORITY", Const, 0}, + {"SO_PROTOCOL", Const, 0}, + {"SO_PROTOTYPE", Const, 1}, + {"SO_RANDOMPORT", Const, 0}, + {"SO_RCVBUF", Const, 0}, + {"SO_RCVBUFFORCE", Const, 0}, + {"SO_RCVLOWAT", Const, 0}, + {"SO_RCVTIMEO", Const, 0}, + {"SO_RESTRICTIONS", Const, 0}, + {"SO_RESTRICT_DENYIN", Const, 0}, + {"SO_RESTRICT_DENYOUT", Const, 0}, + {"SO_RESTRICT_DENYSET", Const, 0}, + {"SO_REUSEADDR", Const, 0}, + {"SO_REUSEPORT", Const, 0}, + {"SO_REUSESHAREUID", Const, 0}, + {"SO_RTABLE", Const, 1}, + {"SO_RXQ_OVFL", Const, 0}, + {"SO_SECURITY_AUTHENTICATION", Const, 0}, + {"SO_SECURITY_ENCRYPTION_NETWORK", Const, 0}, + {"SO_SECURITY_ENCRYPTION_TRANSPORT", Const, 0}, + {"SO_SETFIB", Const, 0}, + {"SO_SNDBUF", Const, 0}, + {"SO_SNDBUFFORCE", Const, 0}, + {"SO_SNDLOWAT", Const, 0}, + {"SO_SNDTIMEO", Const, 0}, + {"SO_SPLICE", Const, 1}, + {"SO_TIMESTAMP", Const, 0}, + {"SO_TIMESTAMPING", Const, 0}, + {"SO_TIMESTAMPNS", Const, 0}, + {"SO_TIMESTAMP_MONOTONIC", Const, 0}, + {"SO_TYPE", Const, 0}, + {"SO_UPCALLCLOSEWAIT", Const, 0}, + {"SO_UPDATE_ACCEPT_CONTEXT", Const, 0}, + {"SO_UPDATE_CONNECT_CONTEXT", Const, 1}, + {"SO_USELOOPBACK", Const, 0}, + {"SO_USER_COOKIE", Const, 1}, + {"SO_VENDOR", Const, 3}, + {"SO_WANTMORE", Const, 0}, + {"SO_WANTOOBFLAG", Const, 0}, + {"SSLExtraCertChainPolicyPara", Type, 0}, + {"SSLExtraCertChainPolicyPara.AuthType", Field, 0}, + {"SSLExtraCertChainPolicyPara.Checks", Field, 0}, + {"SSLExtraCertChainPolicyPara.ServerName", Field, 0}, + {"SSLExtraCertChainPolicyPara.Size", Field, 0}, + {"STANDARD_RIGHTS_ALL", Const, 0}, + {"STANDARD_RIGHTS_EXECUTE", Const, 0}, + {"STANDARD_RIGHTS_READ", Const, 0}, + {"STANDARD_RIGHTS_REQUIRED", Const, 0}, + {"STANDARD_RIGHTS_WRITE", Const, 0}, + {"STARTF_USESHOWWINDOW", Const, 0}, + {"STARTF_USESTDHANDLES", Const, 0}, + {"STD_ERROR_HANDLE", Const, 0}, + {"STD_INPUT_HANDLE", Const, 0}, + {"STD_OUTPUT_HANDLE", Const, 0}, + {"SUBLANG_ENGLISH_US", Const, 0}, + {"SW_FORCEMINIMIZE", Const, 0}, + {"SW_HIDE", Const, 0}, + {"SW_MAXIMIZE", Const, 0}, + {"SW_MINIMIZE", Const, 0}, + {"SW_NORMAL", Const, 0}, + {"SW_RESTORE", Const, 0}, + {"SW_SHOW", Const, 0}, + {"SW_SHOWDEFAULT", Const, 0}, + {"SW_SHOWMAXIMIZED", Const, 0}, + {"SW_SHOWMINIMIZED", Const, 0}, + {"SW_SHOWMINNOACTIVE", Const, 0}, + {"SW_SHOWNA", Const, 0}, + {"SW_SHOWNOACTIVATE", Const, 0}, + {"SW_SHOWNORMAL", Const, 0}, + {"SYMBOLIC_LINK_FLAG_DIRECTORY", Const, 4}, + {"SYNCHRONIZE", Const, 0}, + {"SYSCTL_VERSION", Const, 1}, + {"SYSCTL_VERS_0", Const, 1}, + {"SYSCTL_VERS_1", Const, 1}, + {"SYSCTL_VERS_MASK", Const, 1}, + {"SYS_ABORT2", Const, 0}, + {"SYS_ACCEPT", Const, 0}, + {"SYS_ACCEPT4", Const, 0}, + {"SYS_ACCEPT_NOCANCEL", Const, 0}, + {"SYS_ACCESS", Const, 0}, + {"SYS_ACCESS_EXTENDED", Const, 0}, + {"SYS_ACCT", Const, 0}, + {"SYS_ADD_KEY", Const, 0}, + {"SYS_ADD_PROFIL", Const, 0}, + {"SYS_ADJFREQ", Const, 1}, + {"SYS_ADJTIME", Const, 0}, + {"SYS_ADJTIMEX", Const, 0}, + {"SYS_AFS_SYSCALL", Const, 0}, + {"SYS_AIO_CANCEL", Const, 0}, + {"SYS_AIO_ERROR", Const, 0}, + {"SYS_AIO_FSYNC", Const, 0}, + {"SYS_AIO_MLOCK", Const, 14}, + {"SYS_AIO_READ", Const, 0}, + {"SYS_AIO_RETURN", Const, 0}, + {"SYS_AIO_SUSPEND", Const, 0}, + {"SYS_AIO_SUSPEND_NOCANCEL", Const, 0}, + {"SYS_AIO_WAITCOMPLETE", Const, 14}, + {"SYS_AIO_WRITE", Const, 0}, + {"SYS_ALARM", Const, 0}, + {"SYS_ARCH_PRCTL", Const, 0}, + {"SYS_ARM_FADVISE64_64", Const, 0}, + {"SYS_ARM_SYNC_FILE_RANGE", Const, 0}, + {"SYS_ATGETMSG", Const, 0}, + {"SYS_ATPGETREQ", Const, 0}, + {"SYS_ATPGETRSP", Const, 0}, + {"SYS_ATPSNDREQ", Const, 0}, + {"SYS_ATPSNDRSP", Const, 0}, + {"SYS_ATPUTMSG", Const, 0}, + {"SYS_ATSOCKET", Const, 0}, + {"SYS_AUDIT", Const, 0}, + {"SYS_AUDITCTL", Const, 0}, + {"SYS_AUDITON", Const, 0}, + {"SYS_AUDIT_SESSION_JOIN", Const, 0}, + {"SYS_AUDIT_SESSION_PORT", Const, 0}, + {"SYS_AUDIT_SESSION_SELF", Const, 0}, + {"SYS_BDFLUSH", Const, 0}, + {"SYS_BIND", Const, 0}, + {"SYS_BINDAT", Const, 3}, + {"SYS_BREAK", Const, 0}, + {"SYS_BRK", Const, 0}, + {"SYS_BSDTHREAD_CREATE", Const, 0}, + {"SYS_BSDTHREAD_REGISTER", Const, 0}, + {"SYS_BSDTHREAD_TERMINATE", Const, 0}, + {"SYS_CAPGET", Const, 0}, + {"SYS_CAPSET", Const, 0}, + {"SYS_CAP_ENTER", Const, 0}, + {"SYS_CAP_FCNTLS_GET", Const, 1}, + {"SYS_CAP_FCNTLS_LIMIT", Const, 1}, + {"SYS_CAP_GETMODE", Const, 0}, + {"SYS_CAP_GETRIGHTS", Const, 0}, + {"SYS_CAP_IOCTLS_GET", Const, 1}, + {"SYS_CAP_IOCTLS_LIMIT", Const, 1}, + {"SYS_CAP_NEW", Const, 0}, + {"SYS_CAP_RIGHTS_GET", Const, 1}, + {"SYS_CAP_RIGHTS_LIMIT", Const, 1}, + {"SYS_CHDIR", Const, 0}, + {"SYS_CHFLAGS", Const, 0}, + {"SYS_CHFLAGSAT", Const, 3}, + {"SYS_CHMOD", Const, 0}, + {"SYS_CHMOD_EXTENDED", Const, 0}, + {"SYS_CHOWN", Const, 0}, + {"SYS_CHOWN32", Const, 0}, + {"SYS_CHROOT", Const, 0}, + {"SYS_CHUD", Const, 0}, + {"SYS_CLOCK_ADJTIME", Const, 0}, + {"SYS_CLOCK_GETCPUCLOCKID2", Const, 1}, + {"SYS_CLOCK_GETRES", Const, 0}, + {"SYS_CLOCK_GETTIME", Const, 0}, + {"SYS_CLOCK_NANOSLEEP", Const, 0}, + {"SYS_CLOCK_SETTIME", Const, 0}, + {"SYS_CLONE", Const, 0}, + {"SYS_CLOSE", Const, 0}, + {"SYS_CLOSEFROM", Const, 0}, + {"SYS_CLOSE_NOCANCEL", Const, 0}, + {"SYS_CONNECT", Const, 0}, + {"SYS_CONNECTAT", Const, 3}, + {"SYS_CONNECT_NOCANCEL", Const, 0}, + {"SYS_COPYFILE", Const, 0}, + {"SYS_CPUSET", Const, 0}, + {"SYS_CPUSET_GETAFFINITY", Const, 0}, + {"SYS_CPUSET_GETID", Const, 0}, + {"SYS_CPUSET_SETAFFINITY", Const, 0}, + {"SYS_CPUSET_SETID", Const, 0}, + {"SYS_CREAT", Const, 0}, + {"SYS_CREATE_MODULE", Const, 0}, + {"SYS_CSOPS", Const, 0}, + {"SYS_CSOPS_AUDITTOKEN", Const, 16}, + {"SYS_DELETE", Const, 0}, + {"SYS_DELETE_MODULE", Const, 0}, + {"SYS_DUP", Const, 0}, + {"SYS_DUP2", Const, 0}, + {"SYS_DUP3", Const, 0}, + {"SYS_EACCESS", Const, 0}, + {"SYS_EPOLL_CREATE", Const, 0}, + {"SYS_EPOLL_CREATE1", Const, 0}, + {"SYS_EPOLL_CTL", Const, 0}, + {"SYS_EPOLL_CTL_OLD", Const, 0}, + {"SYS_EPOLL_PWAIT", Const, 0}, + {"SYS_EPOLL_WAIT", Const, 0}, + {"SYS_EPOLL_WAIT_OLD", Const, 0}, + {"SYS_EVENTFD", Const, 0}, + {"SYS_EVENTFD2", Const, 0}, + {"SYS_EXCHANGEDATA", Const, 0}, + {"SYS_EXECVE", Const, 0}, + {"SYS_EXIT", Const, 0}, + {"SYS_EXIT_GROUP", Const, 0}, + {"SYS_EXTATTRCTL", Const, 0}, + {"SYS_EXTATTR_DELETE_FD", Const, 0}, + {"SYS_EXTATTR_DELETE_FILE", Const, 0}, + {"SYS_EXTATTR_DELETE_LINK", Const, 0}, + {"SYS_EXTATTR_GET_FD", Const, 0}, + {"SYS_EXTATTR_GET_FILE", Const, 0}, + {"SYS_EXTATTR_GET_LINK", Const, 0}, + {"SYS_EXTATTR_LIST_FD", Const, 0}, + {"SYS_EXTATTR_LIST_FILE", Const, 0}, + {"SYS_EXTATTR_LIST_LINK", Const, 0}, + {"SYS_EXTATTR_SET_FD", Const, 0}, + {"SYS_EXTATTR_SET_FILE", Const, 0}, + {"SYS_EXTATTR_SET_LINK", Const, 0}, + {"SYS_FACCESSAT", Const, 0}, + {"SYS_FADVISE64", Const, 0}, + {"SYS_FADVISE64_64", Const, 0}, + {"SYS_FALLOCATE", Const, 0}, + {"SYS_FANOTIFY_INIT", Const, 0}, + {"SYS_FANOTIFY_MARK", Const, 0}, + {"SYS_FCHDIR", Const, 0}, + {"SYS_FCHFLAGS", Const, 0}, + {"SYS_FCHMOD", Const, 0}, + {"SYS_FCHMODAT", Const, 0}, + {"SYS_FCHMOD_EXTENDED", Const, 0}, + {"SYS_FCHOWN", Const, 0}, + {"SYS_FCHOWN32", Const, 0}, + {"SYS_FCHOWNAT", Const, 0}, + {"SYS_FCHROOT", Const, 1}, + {"SYS_FCNTL", Const, 0}, + {"SYS_FCNTL64", Const, 0}, + {"SYS_FCNTL_NOCANCEL", Const, 0}, + {"SYS_FDATASYNC", Const, 0}, + {"SYS_FEXECVE", Const, 0}, + {"SYS_FFCLOCK_GETCOUNTER", Const, 0}, + {"SYS_FFCLOCK_GETESTIMATE", Const, 0}, + {"SYS_FFCLOCK_SETESTIMATE", Const, 0}, + {"SYS_FFSCTL", Const, 0}, + {"SYS_FGETATTRLIST", Const, 0}, + {"SYS_FGETXATTR", Const, 0}, + {"SYS_FHOPEN", Const, 0}, + {"SYS_FHSTAT", Const, 0}, + {"SYS_FHSTATFS", Const, 0}, + {"SYS_FILEPORT_MAKEFD", Const, 0}, + {"SYS_FILEPORT_MAKEPORT", Const, 0}, + {"SYS_FKTRACE", Const, 1}, + {"SYS_FLISTXATTR", Const, 0}, + {"SYS_FLOCK", Const, 0}, + {"SYS_FORK", Const, 0}, + {"SYS_FPATHCONF", Const, 0}, + {"SYS_FREEBSD6_FTRUNCATE", Const, 0}, + {"SYS_FREEBSD6_LSEEK", Const, 0}, + {"SYS_FREEBSD6_MMAP", Const, 0}, + {"SYS_FREEBSD6_PREAD", Const, 0}, + {"SYS_FREEBSD6_PWRITE", Const, 0}, + {"SYS_FREEBSD6_TRUNCATE", Const, 0}, + {"SYS_FREMOVEXATTR", Const, 0}, + {"SYS_FSCTL", Const, 0}, + {"SYS_FSETATTRLIST", Const, 0}, + {"SYS_FSETXATTR", Const, 0}, + {"SYS_FSGETPATH", Const, 0}, + {"SYS_FSTAT", Const, 0}, + {"SYS_FSTAT64", Const, 0}, + {"SYS_FSTAT64_EXTENDED", Const, 0}, + {"SYS_FSTATAT", Const, 0}, + {"SYS_FSTATAT64", Const, 0}, + {"SYS_FSTATFS", Const, 0}, + {"SYS_FSTATFS64", Const, 0}, + {"SYS_FSTATV", Const, 0}, + {"SYS_FSTATVFS1", Const, 1}, + {"SYS_FSTAT_EXTENDED", Const, 0}, + {"SYS_FSYNC", Const, 0}, + {"SYS_FSYNC_NOCANCEL", Const, 0}, + {"SYS_FSYNC_RANGE", Const, 1}, + {"SYS_FTIME", Const, 0}, + {"SYS_FTRUNCATE", Const, 0}, + {"SYS_FTRUNCATE64", Const, 0}, + {"SYS_FUTEX", Const, 0}, + {"SYS_FUTIMENS", Const, 1}, + {"SYS_FUTIMES", Const, 0}, + {"SYS_FUTIMESAT", Const, 0}, + {"SYS_GETATTRLIST", Const, 0}, + {"SYS_GETAUDIT", Const, 0}, + {"SYS_GETAUDIT_ADDR", Const, 0}, + {"SYS_GETAUID", Const, 0}, + {"SYS_GETCONTEXT", Const, 0}, + {"SYS_GETCPU", Const, 0}, + {"SYS_GETCWD", Const, 0}, + {"SYS_GETDENTS", Const, 0}, + {"SYS_GETDENTS64", Const, 0}, + {"SYS_GETDIRENTRIES", Const, 0}, + {"SYS_GETDIRENTRIES64", Const, 0}, + {"SYS_GETDIRENTRIESATTR", Const, 0}, + {"SYS_GETDTABLECOUNT", Const, 1}, + {"SYS_GETDTABLESIZE", Const, 0}, + {"SYS_GETEGID", Const, 0}, + {"SYS_GETEGID32", Const, 0}, + {"SYS_GETEUID", Const, 0}, + {"SYS_GETEUID32", Const, 0}, + {"SYS_GETFH", Const, 0}, + {"SYS_GETFSSTAT", Const, 0}, + {"SYS_GETFSSTAT64", Const, 0}, + {"SYS_GETGID", Const, 0}, + {"SYS_GETGID32", Const, 0}, + {"SYS_GETGROUPS", Const, 0}, + {"SYS_GETGROUPS32", Const, 0}, + {"SYS_GETHOSTUUID", Const, 0}, + {"SYS_GETITIMER", Const, 0}, + {"SYS_GETLCID", Const, 0}, + {"SYS_GETLOGIN", Const, 0}, + {"SYS_GETLOGINCLASS", Const, 0}, + {"SYS_GETPEERNAME", Const, 0}, + {"SYS_GETPGID", Const, 0}, + {"SYS_GETPGRP", Const, 0}, + {"SYS_GETPID", Const, 0}, + {"SYS_GETPMSG", Const, 0}, + {"SYS_GETPPID", Const, 0}, + {"SYS_GETPRIORITY", Const, 0}, + {"SYS_GETRESGID", Const, 0}, + {"SYS_GETRESGID32", Const, 0}, + {"SYS_GETRESUID", Const, 0}, + {"SYS_GETRESUID32", Const, 0}, + {"SYS_GETRLIMIT", Const, 0}, + {"SYS_GETRTABLE", Const, 1}, + {"SYS_GETRUSAGE", Const, 0}, + {"SYS_GETSGROUPS", Const, 0}, + {"SYS_GETSID", Const, 0}, + {"SYS_GETSOCKNAME", Const, 0}, + {"SYS_GETSOCKOPT", Const, 0}, + {"SYS_GETTHRID", Const, 1}, + {"SYS_GETTID", Const, 0}, + {"SYS_GETTIMEOFDAY", Const, 0}, + {"SYS_GETUID", Const, 0}, + {"SYS_GETUID32", Const, 0}, + {"SYS_GETVFSSTAT", Const, 1}, + {"SYS_GETWGROUPS", Const, 0}, + {"SYS_GETXATTR", Const, 0}, + {"SYS_GET_KERNEL_SYMS", Const, 0}, + {"SYS_GET_MEMPOLICY", Const, 0}, + {"SYS_GET_ROBUST_LIST", Const, 0}, + {"SYS_GET_THREAD_AREA", Const, 0}, + {"SYS_GSSD_SYSCALL", Const, 14}, + {"SYS_GTTY", Const, 0}, + {"SYS_IDENTITYSVC", Const, 0}, + {"SYS_IDLE", Const, 0}, + {"SYS_INITGROUPS", Const, 0}, + {"SYS_INIT_MODULE", Const, 0}, + {"SYS_INOTIFY_ADD_WATCH", Const, 0}, + {"SYS_INOTIFY_INIT", Const, 0}, + {"SYS_INOTIFY_INIT1", Const, 0}, + {"SYS_INOTIFY_RM_WATCH", Const, 0}, + {"SYS_IOCTL", Const, 0}, + {"SYS_IOPERM", Const, 0}, + {"SYS_IOPL", Const, 0}, + {"SYS_IOPOLICYSYS", Const, 0}, + {"SYS_IOPRIO_GET", Const, 0}, + {"SYS_IOPRIO_SET", Const, 0}, + {"SYS_IO_CANCEL", Const, 0}, + {"SYS_IO_DESTROY", Const, 0}, + {"SYS_IO_GETEVENTS", Const, 0}, + {"SYS_IO_SETUP", Const, 0}, + {"SYS_IO_SUBMIT", Const, 0}, + {"SYS_IPC", Const, 0}, + {"SYS_ISSETUGID", Const, 0}, + {"SYS_JAIL", Const, 0}, + {"SYS_JAIL_ATTACH", Const, 0}, + {"SYS_JAIL_GET", Const, 0}, + {"SYS_JAIL_REMOVE", Const, 0}, + {"SYS_JAIL_SET", Const, 0}, + {"SYS_KAS_INFO", Const, 16}, + {"SYS_KDEBUG_TRACE", Const, 0}, + {"SYS_KENV", Const, 0}, + {"SYS_KEVENT", Const, 0}, + {"SYS_KEVENT64", Const, 0}, + {"SYS_KEXEC_LOAD", Const, 0}, + {"SYS_KEYCTL", Const, 0}, + {"SYS_KILL", Const, 0}, + {"SYS_KLDFIND", Const, 0}, + {"SYS_KLDFIRSTMOD", Const, 0}, + {"SYS_KLDLOAD", Const, 0}, + {"SYS_KLDNEXT", Const, 0}, + {"SYS_KLDSTAT", Const, 0}, + {"SYS_KLDSYM", Const, 0}, + {"SYS_KLDUNLOAD", Const, 0}, + {"SYS_KLDUNLOADF", Const, 0}, + {"SYS_KMQ_NOTIFY", Const, 14}, + {"SYS_KMQ_OPEN", Const, 14}, + {"SYS_KMQ_SETATTR", Const, 14}, + {"SYS_KMQ_TIMEDRECEIVE", Const, 14}, + {"SYS_KMQ_TIMEDSEND", Const, 14}, + {"SYS_KMQ_UNLINK", Const, 14}, + {"SYS_KQUEUE", Const, 0}, + {"SYS_KQUEUE1", Const, 1}, + {"SYS_KSEM_CLOSE", Const, 14}, + {"SYS_KSEM_DESTROY", Const, 14}, + {"SYS_KSEM_GETVALUE", Const, 14}, + {"SYS_KSEM_INIT", Const, 14}, + {"SYS_KSEM_OPEN", Const, 14}, + {"SYS_KSEM_POST", Const, 14}, + {"SYS_KSEM_TIMEDWAIT", Const, 14}, + {"SYS_KSEM_TRYWAIT", Const, 14}, + {"SYS_KSEM_UNLINK", Const, 14}, + {"SYS_KSEM_WAIT", Const, 14}, + {"SYS_KTIMER_CREATE", Const, 0}, + {"SYS_KTIMER_DELETE", Const, 0}, + {"SYS_KTIMER_GETOVERRUN", Const, 0}, + {"SYS_KTIMER_GETTIME", Const, 0}, + {"SYS_KTIMER_SETTIME", Const, 0}, + {"SYS_KTRACE", Const, 0}, + {"SYS_LCHFLAGS", Const, 0}, + {"SYS_LCHMOD", Const, 0}, + {"SYS_LCHOWN", Const, 0}, + {"SYS_LCHOWN32", Const, 0}, + {"SYS_LEDGER", Const, 16}, + {"SYS_LGETFH", Const, 0}, + {"SYS_LGETXATTR", Const, 0}, + {"SYS_LINK", Const, 0}, + {"SYS_LINKAT", Const, 0}, + {"SYS_LIO_LISTIO", Const, 0}, + {"SYS_LISTEN", Const, 0}, + {"SYS_LISTXATTR", Const, 0}, + {"SYS_LLISTXATTR", Const, 0}, + {"SYS_LOCK", Const, 0}, + {"SYS_LOOKUP_DCOOKIE", Const, 0}, + {"SYS_LPATHCONF", Const, 0}, + {"SYS_LREMOVEXATTR", Const, 0}, + {"SYS_LSEEK", Const, 0}, + {"SYS_LSETXATTR", Const, 0}, + {"SYS_LSTAT", Const, 0}, + {"SYS_LSTAT64", Const, 0}, + {"SYS_LSTAT64_EXTENDED", Const, 0}, + {"SYS_LSTATV", Const, 0}, + {"SYS_LSTAT_EXTENDED", Const, 0}, + {"SYS_LUTIMES", Const, 0}, + {"SYS_MAC_SYSCALL", Const, 0}, + {"SYS_MADVISE", Const, 0}, + {"SYS_MADVISE1", Const, 0}, + {"SYS_MAXSYSCALL", Const, 0}, + {"SYS_MBIND", Const, 0}, + {"SYS_MIGRATE_PAGES", Const, 0}, + {"SYS_MINCORE", Const, 0}, + {"SYS_MINHERIT", Const, 0}, + {"SYS_MKCOMPLEX", Const, 0}, + {"SYS_MKDIR", Const, 0}, + {"SYS_MKDIRAT", Const, 0}, + {"SYS_MKDIR_EXTENDED", Const, 0}, + {"SYS_MKFIFO", Const, 0}, + {"SYS_MKFIFOAT", Const, 0}, + {"SYS_MKFIFO_EXTENDED", Const, 0}, + {"SYS_MKNOD", Const, 0}, + {"SYS_MKNODAT", Const, 0}, + {"SYS_MLOCK", Const, 0}, + {"SYS_MLOCKALL", Const, 0}, + {"SYS_MMAP", Const, 0}, + {"SYS_MMAP2", Const, 0}, + {"SYS_MODCTL", Const, 1}, + {"SYS_MODFIND", Const, 0}, + {"SYS_MODFNEXT", Const, 0}, + {"SYS_MODIFY_LDT", Const, 0}, + {"SYS_MODNEXT", Const, 0}, + {"SYS_MODSTAT", Const, 0}, + {"SYS_MODWATCH", Const, 0}, + {"SYS_MOUNT", Const, 0}, + {"SYS_MOVE_PAGES", Const, 0}, + {"SYS_MPROTECT", Const, 0}, + {"SYS_MPX", Const, 0}, + {"SYS_MQUERY", Const, 1}, + {"SYS_MQ_GETSETATTR", Const, 0}, + {"SYS_MQ_NOTIFY", Const, 0}, + {"SYS_MQ_OPEN", Const, 0}, + {"SYS_MQ_TIMEDRECEIVE", Const, 0}, + {"SYS_MQ_TIMEDSEND", Const, 0}, + {"SYS_MQ_UNLINK", Const, 0}, + {"SYS_MREMAP", Const, 0}, + {"SYS_MSGCTL", Const, 0}, + {"SYS_MSGGET", Const, 0}, + {"SYS_MSGRCV", Const, 0}, + {"SYS_MSGRCV_NOCANCEL", Const, 0}, + {"SYS_MSGSND", Const, 0}, + {"SYS_MSGSND_NOCANCEL", Const, 0}, + {"SYS_MSGSYS", Const, 0}, + {"SYS_MSYNC", Const, 0}, + {"SYS_MSYNC_NOCANCEL", Const, 0}, + {"SYS_MUNLOCK", Const, 0}, + {"SYS_MUNLOCKALL", Const, 0}, + {"SYS_MUNMAP", Const, 0}, + {"SYS_NAME_TO_HANDLE_AT", Const, 0}, + {"SYS_NANOSLEEP", Const, 0}, + {"SYS_NEWFSTATAT", Const, 0}, + {"SYS_NFSCLNT", Const, 0}, + {"SYS_NFSSERVCTL", Const, 0}, + {"SYS_NFSSVC", Const, 0}, + {"SYS_NFSTAT", Const, 0}, + {"SYS_NICE", Const, 0}, + {"SYS_NLM_SYSCALL", Const, 14}, + {"SYS_NLSTAT", Const, 0}, + {"SYS_NMOUNT", Const, 0}, + {"SYS_NSTAT", Const, 0}, + {"SYS_NTP_ADJTIME", Const, 0}, + {"SYS_NTP_GETTIME", Const, 0}, + {"SYS_NUMA_GETAFFINITY", Const, 14}, + {"SYS_NUMA_SETAFFINITY", Const, 14}, + {"SYS_OABI_SYSCALL_BASE", Const, 0}, + {"SYS_OBREAK", Const, 0}, + {"SYS_OLDFSTAT", Const, 0}, + {"SYS_OLDLSTAT", Const, 0}, + {"SYS_OLDOLDUNAME", Const, 0}, + {"SYS_OLDSTAT", Const, 0}, + {"SYS_OLDUNAME", Const, 0}, + {"SYS_OPEN", Const, 0}, + {"SYS_OPENAT", Const, 0}, + {"SYS_OPENBSD_POLL", Const, 0}, + {"SYS_OPEN_BY_HANDLE_AT", Const, 0}, + {"SYS_OPEN_DPROTECTED_NP", Const, 16}, + {"SYS_OPEN_EXTENDED", Const, 0}, + {"SYS_OPEN_NOCANCEL", Const, 0}, + {"SYS_OVADVISE", Const, 0}, + {"SYS_PACCEPT", Const, 1}, + {"SYS_PATHCONF", Const, 0}, + {"SYS_PAUSE", Const, 0}, + {"SYS_PCICONFIG_IOBASE", Const, 0}, + {"SYS_PCICONFIG_READ", Const, 0}, + {"SYS_PCICONFIG_WRITE", Const, 0}, + {"SYS_PDFORK", Const, 0}, + {"SYS_PDGETPID", Const, 0}, + {"SYS_PDKILL", Const, 0}, + {"SYS_PERF_EVENT_OPEN", Const, 0}, + {"SYS_PERSONALITY", Const, 0}, + {"SYS_PID_HIBERNATE", Const, 0}, + {"SYS_PID_RESUME", Const, 0}, + {"SYS_PID_SHUTDOWN_SOCKETS", Const, 0}, + {"SYS_PID_SUSPEND", Const, 0}, + {"SYS_PIPE", Const, 0}, + {"SYS_PIPE2", Const, 0}, + {"SYS_PIVOT_ROOT", Const, 0}, + {"SYS_PMC_CONTROL", Const, 1}, + {"SYS_PMC_GET_INFO", Const, 1}, + {"SYS_POLL", Const, 0}, + {"SYS_POLLTS", Const, 1}, + {"SYS_POLL_NOCANCEL", Const, 0}, + {"SYS_POSIX_FADVISE", Const, 0}, + {"SYS_POSIX_FALLOCATE", Const, 0}, + {"SYS_POSIX_OPENPT", Const, 0}, + {"SYS_POSIX_SPAWN", Const, 0}, + {"SYS_PPOLL", Const, 0}, + {"SYS_PRCTL", Const, 0}, + {"SYS_PREAD", Const, 0}, + {"SYS_PREAD64", Const, 0}, + {"SYS_PREADV", Const, 0}, + {"SYS_PREAD_NOCANCEL", Const, 0}, + {"SYS_PRLIMIT64", Const, 0}, + {"SYS_PROCCTL", Const, 3}, + {"SYS_PROCESS_POLICY", Const, 0}, + {"SYS_PROCESS_VM_READV", Const, 0}, + {"SYS_PROCESS_VM_WRITEV", Const, 0}, + {"SYS_PROC_INFO", Const, 0}, + {"SYS_PROF", Const, 0}, + {"SYS_PROFIL", Const, 0}, + {"SYS_PSELECT", Const, 0}, + {"SYS_PSELECT6", Const, 0}, + {"SYS_PSET_ASSIGN", Const, 1}, + {"SYS_PSET_CREATE", Const, 1}, + {"SYS_PSET_DESTROY", Const, 1}, + {"SYS_PSYNCH_CVBROAD", Const, 0}, + {"SYS_PSYNCH_CVCLRPREPOST", Const, 0}, + {"SYS_PSYNCH_CVSIGNAL", Const, 0}, + {"SYS_PSYNCH_CVWAIT", Const, 0}, + {"SYS_PSYNCH_MUTEXDROP", Const, 0}, + {"SYS_PSYNCH_MUTEXWAIT", Const, 0}, + {"SYS_PSYNCH_RW_DOWNGRADE", Const, 0}, + {"SYS_PSYNCH_RW_LONGRDLOCK", Const, 0}, + {"SYS_PSYNCH_RW_RDLOCK", Const, 0}, + {"SYS_PSYNCH_RW_UNLOCK", Const, 0}, + {"SYS_PSYNCH_RW_UNLOCK2", Const, 0}, + {"SYS_PSYNCH_RW_UPGRADE", Const, 0}, + {"SYS_PSYNCH_RW_WRLOCK", Const, 0}, + {"SYS_PSYNCH_RW_YIELDWRLOCK", Const, 0}, + {"SYS_PTRACE", Const, 0}, + {"SYS_PUTPMSG", Const, 0}, + {"SYS_PWRITE", Const, 0}, + {"SYS_PWRITE64", Const, 0}, + {"SYS_PWRITEV", Const, 0}, + {"SYS_PWRITE_NOCANCEL", Const, 0}, + {"SYS_QUERY_MODULE", Const, 0}, + {"SYS_QUOTACTL", Const, 0}, + {"SYS_RASCTL", Const, 1}, + {"SYS_RCTL_ADD_RULE", Const, 0}, + {"SYS_RCTL_GET_LIMITS", Const, 0}, + {"SYS_RCTL_GET_RACCT", Const, 0}, + {"SYS_RCTL_GET_RULES", Const, 0}, + {"SYS_RCTL_REMOVE_RULE", Const, 0}, + {"SYS_READ", Const, 0}, + {"SYS_READAHEAD", Const, 0}, + {"SYS_READDIR", Const, 0}, + {"SYS_READLINK", Const, 0}, + {"SYS_READLINKAT", Const, 0}, + {"SYS_READV", Const, 0}, + {"SYS_READV_NOCANCEL", Const, 0}, + {"SYS_READ_NOCANCEL", Const, 0}, + {"SYS_REBOOT", Const, 0}, + {"SYS_RECV", Const, 0}, + {"SYS_RECVFROM", Const, 0}, + {"SYS_RECVFROM_NOCANCEL", Const, 0}, + {"SYS_RECVMMSG", Const, 0}, + {"SYS_RECVMSG", Const, 0}, + {"SYS_RECVMSG_NOCANCEL", Const, 0}, + {"SYS_REMAP_FILE_PAGES", Const, 0}, + {"SYS_REMOVEXATTR", Const, 0}, + {"SYS_RENAME", Const, 0}, + {"SYS_RENAMEAT", Const, 0}, + {"SYS_REQUEST_KEY", Const, 0}, + {"SYS_RESTART_SYSCALL", Const, 0}, + {"SYS_REVOKE", Const, 0}, + {"SYS_RFORK", Const, 0}, + {"SYS_RMDIR", Const, 0}, + {"SYS_RTPRIO", Const, 0}, + {"SYS_RTPRIO_THREAD", Const, 0}, + {"SYS_RT_SIGACTION", Const, 0}, + {"SYS_RT_SIGPENDING", Const, 0}, + {"SYS_RT_SIGPROCMASK", Const, 0}, + {"SYS_RT_SIGQUEUEINFO", Const, 0}, + {"SYS_RT_SIGRETURN", Const, 0}, + {"SYS_RT_SIGSUSPEND", Const, 0}, + {"SYS_RT_SIGTIMEDWAIT", Const, 0}, + {"SYS_RT_TGSIGQUEUEINFO", Const, 0}, + {"SYS_SBRK", Const, 0}, + {"SYS_SCHED_GETAFFINITY", Const, 0}, + {"SYS_SCHED_GETPARAM", Const, 0}, + {"SYS_SCHED_GETSCHEDULER", Const, 0}, + {"SYS_SCHED_GET_PRIORITY_MAX", Const, 0}, + {"SYS_SCHED_GET_PRIORITY_MIN", Const, 0}, + {"SYS_SCHED_RR_GET_INTERVAL", Const, 0}, + {"SYS_SCHED_SETAFFINITY", Const, 0}, + {"SYS_SCHED_SETPARAM", Const, 0}, + {"SYS_SCHED_SETSCHEDULER", Const, 0}, + {"SYS_SCHED_YIELD", Const, 0}, + {"SYS_SCTP_GENERIC_RECVMSG", Const, 0}, + {"SYS_SCTP_GENERIC_SENDMSG", Const, 0}, + {"SYS_SCTP_GENERIC_SENDMSG_IOV", Const, 0}, + {"SYS_SCTP_PEELOFF", Const, 0}, + {"SYS_SEARCHFS", Const, 0}, + {"SYS_SECURITY", Const, 0}, + {"SYS_SELECT", Const, 0}, + {"SYS_SELECT_NOCANCEL", Const, 0}, + {"SYS_SEMCONFIG", Const, 1}, + {"SYS_SEMCTL", Const, 0}, + {"SYS_SEMGET", Const, 0}, + {"SYS_SEMOP", Const, 0}, + {"SYS_SEMSYS", Const, 0}, + {"SYS_SEMTIMEDOP", Const, 0}, + {"SYS_SEM_CLOSE", Const, 0}, + {"SYS_SEM_DESTROY", Const, 0}, + {"SYS_SEM_GETVALUE", Const, 0}, + {"SYS_SEM_INIT", Const, 0}, + {"SYS_SEM_OPEN", Const, 0}, + {"SYS_SEM_POST", Const, 0}, + {"SYS_SEM_TRYWAIT", Const, 0}, + {"SYS_SEM_UNLINK", Const, 0}, + {"SYS_SEM_WAIT", Const, 0}, + {"SYS_SEM_WAIT_NOCANCEL", Const, 0}, + {"SYS_SEND", Const, 0}, + {"SYS_SENDFILE", Const, 0}, + {"SYS_SENDFILE64", Const, 0}, + {"SYS_SENDMMSG", Const, 0}, + {"SYS_SENDMSG", Const, 0}, + {"SYS_SENDMSG_NOCANCEL", Const, 0}, + {"SYS_SENDTO", Const, 0}, + {"SYS_SENDTO_NOCANCEL", Const, 0}, + {"SYS_SETATTRLIST", Const, 0}, + {"SYS_SETAUDIT", Const, 0}, + {"SYS_SETAUDIT_ADDR", Const, 0}, + {"SYS_SETAUID", Const, 0}, + {"SYS_SETCONTEXT", Const, 0}, + {"SYS_SETDOMAINNAME", Const, 0}, + {"SYS_SETEGID", Const, 0}, + {"SYS_SETEUID", Const, 0}, + {"SYS_SETFIB", Const, 0}, + {"SYS_SETFSGID", Const, 0}, + {"SYS_SETFSGID32", Const, 0}, + {"SYS_SETFSUID", Const, 0}, + {"SYS_SETFSUID32", Const, 0}, + {"SYS_SETGID", Const, 0}, + {"SYS_SETGID32", Const, 0}, + {"SYS_SETGROUPS", Const, 0}, + {"SYS_SETGROUPS32", Const, 0}, + {"SYS_SETHOSTNAME", Const, 0}, + {"SYS_SETITIMER", Const, 0}, + {"SYS_SETLCID", Const, 0}, + {"SYS_SETLOGIN", Const, 0}, + {"SYS_SETLOGINCLASS", Const, 0}, + {"SYS_SETNS", Const, 0}, + {"SYS_SETPGID", Const, 0}, + {"SYS_SETPRIORITY", Const, 0}, + {"SYS_SETPRIVEXEC", Const, 0}, + {"SYS_SETREGID", Const, 0}, + {"SYS_SETREGID32", Const, 0}, + {"SYS_SETRESGID", Const, 0}, + {"SYS_SETRESGID32", Const, 0}, + {"SYS_SETRESUID", Const, 0}, + {"SYS_SETRESUID32", Const, 0}, + {"SYS_SETREUID", Const, 0}, + {"SYS_SETREUID32", Const, 0}, + {"SYS_SETRLIMIT", Const, 0}, + {"SYS_SETRTABLE", Const, 1}, + {"SYS_SETSGROUPS", Const, 0}, + {"SYS_SETSID", Const, 0}, + {"SYS_SETSOCKOPT", Const, 0}, + {"SYS_SETTID", Const, 0}, + {"SYS_SETTID_WITH_PID", Const, 0}, + {"SYS_SETTIMEOFDAY", Const, 0}, + {"SYS_SETUID", Const, 0}, + {"SYS_SETUID32", Const, 0}, + {"SYS_SETWGROUPS", Const, 0}, + {"SYS_SETXATTR", Const, 0}, + {"SYS_SET_MEMPOLICY", Const, 0}, + {"SYS_SET_ROBUST_LIST", Const, 0}, + {"SYS_SET_THREAD_AREA", Const, 0}, + {"SYS_SET_TID_ADDRESS", Const, 0}, + {"SYS_SGETMASK", Const, 0}, + {"SYS_SHARED_REGION_CHECK_NP", Const, 0}, + {"SYS_SHARED_REGION_MAP_AND_SLIDE_NP", Const, 0}, + {"SYS_SHMAT", Const, 0}, + {"SYS_SHMCTL", Const, 0}, + {"SYS_SHMDT", Const, 0}, + {"SYS_SHMGET", Const, 0}, + {"SYS_SHMSYS", Const, 0}, + {"SYS_SHM_OPEN", Const, 0}, + {"SYS_SHM_UNLINK", Const, 0}, + {"SYS_SHUTDOWN", Const, 0}, + {"SYS_SIGACTION", Const, 0}, + {"SYS_SIGALTSTACK", Const, 0}, + {"SYS_SIGNAL", Const, 0}, + {"SYS_SIGNALFD", Const, 0}, + {"SYS_SIGNALFD4", Const, 0}, + {"SYS_SIGPENDING", Const, 0}, + {"SYS_SIGPROCMASK", Const, 0}, + {"SYS_SIGQUEUE", Const, 0}, + {"SYS_SIGQUEUEINFO", Const, 1}, + {"SYS_SIGRETURN", Const, 0}, + {"SYS_SIGSUSPEND", Const, 0}, + {"SYS_SIGSUSPEND_NOCANCEL", Const, 0}, + {"SYS_SIGTIMEDWAIT", Const, 0}, + {"SYS_SIGWAIT", Const, 0}, + {"SYS_SIGWAITINFO", Const, 0}, + {"SYS_SOCKET", Const, 0}, + {"SYS_SOCKETCALL", Const, 0}, + {"SYS_SOCKETPAIR", Const, 0}, + {"SYS_SPLICE", Const, 0}, + {"SYS_SSETMASK", Const, 0}, + {"SYS_SSTK", Const, 0}, + {"SYS_STACK_SNAPSHOT", Const, 0}, + {"SYS_STAT", Const, 0}, + {"SYS_STAT64", Const, 0}, + {"SYS_STAT64_EXTENDED", Const, 0}, + {"SYS_STATFS", Const, 0}, + {"SYS_STATFS64", Const, 0}, + {"SYS_STATV", Const, 0}, + {"SYS_STATVFS1", Const, 1}, + {"SYS_STAT_EXTENDED", Const, 0}, + {"SYS_STIME", Const, 0}, + {"SYS_STTY", Const, 0}, + {"SYS_SWAPCONTEXT", Const, 0}, + {"SYS_SWAPCTL", Const, 1}, + {"SYS_SWAPOFF", Const, 0}, + {"SYS_SWAPON", Const, 0}, + {"SYS_SYMLINK", Const, 0}, + {"SYS_SYMLINKAT", Const, 0}, + {"SYS_SYNC", Const, 0}, + {"SYS_SYNCFS", Const, 0}, + {"SYS_SYNC_FILE_RANGE", Const, 0}, + {"SYS_SYSARCH", Const, 0}, + {"SYS_SYSCALL", Const, 0}, + {"SYS_SYSCALL_BASE", Const, 0}, + {"SYS_SYSFS", Const, 0}, + {"SYS_SYSINFO", Const, 0}, + {"SYS_SYSLOG", Const, 0}, + {"SYS_TEE", Const, 0}, + {"SYS_TGKILL", Const, 0}, + {"SYS_THREAD_SELFID", Const, 0}, + {"SYS_THR_CREATE", Const, 0}, + {"SYS_THR_EXIT", Const, 0}, + {"SYS_THR_KILL", Const, 0}, + {"SYS_THR_KILL2", Const, 0}, + {"SYS_THR_NEW", Const, 0}, + {"SYS_THR_SELF", Const, 0}, + {"SYS_THR_SET_NAME", Const, 0}, + {"SYS_THR_SUSPEND", Const, 0}, + {"SYS_THR_WAKE", Const, 0}, + {"SYS_TIME", Const, 0}, + {"SYS_TIMERFD_CREATE", Const, 0}, + {"SYS_TIMERFD_GETTIME", Const, 0}, + {"SYS_TIMERFD_SETTIME", Const, 0}, + {"SYS_TIMER_CREATE", Const, 0}, + {"SYS_TIMER_DELETE", Const, 0}, + {"SYS_TIMER_GETOVERRUN", Const, 0}, + {"SYS_TIMER_GETTIME", Const, 0}, + {"SYS_TIMER_SETTIME", Const, 0}, + {"SYS_TIMES", Const, 0}, + {"SYS_TKILL", Const, 0}, + {"SYS_TRUNCATE", Const, 0}, + {"SYS_TRUNCATE64", Const, 0}, + {"SYS_TUXCALL", Const, 0}, + {"SYS_UGETRLIMIT", Const, 0}, + {"SYS_ULIMIT", Const, 0}, + {"SYS_UMASK", Const, 0}, + {"SYS_UMASK_EXTENDED", Const, 0}, + {"SYS_UMOUNT", Const, 0}, + {"SYS_UMOUNT2", Const, 0}, + {"SYS_UNAME", Const, 0}, + {"SYS_UNDELETE", Const, 0}, + {"SYS_UNLINK", Const, 0}, + {"SYS_UNLINKAT", Const, 0}, + {"SYS_UNMOUNT", Const, 0}, + {"SYS_UNSHARE", Const, 0}, + {"SYS_USELIB", Const, 0}, + {"SYS_USTAT", Const, 0}, + {"SYS_UTIME", Const, 0}, + {"SYS_UTIMENSAT", Const, 0}, + {"SYS_UTIMES", Const, 0}, + {"SYS_UTRACE", Const, 0}, + {"SYS_UUIDGEN", Const, 0}, + {"SYS_VADVISE", Const, 1}, + {"SYS_VFORK", Const, 0}, + {"SYS_VHANGUP", Const, 0}, + {"SYS_VM86", Const, 0}, + {"SYS_VM86OLD", Const, 0}, + {"SYS_VMSPLICE", Const, 0}, + {"SYS_VM_PRESSURE_MONITOR", Const, 0}, + {"SYS_VSERVER", Const, 0}, + {"SYS_WAIT4", Const, 0}, + {"SYS_WAIT4_NOCANCEL", Const, 0}, + {"SYS_WAIT6", Const, 1}, + {"SYS_WAITEVENT", Const, 0}, + {"SYS_WAITID", Const, 0}, + {"SYS_WAITID_NOCANCEL", Const, 0}, + {"SYS_WAITPID", Const, 0}, + {"SYS_WATCHEVENT", Const, 0}, + {"SYS_WORKQ_KERNRETURN", Const, 0}, + {"SYS_WORKQ_OPEN", Const, 0}, + {"SYS_WRITE", Const, 0}, + {"SYS_WRITEV", Const, 0}, + {"SYS_WRITEV_NOCANCEL", Const, 0}, + {"SYS_WRITE_NOCANCEL", Const, 0}, + {"SYS_YIELD", Const, 0}, + {"SYS__LLSEEK", Const, 0}, + {"SYS__LWP_CONTINUE", Const, 1}, + {"SYS__LWP_CREATE", Const, 1}, + {"SYS__LWP_CTL", Const, 1}, + {"SYS__LWP_DETACH", Const, 1}, + {"SYS__LWP_EXIT", Const, 1}, + {"SYS__LWP_GETNAME", Const, 1}, + {"SYS__LWP_GETPRIVATE", Const, 1}, + {"SYS__LWP_KILL", Const, 1}, + {"SYS__LWP_PARK", Const, 1}, + {"SYS__LWP_SELF", Const, 1}, + {"SYS__LWP_SETNAME", Const, 1}, + {"SYS__LWP_SETPRIVATE", Const, 1}, + {"SYS__LWP_SUSPEND", Const, 1}, + {"SYS__LWP_UNPARK", Const, 1}, + {"SYS__LWP_UNPARK_ALL", Const, 1}, + {"SYS__LWP_WAIT", Const, 1}, + {"SYS__LWP_WAKEUP", Const, 1}, + {"SYS__NEWSELECT", Const, 0}, + {"SYS__PSET_BIND", Const, 1}, + {"SYS__SCHED_GETAFFINITY", Const, 1}, + {"SYS__SCHED_GETPARAM", Const, 1}, + {"SYS__SCHED_SETAFFINITY", Const, 1}, + {"SYS__SCHED_SETPARAM", Const, 1}, + {"SYS__SYSCTL", Const, 0}, + {"SYS__UMTX_LOCK", Const, 0}, + {"SYS__UMTX_OP", Const, 0}, + {"SYS__UMTX_UNLOCK", Const, 0}, + {"SYS___ACL_ACLCHECK_FD", Const, 0}, + {"SYS___ACL_ACLCHECK_FILE", Const, 0}, + {"SYS___ACL_ACLCHECK_LINK", Const, 0}, + {"SYS___ACL_DELETE_FD", Const, 0}, + {"SYS___ACL_DELETE_FILE", Const, 0}, + {"SYS___ACL_DELETE_LINK", Const, 0}, + {"SYS___ACL_GET_FD", Const, 0}, + {"SYS___ACL_GET_FILE", Const, 0}, + {"SYS___ACL_GET_LINK", Const, 0}, + {"SYS___ACL_SET_FD", Const, 0}, + {"SYS___ACL_SET_FILE", Const, 0}, + {"SYS___ACL_SET_LINK", Const, 0}, + {"SYS___CAP_RIGHTS_GET", Const, 14}, + {"SYS___CLONE", Const, 1}, + {"SYS___DISABLE_THREADSIGNAL", Const, 0}, + {"SYS___GETCWD", Const, 0}, + {"SYS___GETLOGIN", Const, 1}, + {"SYS___GET_TCB", Const, 1}, + {"SYS___MAC_EXECVE", Const, 0}, + {"SYS___MAC_GETFSSTAT", Const, 0}, + {"SYS___MAC_GET_FD", Const, 0}, + {"SYS___MAC_GET_FILE", Const, 0}, + {"SYS___MAC_GET_LCID", Const, 0}, + {"SYS___MAC_GET_LCTX", Const, 0}, + {"SYS___MAC_GET_LINK", Const, 0}, + {"SYS___MAC_GET_MOUNT", Const, 0}, + {"SYS___MAC_GET_PID", Const, 0}, + {"SYS___MAC_GET_PROC", Const, 0}, + {"SYS___MAC_MOUNT", Const, 0}, + {"SYS___MAC_SET_FD", Const, 0}, + {"SYS___MAC_SET_FILE", Const, 0}, + {"SYS___MAC_SET_LCTX", Const, 0}, + {"SYS___MAC_SET_LINK", Const, 0}, + {"SYS___MAC_SET_PROC", Const, 0}, + {"SYS___MAC_SYSCALL", Const, 0}, + {"SYS___OLD_SEMWAIT_SIGNAL", Const, 0}, + {"SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL", Const, 0}, + {"SYS___POSIX_CHOWN", Const, 1}, + {"SYS___POSIX_FCHOWN", Const, 1}, + {"SYS___POSIX_LCHOWN", Const, 1}, + {"SYS___POSIX_RENAME", Const, 1}, + {"SYS___PTHREAD_CANCELED", Const, 0}, + {"SYS___PTHREAD_CHDIR", Const, 0}, + {"SYS___PTHREAD_FCHDIR", Const, 0}, + {"SYS___PTHREAD_KILL", Const, 0}, + {"SYS___PTHREAD_MARKCANCEL", Const, 0}, + {"SYS___PTHREAD_SIGMASK", Const, 0}, + {"SYS___QUOTACTL", Const, 1}, + {"SYS___SEMCTL", Const, 1}, + {"SYS___SEMWAIT_SIGNAL", Const, 0}, + {"SYS___SEMWAIT_SIGNAL_NOCANCEL", Const, 0}, + {"SYS___SETLOGIN", Const, 1}, + {"SYS___SETUGID", Const, 0}, + {"SYS___SET_TCB", Const, 1}, + {"SYS___SIGACTION_SIGTRAMP", Const, 1}, + {"SYS___SIGTIMEDWAIT", Const, 1}, + {"SYS___SIGWAIT", Const, 0}, + {"SYS___SIGWAIT_NOCANCEL", Const, 0}, + {"SYS___SYSCTL", Const, 0}, + {"SYS___TFORK", Const, 1}, + {"SYS___THREXIT", Const, 1}, + {"SYS___THRSIGDIVERT", Const, 1}, + {"SYS___THRSLEEP", Const, 1}, + {"SYS___THRWAKEUP", Const, 1}, + {"S_ARCH1", Const, 1}, + {"S_ARCH2", Const, 1}, + {"S_BLKSIZE", Const, 0}, + {"S_IEXEC", Const, 0}, + {"S_IFBLK", Const, 0}, + {"S_IFCHR", Const, 0}, + {"S_IFDIR", Const, 0}, + {"S_IFIFO", Const, 0}, + {"S_IFLNK", Const, 0}, + {"S_IFMT", Const, 0}, + {"S_IFREG", Const, 0}, + {"S_IFSOCK", Const, 0}, + {"S_IFWHT", Const, 0}, + {"S_IREAD", Const, 0}, + {"S_IRGRP", Const, 0}, + {"S_IROTH", Const, 0}, + {"S_IRUSR", Const, 0}, + {"S_IRWXG", Const, 0}, + {"S_IRWXO", Const, 0}, + {"S_IRWXU", Const, 0}, + {"S_ISGID", Const, 0}, + {"S_ISTXT", Const, 0}, + {"S_ISUID", Const, 0}, + {"S_ISVTX", Const, 0}, + {"S_IWGRP", Const, 0}, + {"S_IWOTH", Const, 0}, + {"S_IWRITE", Const, 0}, + {"S_IWUSR", Const, 0}, + {"S_IXGRP", Const, 0}, + {"S_IXOTH", Const, 0}, + {"S_IXUSR", Const, 0}, + {"S_LOGIN_SET", Const, 1}, + {"SecurityAttributes", Type, 0}, + {"SecurityAttributes.InheritHandle", Field, 0}, + {"SecurityAttributes.Length", Field, 0}, + {"SecurityAttributes.SecurityDescriptor", Field, 0}, + {"Seek", Func, 0}, + {"Select", Func, 0}, + {"Sendfile", Func, 0}, + {"Sendmsg", Func, 0}, + {"SendmsgN", Func, 3}, + {"Sendto", Func, 0}, + {"Servent", Type, 0}, + {"Servent.Aliases", Field, 0}, + {"Servent.Name", Field, 0}, + {"Servent.Port", Field, 0}, + {"Servent.Proto", Field, 0}, + {"SetBpf", Func, 0}, + {"SetBpfBuflen", Func, 0}, + {"SetBpfDatalink", Func, 0}, + {"SetBpfHeadercmpl", Func, 0}, + {"SetBpfImmediate", Func, 0}, + {"SetBpfInterface", Func, 0}, + {"SetBpfPromisc", Func, 0}, + {"SetBpfTimeout", Func, 0}, + {"SetCurrentDirectory", Func, 0}, + {"SetEndOfFile", Func, 0}, + {"SetEnvironmentVariable", Func, 0}, + {"SetFileAttributes", Func, 0}, + {"SetFileCompletionNotificationModes", Func, 2}, + {"SetFilePointer", Func, 0}, + {"SetFileTime", Func, 0}, + {"SetHandleInformation", Func, 0}, + {"SetKevent", Func, 0}, + {"SetLsfPromisc", Func, 0}, + {"SetNonblock", Func, 0}, + {"Setdomainname", Func, 0}, + {"Setegid", Func, 0}, + {"Setenv", Func, 0}, + {"Seteuid", Func, 0}, + {"Setfsgid", Func, 0}, + {"Setfsuid", Func, 0}, + {"Setgid", Func, 0}, + {"Setgroups", Func, 0}, + {"Sethostname", Func, 0}, + {"Setlogin", Func, 0}, + {"Setpgid", Func, 0}, + {"Setpriority", Func, 0}, + {"Setprivexec", Func, 0}, + {"Setregid", Func, 0}, + {"Setresgid", Func, 0}, + {"Setresuid", Func, 0}, + {"Setreuid", Func, 0}, + {"Setrlimit", Func, 0}, + {"Setsid", Func, 0}, + {"Setsockopt", Func, 0}, + {"SetsockoptByte", Func, 0}, + {"SetsockoptICMPv6Filter", Func, 2}, + {"SetsockoptIPMreq", Func, 0}, + {"SetsockoptIPMreqn", Func, 0}, + {"SetsockoptIPv6Mreq", Func, 0}, + {"SetsockoptInet4Addr", Func, 0}, + {"SetsockoptInt", Func, 0}, + {"SetsockoptLinger", Func, 0}, + {"SetsockoptString", Func, 0}, + {"SetsockoptTimeval", Func, 0}, + {"Settimeofday", Func, 0}, + {"Setuid", Func, 0}, + {"Setxattr", Func, 1}, + {"Shutdown", Func, 0}, + {"SidTypeAlias", Const, 0}, + {"SidTypeComputer", Const, 0}, + {"SidTypeDeletedAccount", Const, 0}, + {"SidTypeDomain", Const, 0}, + {"SidTypeGroup", Const, 0}, + {"SidTypeInvalid", Const, 0}, + {"SidTypeLabel", Const, 0}, + {"SidTypeUnknown", Const, 0}, + {"SidTypeUser", Const, 0}, + {"SidTypeWellKnownGroup", Const, 0}, + {"Signal", Type, 0}, + {"SizeofBpfHdr", Const, 0}, + {"SizeofBpfInsn", Const, 0}, + {"SizeofBpfProgram", Const, 0}, + {"SizeofBpfStat", Const, 0}, + {"SizeofBpfVersion", Const, 0}, + {"SizeofBpfZbuf", Const, 0}, + {"SizeofBpfZbufHeader", Const, 0}, + {"SizeofCmsghdr", Const, 0}, + {"SizeofICMPv6Filter", Const, 2}, + {"SizeofIPMreq", Const, 0}, + {"SizeofIPMreqn", Const, 0}, + {"SizeofIPv6MTUInfo", Const, 2}, + {"SizeofIPv6Mreq", Const, 0}, + {"SizeofIfAddrmsg", Const, 0}, + {"SizeofIfAnnounceMsghdr", Const, 1}, + {"SizeofIfData", Const, 0}, + {"SizeofIfInfomsg", Const, 0}, + {"SizeofIfMsghdr", Const, 0}, + {"SizeofIfaMsghdr", Const, 0}, + {"SizeofIfmaMsghdr", Const, 0}, + {"SizeofIfmaMsghdr2", Const, 0}, + {"SizeofInet4Pktinfo", Const, 0}, + {"SizeofInet6Pktinfo", Const, 0}, + {"SizeofInotifyEvent", Const, 0}, + {"SizeofLinger", Const, 0}, + {"SizeofMsghdr", Const, 0}, + {"SizeofNlAttr", Const, 0}, + {"SizeofNlMsgerr", Const, 0}, + {"SizeofNlMsghdr", Const, 0}, + {"SizeofRtAttr", Const, 0}, + {"SizeofRtGenmsg", Const, 0}, + {"SizeofRtMetrics", Const, 0}, + {"SizeofRtMsg", Const, 0}, + {"SizeofRtMsghdr", Const, 0}, + {"SizeofRtNexthop", Const, 0}, + {"SizeofSockFilter", Const, 0}, + {"SizeofSockFprog", Const, 0}, + {"SizeofSockaddrAny", Const, 0}, + {"SizeofSockaddrDatalink", Const, 0}, + {"SizeofSockaddrInet4", Const, 0}, + {"SizeofSockaddrInet6", Const, 0}, + {"SizeofSockaddrLinklayer", Const, 0}, + {"SizeofSockaddrNetlink", Const, 0}, + {"SizeofSockaddrUnix", Const, 0}, + {"SizeofTCPInfo", Const, 1}, + {"SizeofUcred", Const, 0}, + {"SlicePtrFromStrings", Func, 1}, + {"SockFilter", Type, 0}, + {"SockFilter.Code", Field, 0}, + {"SockFilter.Jf", Field, 0}, + {"SockFilter.Jt", Field, 0}, + {"SockFilter.K", Field, 0}, + {"SockFprog", Type, 0}, + {"SockFprog.Filter", Field, 0}, + {"SockFprog.Len", Field, 0}, + {"SockFprog.Pad_cgo_0", Field, 0}, + {"Sockaddr", Type, 0}, + {"SockaddrDatalink", Type, 0}, + {"SockaddrDatalink.Alen", Field, 0}, + {"SockaddrDatalink.Data", Field, 0}, + {"SockaddrDatalink.Family", Field, 0}, + {"SockaddrDatalink.Index", Field, 0}, + {"SockaddrDatalink.Len", Field, 0}, + {"SockaddrDatalink.Nlen", Field, 0}, + {"SockaddrDatalink.Slen", Field, 0}, + {"SockaddrDatalink.Type", Field, 0}, + {"SockaddrGen", Type, 0}, + {"SockaddrInet4", Type, 0}, + {"SockaddrInet4.Addr", Field, 0}, + {"SockaddrInet4.Port", Field, 0}, + {"SockaddrInet6", Type, 0}, + {"SockaddrInet6.Addr", Field, 0}, + {"SockaddrInet6.Port", Field, 0}, + {"SockaddrInet6.ZoneId", Field, 0}, + {"SockaddrLinklayer", Type, 0}, + {"SockaddrLinklayer.Addr", Field, 0}, + {"SockaddrLinklayer.Halen", Field, 0}, + {"SockaddrLinklayer.Hatype", Field, 0}, + {"SockaddrLinklayer.Ifindex", Field, 0}, + {"SockaddrLinklayer.Pkttype", Field, 0}, + {"SockaddrLinklayer.Protocol", Field, 0}, + {"SockaddrNetlink", Type, 0}, + {"SockaddrNetlink.Family", Field, 0}, + {"SockaddrNetlink.Groups", Field, 0}, + {"SockaddrNetlink.Pad", Field, 0}, + {"SockaddrNetlink.Pid", Field, 0}, + {"SockaddrUnix", Type, 0}, + {"SockaddrUnix.Name", Field, 0}, + {"Socket", Func, 0}, + {"SocketControlMessage", Type, 0}, + {"SocketControlMessage.Data", Field, 0}, + {"SocketControlMessage.Header", Field, 0}, + {"SocketDisableIPv6", Var, 0}, + {"Socketpair", Func, 0}, + {"Splice", Func, 0}, + {"StartProcess", Func, 0}, + {"StartupInfo", Type, 0}, + {"StartupInfo.Cb", Field, 0}, + {"StartupInfo.Desktop", Field, 0}, + {"StartupInfo.FillAttribute", Field, 0}, + {"StartupInfo.Flags", Field, 0}, + {"StartupInfo.ShowWindow", Field, 0}, + {"StartupInfo.StdErr", Field, 0}, + {"StartupInfo.StdInput", Field, 0}, + {"StartupInfo.StdOutput", Field, 0}, + {"StartupInfo.Title", Field, 0}, + {"StartupInfo.X", Field, 0}, + {"StartupInfo.XCountChars", Field, 0}, + {"StartupInfo.XSize", Field, 0}, + {"StartupInfo.Y", Field, 0}, + {"StartupInfo.YCountChars", Field, 0}, + {"StartupInfo.YSize", Field, 0}, + {"Stat", Func, 0}, + {"Stat_t", Type, 0}, + {"Stat_t.Atim", Field, 0}, + {"Stat_t.Atim_ext", Field, 12}, + {"Stat_t.Atimespec", Field, 0}, + {"Stat_t.Birthtimespec", Field, 0}, + {"Stat_t.Blksize", Field, 0}, + {"Stat_t.Blocks", Field, 0}, + {"Stat_t.Btim_ext", Field, 12}, + {"Stat_t.Ctim", Field, 0}, + {"Stat_t.Ctim_ext", Field, 12}, + {"Stat_t.Ctimespec", Field, 0}, + {"Stat_t.Dev", Field, 0}, + {"Stat_t.Flags", Field, 0}, + {"Stat_t.Gen", Field, 0}, + {"Stat_t.Gid", Field, 0}, + {"Stat_t.Ino", Field, 0}, + {"Stat_t.Lspare", Field, 0}, + {"Stat_t.Lspare0", Field, 2}, + {"Stat_t.Lspare1", Field, 2}, + {"Stat_t.Mode", Field, 0}, + {"Stat_t.Mtim", Field, 0}, + {"Stat_t.Mtim_ext", Field, 12}, + {"Stat_t.Mtimespec", Field, 0}, + {"Stat_t.Nlink", Field, 0}, + {"Stat_t.Pad_cgo_0", Field, 0}, + {"Stat_t.Pad_cgo_1", Field, 0}, + {"Stat_t.Pad_cgo_2", Field, 0}, + {"Stat_t.Padding0", Field, 12}, + {"Stat_t.Padding1", Field, 12}, + {"Stat_t.Qspare", Field, 0}, + {"Stat_t.Rdev", Field, 0}, + {"Stat_t.Size", Field, 0}, + {"Stat_t.Spare", Field, 2}, + {"Stat_t.Uid", Field, 0}, + {"Stat_t.X__pad0", Field, 0}, + {"Stat_t.X__pad1", Field, 0}, + {"Stat_t.X__pad2", Field, 0}, + {"Stat_t.X__st_birthtim", Field, 2}, + {"Stat_t.X__st_ino", Field, 0}, + {"Stat_t.X__unused", Field, 0}, + {"Statfs", Func, 0}, + {"Statfs_t", Type, 0}, + {"Statfs_t.Asyncreads", Field, 0}, + {"Statfs_t.Asyncwrites", Field, 0}, + {"Statfs_t.Bavail", Field, 0}, + {"Statfs_t.Bfree", Field, 0}, + {"Statfs_t.Blocks", Field, 0}, + {"Statfs_t.Bsize", Field, 0}, + {"Statfs_t.Charspare", Field, 0}, + {"Statfs_t.F_asyncreads", Field, 2}, + {"Statfs_t.F_asyncwrites", Field, 2}, + {"Statfs_t.F_bavail", Field, 2}, + {"Statfs_t.F_bfree", Field, 2}, + {"Statfs_t.F_blocks", Field, 2}, + {"Statfs_t.F_bsize", Field, 2}, + {"Statfs_t.F_ctime", Field, 2}, + {"Statfs_t.F_favail", Field, 2}, + {"Statfs_t.F_ffree", Field, 2}, + {"Statfs_t.F_files", Field, 2}, + {"Statfs_t.F_flags", Field, 2}, + {"Statfs_t.F_fsid", Field, 2}, + {"Statfs_t.F_fstypename", Field, 2}, + {"Statfs_t.F_iosize", Field, 2}, + {"Statfs_t.F_mntfromname", Field, 2}, + {"Statfs_t.F_mntfromspec", Field, 3}, + {"Statfs_t.F_mntonname", Field, 2}, + {"Statfs_t.F_namemax", Field, 2}, + {"Statfs_t.F_owner", Field, 2}, + {"Statfs_t.F_spare", Field, 2}, + {"Statfs_t.F_syncreads", Field, 2}, + {"Statfs_t.F_syncwrites", Field, 2}, + {"Statfs_t.Ffree", Field, 0}, + {"Statfs_t.Files", Field, 0}, + {"Statfs_t.Flags", Field, 0}, + {"Statfs_t.Frsize", Field, 0}, + {"Statfs_t.Fsid", Field, 0}, + {"Statfs_t.Fssubtype", Field, 0}, + {"Statfs_t.Fstypename", Field, 0}, + {"Statfs_t.Iosize", Field, 0}, + {"Statfs_t.Mntfromname", Field, 0}, + {"Statfs_t.Mntonname", Field, 0}, + {"Statfs_t.Mount_info", Field, 2}, + {"Statfs_t.Namelen", Field, 0}, + {"Statfs_t.Namemax", Field, 0}, + {"Statfs_t.Owner", Field, 0}, + {"Statfs_t.Pad_cgo_0", Field, 0}, + {"Statfs_t.Pad_cgo_1", Field, 2}, + {"Statfs_t.Reserved", Field, 0}, + {"Statfs_t.Spare", Field, 0}, + {"Statfs_t.Syncreads", Field, 0}, + {"Statfs_t.Syncwrites", Field, 0}, + {"Statfs_t.Type", Field, 0}, + {"Statfs_t.Version", Field, 0}, + {"Stderr", Var, 0}, + {"Stdin", Var, 0}, + {"Stdout", Var, 0}, + {"StringBytePtr", Func, 0}, + {"StringByteSlice", Func, 0}, + {"StringSlicePtr", Func, 0}, + {"StringToSid", Func, 0}, + {"StringToUTF16", Func, 0}, + {"StringToUTF16Ptr", Func, 0}, + {"Symlink", Func, 0}, + {"Sync", Func, 0}, + {"SyncFileRange", Func, 0}, + {"SysProcAttr", Type, 0}, + {"SysProcAttr.AdditionalInheritedHandles", Field, 17}, + {"SysProcAttr.AmbientCaps", Field, 9}, + {"SysProcAttr.CgroupFD", Field, 20}, + {"SysProcAttr.Chroot", Field, 0}, + {"SysProcAttr.Cloneflags", Field, 2}, + {"SysProcAttr.CmdLine", Field, 0}, + {"SysProcAttr.CreationFlags", Field, 1}, + {"SysProcAttr.Credential", Field, 0}, + {"SysProcAttr.Ctty", Field, 1}, + {"SysProcAttr.Foreground", Field, 5}, + {"SysProcAttr.GidMappings", Field, 4}, + {"SysProcAttr.GidMappingsEnableSetgroups", Field, 5}, + {"SysProcAttr.HideWindow", Field, 0}, + {"SysProcAttr.Jail", Field, 21}, + {"SysProcAttr.NoInheritHandles", Field, 16}, + {"SysProcAttr.Noctty", Field, 0}, + {"SysProcAttr.ParentProcess", Field, 17}, + {"SysProcAttr.Pdeathsig", Field, 0}, + {"SysProcAttr.Pgid", Field, 5}, + {"SysProcAttr.PidFD", Field, 22}, + {"SysProcAttr.ProcessAttributes", Field, 13}, + {"SysProcAttr.Ptrace", Field, 0}, + {"SysProcAttr.Setctty", Field, 0}, + {"SysProcAttr.Setpgid", Field, 0}, + {"SysProcAttr.Setsid", Field, 0}, + {"SysProcAttr.ThreadAttributes", Field, 13}, + {"SysProcAttr.Token", Field, 10}, + {"SysProcAttr.UidMappings", Field, 4}, + {"SysProcAttr.Unshareflags", Field, 7}, + {"SysProcAttr.UseCgroupFD", Field, 20}, + {"SysProcIDMap", Type, 4}, + {"SysProcIDMap.ContainerID", Field, 4}, + {"SysProcIDMap.HostID", Field, 4}, + {"SysProcIDMap.Size", Field, 4}, + {"Syscall", Func, 0}, + {"Syscall12", Func, 0}, + {"Syscall15", Func, 0}, + {"Syscall18", Func, 12}, + {"Syscall6", Func, 0}, + {"Syscall9", Func, 0}, + {"SyscallN", Func, 18}, + {"Sysctl", Func, 0}, + {"SysctlUint32", Func, 0}, + {"Sysctlnode", Type, 2}, + {"Sysctlnode.Flags", Field, 2}, + {"Sysctlnode.Name", Field, 2}, + {"Sysctlnode.Num", Field, 2}, + {"Sysctlnode.Un", Field, 2}, + {"Sysctlnode.Ver", Field, 2}, + {"Sysctlnode.X__rsvd", Field, 2}, + {"Sysctlnode.X_sysctl_desc", Field, 2}, + {"Sysctlnode.X_sysctl_func", Field, 2}, + {"Sysctlnode.X_sysctl_parent", Field, 2}, + {"Sysctlnode.X_sysctl_size", Field, 2}, + {"Sysinfo", Func, 0}, + {"Sysinfo_t", Type, 0}, + {"Sysinfo_t.Bufferram", Field, 0}, + {"Sysinfo_t.Freehigh", Field, 0}, + {"Sysinfo_t.Freeram", Field, 0}, + {"Sysinfo_t.Freeswap", Field, 0}, + {"Sysinfo_t.Loads", Field, 0}, + {"Sysinfo_t.Pad", Field, 0}, + {"Sysinfo_t.Pad_cgo_0", Field, 0}, + {"Sysinfo_t.Pad_cgo_1", Field, 0}, + {"Sysinfo_t.Procs", Field, 0}, + {"Sysinfo_t.Sharedram", Field, 0}, + {"Sysinfo_t.Totalhigh", Field, 0}, + {"Sysinfo_t.Totalram", Field, 0}, + {"Sysinfo_t.Totalswap", Field, 0}, + {"Sysinfo_t.Unit", Field, 0}, + {"Sysinfo_t.Uptime", Field, 0}, + {"Sysinfo_t.X_f", Field, 0}, + {"Systemtime", Type, 0}, + {"Systemtime.Day", Field, 0}, + {"Systemtime.DayOfWeek", Field, 0}, + {"Systemtime.Hour", Field, 0}, + {"Systemtime.Milliseconds", Field, 0}, + {"Systemtime.Minute", Field, 0}, + {"Systemtime.Month", Field, 0}, + {"Systemtime.Second", Field, 0}, + {"Systemtime.Year", Field, 0}, + {"TCGETS", Const, 0}, + {"TCIFLUSH", Const, 1}, + {"TCIOFLUSH", Const, 1}, + {"TCOFLUSH", Const, 1}, + {"TCPInfo", Type, 1}, + {"TCPInfo.Advmss", Field, 1}, + {"TCPInfo.Ato", Field, 1}, + {"TCPInfo.Backoff", Field, 1}, + {"TCPInfo.Ca_state", Field, 1}, + {"TCPInfo.Fackets", Field, 1}, + {"TCPInfo.Last_ack_recv", Field, 1}, + {"TCPInfo.Last_ack_sent", Field, 1}, + {"TCPInfo.Last_data_recv", Field, 1}, + {"TCPInfo.Last_data_sent", Field, 1}, + {"TCPInfo.Lost", Field, 1}, + {"TCPInfo.Options", Field, 1}, + {"TCPInfo.Pad_cgo_0", Field, 1}, + {"TCPInfo.Pmtu", Field, 1}, + {"TCPInfo.Probes", Field, 1}, + {"TCPInfo.Rcv_mss", Field, 1}, + {"TCPInfo.Rcv_rtt", Field, 1}, + {"TCPInfo.Rcv_space", Field, 1}, + {"TCPInfo.Rcv_ssthresh", Field, 1}, + {"TCPInfo.Reordering", Field, 1}, + {"TCPInfo.Retrans", Field, 1}, + {"TCPInfo.Retransmits", Field, 1}, + {"TCPInfo.Rto", Field, 1}, + {"TCPInfo.Rtt", Field, 1}, + {"TCPInfo.Rttvar", Field, 1}, + {"TCPInfo.Sacked", Field, 1}, + {"TCPInfo.Snd_cwnd", Field, 1}, + {"TCPInfo.Snd_mss", Field, 1}, + {"TCPInfo.Snd_ssthresh", Field, 1}, + {"TCPInfo.State", Field, 1}, + {"TCPInfo.Total_retrans", Field, 1}, + {"TCPInfo.Unacked", Field, 1}, + {"TCPKeepalive", Type, 3}, + {"TCPKeepalive.Interval", Field, 3}, + {"TCPKeepalive.OnOff", Field, 3}, + {"TCPKeepalive.Time", Field, 3}, + {"TCP_CA_NAME_MAX", Const, 0}, + {"TCP_CONGCTL", Const, 1}, + {"TCP_CONGESTION", Const, 0}, + {"TCP_CONNECTIONTIMEOUT", Const, 0}, + {"TCP_CORK", Const, 0}, + {"TCP_DEFER_ACCEPT", Const, 0}, + {"TCP_ENABLE_ECN", Const, 16}, + {"TCP_INFO", Const, 0}, + {"TCP_KEEPALIVE", Const, 0}, + {"TCP_KEEPCNT", Const, 0}, + {"TCP_KEEPIDLE", Const, 0}, + {"TCP_KEEPINIT", Const, 1}, + {"TCP_KEEPINTVL", Const, 0}, + {"TCP_LINGER2", Const, 0}, + {"TCP_MAXBURST", Const, 0}, + {"TCP_MAXHLEN", Const, 0}, + {"TCP_MAXOLEN", Const, 0}, + {"TCP_MAXSEG", Const, 0}, + {"TCP_MAXWIN", Const, 0}, + {"TCP_MAX_SACK", Const, 0}, + {"TCP_MAX_WINSHIFT", Const, 0}, + {"TCP_MD5SIG", Const, 0}, + {"TCP_MD5SIG_MAXKEYLEN", Const, 0}, + {"TCP_MINMSS", Const, 0}, + {"TCP_MINMSSOVERLOAD", Const, 0}, + {"TCP_MSS", Const, 0}, + {"TCP_NODELAY", Const, 0}, + {"TCP_NOOPT", Const, 0}, + {"TCP_NOPUSH", Const, 0}, + {"TCP_NOTSENT_LOWAT", Const, 16}, + {"TCP_NSTATES", Const, 1}, + {"TCP_QUICKACK", Const, 0}, + {"TCP_RXT_CONNDROPTIME", Const, 0}, + {"TCP_RXT_FINDROP", Const, 0}, + {"TCP_SACK_ENABLE", Const, 1}, + {"TCP_SENDMOREACKS", Const, 16}, + {"TCP_SYNCNT", Const, 0}, + {"TCP_VENDOR", Const, 3}, + {"TCP_WINDOW_CLAMP", Const, 0}, + {"TCSAFLUSH", Const, 1}, + {"TCSETS", Const, 0}, + {"TF_DISCONNECT", Const, 0}, + {"TF_REUSE_SOCKET", Const, 0}, + {"TF_USE_DEFAULT_WORKER", Const, 0}, + {"TF_USE_KERNEL_APC", Const, 0}, + {"TF_USE_SYSTEM_THREAD", Const, 0}, + {"TF_WRITE_BEHIND", Const, 0}, + {"TH32CS_INHERIT", Const, 4}, + {"TH32CS_SNAPALL", Const, 4}, + {"TH32CS_SNAPHEAPLIST", Const, 4}, + {"TH32CS_SNAPMODULE", Const, 4}, + {"TH32CS_SNAPMODULE32", Const, 4}, + {"TH32CS_SNAPPROCESS", Const, 4}, + {"TH32CS_SNAPTHREAD", Const, 4}, + {"TIME_ZONE_ID_DAYLIGHT", Const, 0}, + {"TIME_ZONE_ID_STANDARD", Const, 0}, + {"TIME_ZONE_ID_UNKNOWN", Const, 0}, + {"TIOCCBRK", Const, 0}, + {"TIOCCDTR", Const, 0}, + {"TIOCCONS", Const, 0}, + {"TIOCDCDTIMESTAMP", Const, 0}, + {"TIOCDRAIN", Const, 0}, + {"TIOCDSIMICROCODE", Const, 0}, + {"TIOCEXCL", Const, 0}, + {"TIOCEXT", Const, 0}, + {"TIOCFLAG_CDTRCTS", Const, 1}, + {"TIOCFLAG_CLOCAL", Const, 1}, + {"TIOCFLAG_CRTSCTS", Const, 1}, + {"TIOCFLAG_MDMBUF", Const, 1}, + {"TIOCFLAG_PPS", Const, 1}, + {"TIOCFLAG_SOFTCAR", Const, 1}, + {"TIOCFLUSH", Const, 0}, + {"TIOCGDEV", Const, 0}, + {"TIOCGDRAINWAIT", Const, 0}, + {"TIOCGETA", Const, 0}, + {"TIOCGETD", Const, 0}, + {"TIOCGFLAGS", Const, 1}, + {"TIOCGICOUNT", Const, 0}, + {"TIOCGLCKTRMIOS", Const, 0}, + {"TIOCGLINED", Const, 1}, + {"TIOCGPGRP", Const, 0}, + {"TIOCGPTN", Const, 0}, + {"TIOCGQSIZE", Const, 1}, + {"TIOCGRANTPT", Const, 1}, + {"TIOCGRS485", Const, 0}, + {"TIOCGSERIAL", Const, 0}, + {"TIOCGSID", Const, 0}, + {"TIOCGSIZE", Const, 1}, + {"TIOCGSOFTCAR", Const, 0}, + {"TIOCGTSTAMP", Const, 1}, + {"TIOCGWINSZ", Const, 0}, + {"TIOCINQ", Const, 0}, + {"TIOCIXOFF", Const, 0}, + {"TIOCIXON", Const, 0}, + {"TIOCLINUX", Const, 0}, + {"TIOCMBIC", Const, 0}, + {"TIOCMBIS", Const, 0}, + {"TIOCMGDTRWAIT", Const, 0}, + {"TIOCMGET", Const, 0}, + {"TIOCMIWAIT", Const, 0}, + {"TIOCMODG", Const, 0}, + {"TIOCMODS", Const, 0}, + {"TIOCMSDTRWAIT", Const, 0}, + {"TIOCMSET", Const, 0}, + {"TIOCM_CAR", Const, 0}, + {"TIOCM_CD", Const, 0}, + {"TIOCM_CTS", Const, 0}, + {"TIOCM_DCD", Const, 0}, + {"TIOCM_DSR", Const, 0}, + {"TIOCM_DTR", Const, 0}, + {"TIOCM_LE", Const, 0}, + {"TIOCM_RI", Const, 0}, + {"TIOCM_RNG", Const, 0}, + {"TIOCM_RTS", Const, 0}, + {"TIOCM_SR", Const, 0}, + {"TIOCM_ST", Const, 0}, + {"TIOCNOTTY", Const, 0}, + {"TIOCNXCL", Const, 0}, + {"TIOCOUTQ", Const, 0}, + {"TIOCPKT", Const, 0}, + {"TIOCPKT_DATA", Const, 0}, + {"TIOCPKT_DOSTOP", Const, 0}, + {"TIOCPKT_FLUSHREAD", Const, 0}, + {"TIOCPKT_FLUSHWRITE", Const, 0}, + {"TIOCPKT_IOCTL", Const, 0}, + {"TIOCPKT_NOSTOP", Const, 0}, + {"TIOCPKT_START", Const, 0}, + {"TIOCPKT_STOP", Const, 0}, + {"TIOCPTMASTER", Const, 0}, + {"TIOCPTMGET", Const, 1}, + {"TIOCPTSNAME", Const, 1}, + {"TIOCPTYGNAME", Const, 0}, + {"TIOCPTYGRANT", Const, 0}, + {"TIOCPTYUNLK", Const, 0}, + {"TIOCRCVFRAME", Const, 1}, + {"TIOCREMOTE", Const, 0}, + {"TIOCSBRK", Const, 0}, + {"TIOCSCONS", Const, 0}, + {"TIOCSCTTY", Const, 0}, + {"TIOCSDRAINWAIT", Const, 0}, + {"TIOCSDTR", Const, 0}, + {"TIOCSERCONFIG", Const, 0}, + {"TIOCSERGETLSR", Const, 0}, + {"TIOCSERGETMULTI", Const, 0}, + {"TIOCSERGSTRUCT", Const, 0}, + {"TIOCSERGWILD", Const, 0}, + {"TIOCSERSETMULTI", Const, 0}, + {"TIOCSERSWILD", Const, 0}, + {"TIOCSER_TEMT", Const, 0}, + {"TIOCSETA", Const, 0}, + {"TIOCSETAF", Const, 0}, + {"TIOCSETAW", Const, 0}, + {"TIOCSETD", Const, 0}, + {"TIOCSFLAGS", Const, 1}, + {"TIOCSIG", Const, 0}, + {"TIOCSLCKTRMIOS", Const, 0}, + {"TIOCSLINED", Const, 1}, + {"TIOCSPGRP", Const, 0}, + {"TIOCSPTLCK", Const, 0}, + {"TIOCSQSIZE", Const, 1}, + {"TIOCSRS485", Const, 0}, + {"TIOCSSERIAL", Const, 0}, + {"TIOCSSIZE", Const, 1}, + {"TIOCSSOFTCAR", Const, 0}, + {"TIOCSTART", Const, 0}, + {"TIOCSTAT", Const, 0}, + {"TIOCSTI", Const, 0}, + {"TIOCSTOP", Const, 0}, + {"TIOCSTSTAMP", Const, 1}, + {"TIOCSWINSZ", Const, 0}, + {"TIOCTIMESTAMP", Const, 0}, + {"TIOCUCNTL", Const, 0}, + {"TIOCVHANGUP", Const, 0}, + {"TIOCXMTFRAME", Const, 1}, + {"TOKEN_ADJUST_DEFAULT", Const, 0}, + {"TOKEN_ADJUST_GROUPS", Const, 0}, + {"TOKEN_ADJUST_PRIVILEGES", Const, 0}, + {"TOKEN_ADJUST_SESSIONID", Const, 11}, + {"TOKEN_ALL_ACCESS", Const, 0}, + {"TOKEN_ASSIGN_PRIMARY", Const, 0}, + {"TOKEN_DUPLICATE", Const, 0}, + {"TOKEN_EXECUTE", Const, 0}, + {"TOKEN_IMPERSONATE", Const, 0}, + {"TOKEN_QUERY", Const, 0}, + {"TOKEN_QUERY_SOURCE", Const, 0}, + {"TOKEN_READ", Const, 0}, + {"TOKEN_WRITE", Const, 0}, + {"TOSTOP", Const, 0}, + {"TRUNCATE_EXISTING", Const, 0}, + {"TUNATTACHFILTER", Const, 0}, + {"TUNDETACHFILTER", Const, 0}, + {"TUNGETFEATURES", Const, 0}, + {"TUNGETIFF", Const, 0}, + {"TUNGETSNDBUF", Const, 0}, + {"TUNGETVNETHDRSZ", Const, 0}, + {"TUNSETDEBUG", Const, 0}, + {"TUNSETGROUP", Const, 0}, + {"TUNSETIFF", Const, 0}, + {"TUNSETLINK", Const, 0}, + {"TUNSETNOCSUM", Const, 0}, + {"TUNSETOFFLOAD", Const, 0}, + {"TUNSETOWNER", Const, 0}, + {"TUNSETPERSIST", Const, 0}, + {"TUNSETSNDBUF", Const, 0}, + {"TUNSETTXFILTER", Const, 0}, + {"TUNSETVNETHDRSZ", Const, 0}, + {"Tee", Func, 0}, + {"TerminateProcess", Func, 0}, + {"Termios", Type, 0}, + {"Termios.Cc", Field, 0}, + {"Termios.Cflag", Field, 0}, + {"Termios.Iflag", Field, 0}, + {"Termios.Ispeed", Field, 0}, + {"Termios.Lflag", Field, 0}, + {"Termios.Line", Field, 0}, + {"Termios.Oflag", Field, 0}, + {"Termios.Ospeed", Field, 0}, + {"Termios.Pad_cgo_0", Field, 0}, + {"Tgkill", Func, 0}, + {"Time", Func, 0}, + {"Time_t", Type, 0}, + {"Times", Func, 0}, + {"Timespec", Type, 0}, + {"Timespec.Nsec", Field, 0}, + {"Timespec.Pad_cgo_0", Field, 2}, + {"Timespec.Sec", Field, 0}, + {"TimespecToNsec", Func, 0}, + {"Timeval", Type, 0}, + {"Timeval.Pad_cgo_0", Field, 0}, + {"Timeval.Sec", Field, 0}, + {"Timeval.Usec", Field, 0}, + {"Timeval32", Type, 0}, + {"Timeval32.Sec", Field, 0}, + {"Timeval32.Usec", Field, 0}, + {"TimevalToNsec", Func, 0}, + {"Timex", Type, 0}, + {"Timex.Calcnt", Field, 0}, + {"Timex.Constant", Field, 0}, + {"Timex.Errcnt", Field, 0}, + {"Timex.Esterror", Field, 0}, + {"Timex.Freq", Field, 0}, + {"Timex.Jitcnt", Field, 0}, + {"Timex.Jitter", Field, 0}, + {"Timex.Maxerror", Field, 0}, + {"Timex.Modes", Field, 0}, + {"Timex.Offset", Field, 0}, + {"Timex.Pad_cgo_0", Field, 0}, + {"Timex.Pad_cgo_1", Field, 0}, + {"Timex.Pad_cgo_2", Field, 0}, + {"Timex.Pad_cgo_3", Field, 0}, + {"Timex.Ppsfreq", Field, 0}, + {"Timex.Precision", Field, 0}, + {"Timex.Shift", Field, 0}, + {"Timex.Stabil", Field, 0}, + {"Timex.Status", Field, 0}, + {"Timex.Stbcnt", Field, 0}, + {"Timex.Tai", Field, 0}, + {"Timex.Tick", Field, 0}, + {"Timex.Time", Field, 0}, + {"Timex.Tolerance", Field, 0}, + {"Timezoneinformation", Type, 0}, + {"Timezoneinformation.Bias", Field, 0}, + {"Timezoneinformation.DaylightBias", Field, 0}, + {"Timezoneinformation.DaylightDate", Field, 0}, + {"Timezoneinformation.DaylightName", Field, 0}, + {"Timezoneinformation.StandardBias", Field, 0}, + {"Timezoneinformation.StandardDate", Field, 0}, + {"Timezoneinformation.StandardName", Field, 0}, + {"Tms", Type, 0}, + {"Tms.Cstime", Field, 0}, + {"Tms.Cutime", Field, 0}, + {"Tms.Stime", Field, 0}, + {"Tms.Utime", Field, 0}, + {"Token", Type, 0}, + {"TokenAccessInformation", Const, 0}, + {"TokenAuditPolicy", Const, 0}, + {"TokenDefaultDacl", Const, 0}, + {"TokenElevation", Const, 0}, + {"TokenElevationType", Const, 0}, + {"TokenGroups", Const, 0}, + {"TokenGroupsAndPrivileges", Const, 0}, + {"TokenHasRestrictions", Const, 0}, + {"TokenImpersonationLevel", Const, 0}, + {"TokenIntegrityLevel", Const, 0}, + {"TokenLinkedToken", Const, 0}, + {"TokenLogonSid", Const, 0}, + {"TokenMandatoryPolicy", Const, 0}, + {"TokenOrigin", Const, 0}, + {"TokenOwner", Const, 0}, + {"TokenPrimaryGroup", Const, 0}, + {"TokenPrivileges", Const, 0}, + {"TokenRestrictedSids", Const, 0}, + {"TokenSandBoxInert", Const, 0}, + {"TokenSessionId", Const, 0}, + {"TokenSessionReference", Const, 0}, + {"TokenSource", Const, 0}, + {"TokenStatistics", Const, 0}, + {"TokenType", Const, 0}, + {"TokenUIAccess", Const, 0}, + {"TokenUser", Const, 0}, + {"TokenVirtualizationAllowed", Const, 0}, + {"TokenVirtualizationEnabled", Const, 0}, + {"Tokenprimarygroup", Type, 0}, + {"Tokenprimarygroup.PrimaryGroup", Field, 0}, + {"Tokenuser", Type, 0}, + {"Tokenuser.User", Field, 0}, + {"TranslateAccountName", Func, 0}, + {"TranslateName", Func, 0}, + {"TransmitFile", Func, 0}, + {"TransmitFileBuffers", Type, 0}, + {"TransmitFileBuffers.Head", Field, 0}, + {"TransmitFileBuffers.HeadLength", Field, 0}, + {"TransmitFileBuffers.Tail", Field, 0}, + {"TransmitFileBuffers.TailLength", Field, 0}, + {"Truncate", Func, 0}, + {"UNIX_PATH_MAX", Const, 12}, + {"USAGE_MATCH_TYPE_AND", Const, 0}, + {"USAGE_MATCH_TYPE_OR", Const, 0}, + {"UTF16FromString", Func, 1}, + {"UTF16PtrFromString", Func, 1}, + {"UTF16ToString", Func, 0}, + {"Ucred", Type, 0}, + {"Ucred.Gid", Field, 0}, + {"Ucred.Pid", Field, 0}, + {"Ucred.Uid", Field, 0}, + {"Umask", Func, 0}, + {"Uname", Func, 0}, + {"Undelete", Func, 0}, + {"UnixCredentials", Func, 0}, + {"UnixRights", Func, 0}, + {"Unlink", Func, 0}, + {"Unlinkat", Func, 0}, + {"UnmapViewOfFile", Func, 0}, + {"Unmount", Func, 0}, + {"Unsetenv", Func, 4}, + {"Unshare", Func, 0}, + {"UserInfo10", Type, 0}, + {"UserInfo10.Comment", Field, 0}, + {"UserInfo10.FullName", Field, 0}, + {"UserInfo10.Name", Field, 0}, + {"UserInfo10.UsrComment", Field, 0}, + {"Ustat", Func, 0}, + {"Ustat_t", Type, 0}, + {"Ustat_t.Fname", Field, 0}, + {"Ustat_t.Fpack", Field, 0}, + {"Ustat_t.Pad_cgo_0", Field, 0}, + {"Ustat_t.Pad_cgo_1", Field, 0}, + {"Ustat_t.Tfree", Field, 0}, + {"Ustat_t.Tinode", Field, 0}, + {"Utimbuf", Type, 0}, + {"Utimbuf.Actime", Field, 0}, + {"Utimbuf.Modtime", Field, 0}, + {"Utime", Func, 0}, + {"Utimes", Func, 0}, + {"UtimesNano", Func, 1}, + {"Utsname", Type, 0}, + {"Utsname.Domainname", Field, 0}, + {"Utsname.Machine", Field, 0}, + {"Utsname.Nodename", Field, 0}, + {"Utsname.Release", Field, 0}, + {"Utsname.Sysname", Field, 0}, + {"Utsname.Version", Field, 0}, + {"VDISCARD", Const, 0}, + {"VDSUSP", Const, 1}, + {"VEOF", Const, 0}, + {"VEOL", Const, 0}, + {"VEOL2", Const, 0}, + {"VERASE", Const, 0}, + {"VERASE2", Const, 1}, + {"VINTR", Const, 0}, + {"VKILL", Const, 0}, + {"VLNEXT", Const, 0}, + {"VMIN", Const, 0}, + {"VQUIT", Const, 0}, + {"VREPRINT", Const, 0}, + {"VSTART", Const, 0}, + {"VSTATUS", Const, 1}, + {"VSTOP", Const, 0}, + {"VSUSP", Const, 0}, + {"VSWTC", Const, 0}, + {"VT0", Const, 1}, + {"VT1", Const, 1}, + {"VTDLY", Const, 1}, + {"VTIME", Const, 0}, + {"VWERASE", Const, 0}, + {"VirtualLock", Func, 0}, + {"VirtualUnlock", Func, 0}, + {"WAIT_ABANDONED", Const, 0}, + {"WAIT_FAILED", Const, 0}, + {"WAIT_OBJECT_0", Const, 0}, + {"WAIT_TIMEOUT", Const, 0}, + {"WALL", Const, 0}, + {"WALLSIG", Const, 1}, + {"WALTSIG", Const, 1}, + {"WCLONE", Const, 0}, + {"WCONTINUED", Const, 0}, + {"WCOREFLAG", Const, 0}, + {"WEXITED", Const, 0}, + {"WLINUXCLONE", Const, 0}, + {"WNOHANG", Const, 0}, + {"WNOTHREAD", Const, 0}, + {"WNOWAIT", Const, 0}, + {"WNOZOMBIE", Const, 1}, + {"WOPTSCHECKED", Const, 1}, + {"WORDSIZE", Const, 0}, + {"WSABuf", Type, 0}, + {"WSABuf.Buf", Field, 0}, + {"WSABuf.Len", Field, 0}, + {"WSACleanup", Func, 0}, + {"WSADESCRIPTION_LEN", Const, 0}, + {"WSAData", Type, 0}, + {"WSAData.Description", Field, 0}, + {"WSAData.HighVersion", Field, 0}, + {"WSAData.MaxSockets", Field, 0}, + {"WSAData.MaxUdpDg", Field, 0}, + {"WSAData.SystemStatus", Field, 0}, + {"WSAData.VendorInfo", Field, 0}, + {"WSAData.Version", Field, 0}, + {"WSAEACCES", Const, 2}, + {"WSAECONNABORTED", Const, 9}, + {"WSAECONNRESET", Const, 3}, + {"WSAENOPROTOOPT", Const, 23}, + {"WSAEnumProtocols", Func, 2}, + {"WSAID_CONNECTEX", Var, 1}, + {"WSAIoctl", Func, 0}, + {"WSAPROTOCOL_LEN", Const, 2}, + {"WSAProtocolChain", Type, 2}, + {"WSAProtocolChain.ChainEntries", Field, 2}, + {"WSAProtocolChain.ChainLen", Field, 2}, + {"WSAProtocolInfo", Type, 2}, + {"WSAProtocolInfo.AddressFamily", Field, 2}, + {"WSAProtocolInfo.CatalogEntryId", Field, 2}, + {"WSAProtocolInfo.MaxSockAddr", Field, 2}, + {"WSAProtocolInfo.MessageSize", Field, 2}, + {"WSAProtocolInfo.MinSockAddr", Field, 2}, + {"WSAProtocolInfo.NetworkByteOrder", Field, 2}, + {"WSAProtocolInfo.Protocol", Field, 2}, + {"WSAProtocolInfo.ProtocolChain", Field, 2}, + {"WSAProtocolInfo.ProtocolMaxOffset", Field, 2}, + {"WSAProtocolInfo.ProtocolName", Field, 2}, + {"WSAProtocolInfo.ProviderFlags", Field, 2}, + {"WSAProtocolInfo.ProviderId", Field, 2}, + {"WSAProtocolInfo.ProviderReserved", Field, 2}, + {"WSAProtocolInfo.SecurityScheme", Field, 2}, + {"WSAProtocolInfo.ServiceFlags1", Field, 2}, + {"WSAProtocolInfo.ServiceFlags2", Field, 2}, + {"WSAProtocolInfo.ServiceFlags3", Field, 2}, + {"WSAProtocolInfo.ServiceFlags4", Field, 2}, + {"WSAProtocolInfo.SocketType", Field, 2}, + {"WSAProtocolInfo.Version", Field, 2}, + {"WSARecv", Func, 0}, + {"WSARecvFrom", Func, 0}, + {"WSASYS_STATUS_LEN", Const, 0}, + {"WSASend", Func, 0}, + {"WSASendTo", Func, 0}, + {"WSASendto", Func, 0}, + {"WSAStartup", Func, 0}, + {"WSTOPPED", Const, 0}, + {"WTRAPPED", Const, 1}, + {"WUNTRACED", Const, 0}, + {"Wait4", Func, 0}, + {"WaitForSingleObject", Func, 0}, + {"WaitStatus", Type, 0}, + {"WaitStatus.ExitCode", Field, 0}, + {"Win32FileAttributeData", Type, 0}, + {"Win32FileAttributeData.CreationTime", Field, 0}, + {"Win32FileAttributeData.FileAttributes", Field, 0}, + {"Win32FileAttributeData.FileSizeHigh", Field, 0}, + {"Win32FileAttributeData.FileSizeLow", Field, 0}, + {"Win32FileAttributeData.LastAccessTime", Field, 0}, + {"Win32FileAttributeData.LastWriteTime", Field, 0}, + {"Win32finddata", Type, 0}, + {"Win32finddata.AlternateFileName", Field, 0}, + {"Win32finddata.CreationTime", Field, 0}, + {"Win32finddata.FileAttributes", Field, 0}, + {"Win32finddata.FileName", Field, 0}, + {"Win32finddata.FileSizeHigh", Field, 0}, + {"Win32finddata.FileSizeLow", Field, 0}, + {"Win32finddata.LastAccessTime", Field, 0}, + {"Win32finddata.LastWriteTime", Field, 0}, + {"Win32finddata.Reserved0", Field, 0}, + {"Win32finddata.Reserved1", Field, 0}, + {"Write", Func, 0}, + {"WriteConsole", Func, 1}, + {"WriteFile", Func, 0}, + {"X509_ASN_ENCODING", Const, 0}, + {"XCASE", Const, 0}, + {"XP1_CONNECTIONLESS", Const, 2}, + {"XP1_CONNECT_DATA", Const, 2}, + {"XP1_DISCONNECT_DATA", Const, 2}, + {"XP1_EXPEDITED_DATA", Const, 2}, + {"XP1_GRACEFUL_CLOSE", Const, 2}, + {"XP1_GUARANTEED_DELIVERY", Const, 2}, + {"XP1_GUARANTEED_ORDER", Const, 2}, + {"XP1_IFS_HANDLES", Const, 2}, + {"XP1_MESSAGE_ORIENTED", Const, 2}, + {"XP1_MULTIPOINT_CONTROL_PLANE", Const, 2}, + {"XP1_MULTIPOINT_DATA_PLANE", Const, 2}, + {"XP1_PARTIAL_MESSAGE", Const, 2}, + {"XP1_PSEUDO_STREAM", Const, 2}, + {"XP1_QOS_SUPPORTED", Const, 2}, + {"XP1_SAN_SUPPORT_SDP", Const, 2}, + {"XP1_SUPPORT_BROADCAST", Const, 2}, + {"XP1_SUPPORT_MULTIPOINT", Const, 2}, + {"XP1_UNI_RECV", Const, 2}, + {"XP1_UNI_SEND", Const, 2}, + }, + "syscall/js": { + {"CopyBytesToGo", Func, 0}, + {"CopyBytesToJS", Func, 0}, + {"Error", Type, 0}, + {"Func", Type, 0}, + {"FuncOf", Func, 0}, + {"Global", Func, 0}, + {"Null", Func, 0}, + {"Type", Type, 0}, + {"TypeBoolean", Const, 0}, + {"TypeFunction", Const, 0}, + {"TypeNull", Const, 0}, + {"TypeNumber", Const, 0}, + {"TypeObject", Const, 0}, + {"TypeString", Const, 0}, + {"TypeSymbol", Const, 0}, + {"TypeUndefined", Const, 0}, + {"Undefined", Func, 0}, + {"Value", Type, 0}, + {"ValueError", Type, 0}, + {"ValueOf", Func, 0}, + }, + "testing": { + {"(*B).Cleanup", Method, 14}, + {"(*B).Elapsed", Method, 20}, + {"(*B).Error", Method, 0}, + {"(*B).Errorf", Method, 0}, + {"(*B).Fail", Method, 0}, + {"(*B).FailNow", Method, 0}, + {"(*B).Failed", Method, 0}, + {"(*B).Fatal", Method, 0}, + {"(*B).Fatalf", Method, 0}, + {"(*B).Helper", Method, 9}, + {"(*B).Log", Method, 0}, + {"(*B).Logf", Method, 0}, + {"(*B).Name", Method, 8}, + {"(*B).ReportAllocs", Method, 1}, + {"(*B).ReportMetric", Method, 13}, + {"(*B).ResetTimer", Method, 0}, + {"(*B).Run", Method, 7}, + {"(*B).RunParallel", Method, 3}, + {"(*B).SetBytes", Method, 0}, + {"(*B).SetParallelism", Method, 3}, + {"(*B).Setenv", Method, 17}, + {"(*B).Skip", Method, 1}, + {"(*B).SkipNow", Method, 1}, + {"(*B).Skipf", Method, 1}, + {"(*B).Skipped", Method, 1}, + {"(*B).StartTimer", Method, 0}, + {"(*B).StopTimer", Method, 0}, + {"(*B).TempDir", Method, 15}, + {"(*F).Add", Method, 18}, + {"(*F).Cleanup", Method, 18}, + {"(*F).Error", Method, 18}, + {"(*F).Errorf", Method, 18}, + {"(*F).Fail", Method, 18}, + {"(*F).FailNow", Method, 18}, + {"(*F).Failed", Method, 18}, + {"(*F).Fatal", Method, 18}, + {"(*F).Fatalf", Method, 18}, + {"(*F).Fuzz", Method, 18}, + {"(*F).Helper", Method, 18}, + {"(*F).Log", Method, 18}, + {"(*F).Logf", Method, 18}, + {"(*F).Name", Method, 18}, + {"(*F).Setenv", Method, 18}, + {"(*F).Skip", Method, 18}, + {"(*F).SkipNow", Method, 18}, + {"(*F).Skipf", Method, 18}, + {"(*F).Skipped", Method, 18}, + {"(*F).TempDir", Method, 18}, + {"(*M).Run", Method, 4}, + {"(*PB).Next", Method, 3}, + {"(*T).Cleanup", Method, 14}, + {"(*T).Deadline", Method, 15}, + {"(*T).Error", Method, 0}, + {"(*T).Errorf", Method, 0}, + {"(*T).Fail", Method, 0}, + {"(*T).FailNow", Method, 0}, + {"(*T).Failed", Method, 0}, + {"(*T).Fatal", Method, 0}, + {"(*T).Fatalf", Method, 0}, + {"(*T).Helper", Method, 9}, + {"(*T).Log", Method, 0}, + {"(*T).Logf", Method, 0}, + {"(*T).Name", Method, 8}, + {"(*T).Parallel", Method, 0}, + {"(*T).Run", Method, 7}, + {"(*T).Setenv", Method, 17}, + {"(*T).Skip", Method, 1}, + {"(*T).SkipNow", Method, 1}, + {"(*T).Skipf", Method, 1}, + {"(*T).Skipped", Method, 1}, + {"(*T).TempDir", Method, 15}, + {"(BenchmarkResult).AllocedBytesPerOp", Method, 1}, + {"(BenchmarkResult).AllocsPerOp", Method, 1}, + {"(BenchmarkResult).MemString", Method, 1}, + {"(BenchmarkResult).NsPerOp", Method, 0}, + {"(BenchmarkResult).String", Method, 0}, + {"AllocsPerRun", Func, 1}, + {"B", Type, 0}, + {"B.N", Field, 0}, + {"Benchmark", Func, 0}, + {"BenchmarkResult", Type, 0}, + {"BenchmarkResult.Bytes", Field, 0}, + {"BenchmarkResult.Extra", Field, 13}, + {"BenchmarkResult.MemAllocs", Field, 1}, + {"BenchmarkResult.MemBytes", Field, 1}, + {"BenchmarkResult.N", Field, 0}, + {"BenchmarkResult.T", Field, 0}, + {"Cover", Type, 2}, + {"Cover.Blocks", Field, 2}, + {"Cover.Counters", Field, 2}, + {"Cover.CoveredPackages", Field, 2}, + {"Cover.Mode", Field, 2}, + {"CoverBlock", Type, 2}, + {"CoverBlock.Col0", Field, 2}, + {"CoverBlock.Col1", Field, 2}, + {"CoverBlock.Line0", Field, 2}, + {"CoverBlock.Line1", Field, 2}, + {"CoverBlock.Stmts", Field, 2}, + {"CoverMode", Func, 8}, + {"Coverage", Func, 4}, + {"F", Type, 18}, + {"Init", Func, 13}, + {"InternalBenchmark", Type, 0}, + {"InternalBenchmark.F", Field, 0}, + {"InternalBenchmark.Name", Field, 0}, + {"InternalExample", Type, 0}, + {"InternalExample.F", Field, 0}, + {"InternalExample.Name", Field, 0}, + {"InternalExample.Output", Field, 0}, + {"InternalExample.Unordered", Field, 7}, + {"InternalFuzzTarget", Type, 18}, + {"InternalFuzzTarget.Fn", Field, 18}, + {"InternalFuzzTarget.Name", Field, 18}, + {"InternalTest", Type, 0}, + {"InternalTest.F", Field, 0}, + {"InternalTest.Name", Field, 0}, + {"M", Type, 4}, + {"Main", Func, 0}, + {"MainStart", Func, 4}, + {"PB", Type, 3}, + {"RegisterCover", Func, 2}, + {"RunBenchmarks", Func, 0}, + {"RunExamples", Func, 0}, + {"RunTests", Func, 0}, + {"Short", Func, 0}, + {"T", Type, 0}, + {"TB", Type, 2}, + {"Testing", Func, 21}, + {"Verbose", Func, 1}, + }, + "testing/fstest": { + {"(MapFS).Glob", Method, 16}, + {"(MapFS).Open", Method, 16}, + {"(MapFS).ReadDir", Method, 16}, + {"(MapFS).ReadFile", Method, 16}, + {"(MapFS).Stat", Method, 16}, + {"(MapFS).Sub", Method, 16}, + {"MapFS", Type, 16}, + {"MapFile", Type, 16}, + {"MapFile.Data", Field, 16}, + {"MapFile.ModTime", Field, 16}, + {"MapFile.Mode", Field, 16}, + {"MapFile.Sys", Field, 16}, + {"TestFS", Func, 16}, + }, + "testing/iotest": { + {"DataErrReader", Func, 0}, + {"ErrReader", Func, 16}, + {"ErrTimeout", Var, 0}, + {"HalfReader", Func, 0}, + {"NewReadLogger", Func, 0}, + {"NewWriteLogger", Func, 0}, + {"OneByteReader", Func, 0}, + {"TestReader", Func, 16}, + {"TimeoutReader", Func, 0}, + {"TruncateWriter", Func, 0}, + }, + "testing/quick": { + {"(*CheckEqualError).Error", Method, 0}, + {"(*CheckError).Error", Method, 0}, + {"(SetupError).Error", Method, 0}, + {"Check", Func, 0}, + {"CheckEqual", Func, 0}, + {"CheckEqualError", Type, 0}, + {"CheckEqualError.CheckError", Field, 0}, + {"CheckEqualError.Out1", Field, 0}, + {"CheckEqualError.Out2", Field, 0}, + {"CheckError", Type, 0}, + {"CheckError.Count", Field, 0}, + {"CheckError.In", Field, 0}, + {"Config", Type, 0}, + {"Config.MaxCount", Field, 0}, + {"Config.MaxCountScale", Field, 0}, + {"Config.Rand", Field, 0}, + {"Config.Values", Field, 0}, + {"Generator", Type, 0}, + {"SetupError", Type, 0}, + {"Value", Func, 0}, + }, + "testing/slogtest": { + {"Run", Func, 22}, + {"TestHandler", Func, 21}, + }, + "text/scanner": { + {"(*Position).IsValid", Method, 0}, + {"(*Scanner).Init", Method, 0}, + {"(*Scanner).IsValid", Method, 0}, + {"(*Scanner).Next", Method, 0}, + {"(*Scanner).Peek", Method, 0}, + {"(*Scanner).Pos", Method, 0}, + {"(*Scanner).Scan", Method, 0}, + {"(*Scanner).TokenText", Method, 0}, + {"(Position).String", Method, 0}, + {"(Scanner).String", Method, 0}, + {"Char", Const, 0}, + {"Comment", Const, 0}, + {"EOF", Const, 0}, + {"Float", Const, 0}, + {"GoTokens", Const, 0}, + {"GoWhitespace", Const, 0}, + {"Ident", Const, 0}, + {"Int", Const, 0}, + {"Position", Type, 0}, + {"Position.Column", Field, 0}, + {"Position.Filename", Field, 0}, + {"Position.Line", Field, 0}, + {"Position.Offset", Field, 0}, + {"RawString", Const, 0}, + {"ScanChars", Const, 0}, + {"ScanComments", Const, 0}, + {"ScanFloats", Const, 0}, + {"ScanIdents", Const, 0}, + {"ScanInts", Const, 0}, + {"ScanRawStrings", Const, 0}, + {"ScanStrings", Const, 0}, + {"Scanner", Type, 0}, + {"Scanner.Error", Field, 0}, + {"Scanner.ErrorCount", Field, 0}, + {"Scanner.IsIdentRune", Field, 4}, + {"Scanner.Mode", Field, 0}, + {"Scanner.Position", Field, 0}, + {"Scanner.Whitespace", Field, 0}, + {"SkipComments", Const, 0}, + {"String", Const, 0}, + {"TokenString", Func, 0}, + }, + "text/tabwriter": { + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Init", Method, 0}, + {"(*Writer).Write", Method, 0}, + {"AlignRight", Const, 0}, + {"Debug", Const, 0}, + {"DiscardEmptyColumns", Const, 0}, + {"Escape", Const, 0}, + {"FilterHTML", Const, 0}, + {"NewWriter", Func, 0}, + {"StripEscape", Const, 0}, + {"TabIndent", Const, 0}, + {"Writer", Type, 0}, + }, + "text/template": { + {"(*Template).AddParseTree", Method, 0}, + {"(*Template).Clone", Method, 0}, + {"(*Template).DefinedTemplates", Method, 5}, + {"(*Template).Delims", Method, 0}, + {"(*Template).Execute", Method, 0}, + {"(*Template).ExecuteTemplate", Method, 0}, + {"(*Template).Funcs", Method, 0}, + {"(*Template).Lookup", Method, 0}, + {"(*Template).Name", Method, 0}, + {"(*Template).New", Method, 0}, + {"(*Template).Option", Method, 5}, + {"(*Template).Parse", Method, 0}, + {"(*Template).ParseFS", Method, 16}, + {"(*Template).ParseFiles", Method, 0}, + {"(*Template).ParseGlob", Method, 0}, + {"(*Template).Templates", Method, 0}, + {"(ExecError).Error", Method, 6}, + {"(ExecError).Unwrap", Method, 13}, + {"(Template).Copy", Method, 2}, + {"(Template).ErrorContext", Method, 1}, + {"ExecError", Type, 6}, + {"ExecError.Err", Field, 6}, + {"ExecError.Name", Field, 6}, + {"FuncMap", Type, 0}, + {"HTMLEscape", Func, 0}, + {"HTMLEscapeString", Func, 0}, + {"HTMLEscaper", Func, 0}, + {"IsTrue", Func, 6}, + {"JSEscape", Func, 0}, + {"JSEscapeString", Func, 0}, + {"JSEscaper", Func, 0}, + {"Must", Func, 0}, + {"New", Func, 0}, + {"ParseFS", Func, 16}, + {"ParseFiles", Func, 0}, + {"ParseGlob", Func, 0}, + {"Template", Type, 0}, + {"Template.Tree", Field, 0}, + {"URLQueryEscaper", Func, 0}, + }, + "text/template/parse": { + {"(*ActionNode).Copy", Method, 0}, + {"(*ActionNode).String", Method, 0}, + {"(*BoolNode).Copy", Method, 0}, + {"(*BoolNode).String", Method, 0}, + {"(*BranchNode).Copy", Method, 4}, + {"(*BranchNode).String", Method, 0}, + {"(*BreakNode).Copy", Method, 18}, + {"(*BreakNode).String", Method, 18}, + {"(*ChainNode).Add", Method, 1}, + {"(*ChainNode).Copy", Method, 1}, + {"(*ChainNode).String", Method, 1}, + {"(*CommandNode).Copy", Method, 0}, + {"(*CommandNode).String", Method, 0}, + {"(*CommentNode).Copy", Method, 16}, + {"(*CommentNode).String", Method, 16}, + {"(*ContinueNode).Copy", Method, 18}, + {"(*ContinueNode).String", Method, 18}, + {"(*DotNode).Copy", Method, 0}, + {"(*DotNode).String", Method, 0}, + {"(*DotNode).Type", Method, 0}, + {"(*FieldNode).Copy", Method, 0}, + {"(*FieldNode).String", Method, 0}, + {"(*IdentifierNode).Copy", Method, 0}, + {"(*IdentifierNode).SetPos", Method, 1}, + {"(*IdentifierNode).SetTree", Method, 4}, + {"(*IdentifierNode).String", Method, 0}, + {"(*IfNode).Copy", Method, 0}, + {"(*IfNode).String", Method, 0}, + {"(*ListNode).Copy", Method, 0}, + {"(*ListNode).CopyList", Method, 0}, + {"(*ListNode).String", Method, 0}, + {"(*NilNode).Copy", Method, 1}, + {"(*NilNode).String", Method, 1}, + {"(*NilNode).Type", Method, 1}, + {"(*NumberNode).Copy", Method, 0}, + {"(*NumberNode).String", Method, 0}, + {"(*PipeNode).Copy", Method, 0}, + {"(*PipeNode).CopyPipe", Method, 0}, + {"(*PipeNode).String", Method, 0}, + {"(*RangeNode).Copy", Method, 0}, + {"(*RangeNode).String", Method, 0}, + {"(*StringNode).Copy", Method, 0}, + {"(*StringNode).String", Method, 0}, + {"(*TemplateNode).Copy", Method, 0}, + {"(*TemplateNode).String", Method, 0}, + {"(*TextNode).Copy", Method, 0}, + {"(*TextNode).String", Method, 0}, + {"(*Tree).Copy", Method, 2}, + {"(*Tree).ErrorContext", Method, 1}, + {"(*Tree).Parse", Method, 0}, + {"(*VariableNode).Copy", Method, 0}, + {"(*VariableNode).String", Method, 0}, + {"(*WithNode).Copy", Method, 0}, + {"(*WithNode).String", Method, 0}, + {"(ActionNode).Position", Method, 1}, + {"(ActionNode).Type", Method, 0}, + {"(BoolNode).Position", Method, 1}, + {"(BoolNode).Type", Method, 0}, + {"(BranchNode).Position", Method, 1}, + {"(BranchNode).Type", Method, 0}, + {"(BreakNode).Position", Method, 18}, + {"(BreakNode).Type", Method, 18}, + {"(ChainNode).Position", Method, 1}, + {"(ChainNode).Type", Method, 1}, + {"(CommandNode).Position", Method, 1}, + {"(CommandNode).Type", Method, 0}, + {"(CommentNode).Position", Method, 16}, + {"(CommentNode).Type", Method, 16}, + {"(ContinueNode).Position", Method, 18}, + {"(ContinueNode).Type", Method, 18}, + {"(DotNode).Position", Method, 1}, + {"(FieldNode).Position", Method, 1}, + {"(FieldNode).Type", Method, 0}, + {"(IdentifierNode).Position", Method, 1}, + {"(IdentifierNode).Type", Method, 0}, + {"(IfNode).Position", Method, 1}, + {"(IfNode).Type", Method, 0}, + {"(ListNode).Position", Method, 1}, + {"(ListNode).Type", Method, 0}, + {"(NilNode).Position", Method, 1}, + {"(NodeType).Type", Method, 0}, + {"(NumberNode).Position", Method, 1}, + {"(NumberNode).Type", Method, 0}, + {"(PipeNode).Position", Method, 1}, + {"(PipeNode).Type", Method, 0}, + {"(Pos).Position", Method, 1}, + {"(RangeNode).Position", Method, 1}, + {"(RangeNode).Type", Method, 0}, + {"(StringNode).Position", Method, 1}, + {"(StringNode).Type", Method, 0}, + {"(TemplateNode).Position", Method, 1}, + {"(TemplateNode).Type", Method, 0}, + {"(TextNode).Position", Method, 1}, + {"(TextNode).Type", Method, 0}, + {"(VariableNode).Position", Method, 1}, + {"(VariableNode).Type", Method, 0}, + {"(WithNode).Position", Method, 1}, + {"(WithNode).Type", Method, 0}, + {"ActionNode", Type, 0}, + {"ActionNode.Line", Field, 0}, + {"ActionNode.NodeType", Field, 0}, + {"ActionNode.Pipe", Field, 0}, + {"ActionNode.Pos", Field, 1}, + {"BoolNode", Type, 0}, + {"BoolNode.NodeType", Field, 0}, + {"BoolNode.Pos", Field, 1}, + {"BoolNode.True", Field, 0}, + {"BranchNode", Type, 0}, + {"BranchNode.ElseList", Field, 0}, + {"BranchNode.Line", Field, 0}, + {"BranchNode.List", Field, 0}, + {"BranchNode.NodeType", Field, 0}, + {"BranchNode.Pipe", Field, 0}, + {"BranchNode.Pos", Field, 1}, + {"BreakNode", Type, 18}, + {"BreakNode.Line", Field, 18}, + {"BreakNode.NodeType", Field, 18}, + {"BreakNode.Pos", Field, 18}, + {"ChainNode", Type, 1}, + {"ChainNode.Field", Field, 1}, + {"ChainNode.Node", Field, 1}, + {"ChainNode.NodeType", Field, 1}, + {"ChainNode.Pos", Field, 1}, + {"CommandNode", Type, 0}, + {"CommandNode.Args", Field, 0}, + {"CommandNode.NodeType", Field, 0}, + {"CommandNode.Pos", Field, 1}, + {"CommentNode", Type, 16}, + {"CommentNode.NodeType", Field, 16}, + {"CommentNode.Pos", Field, 16}, + {"CommentNode.Text", Field, 16}, + {"ContinueNode", Type, 18}, + {"ContinueNode.Line", Field, 18}, + {"ContinueNode.NodeType", Field, 18}, + {"ContinueNode.Pos", Field, 18}, + {"DotNode", Type, 0}, + {"DotNode.NodeType", Field, 4}, + {"DotNode.Pos", Field, 1}, + {"FieldNode", Type, 0}, + {"FieldNode.Ident", Field, 0}, + {"FieldNode.NodeType", Field, 0}, + {"FieldNode.Pos", Field, 1}, + {"IdentifierNode", Type, 0}, + {"IdentifierNode.Ident", Field, 0}, + {"IdentifierNode.NodeType", Field, 0}, + {"IdentifierNode.Pos", Field, 1}, + {"IfNode", Type, 0}, + {"IfNode.BranchNode", Field, 0}, + {"IsEmptyTree", Func, 0}, + {"ListNode", Type, 0}, + {"ListNode.NodeType", Field, 0}, + {"ListNode.Nodes", Field, 0}, + {"ListNode.Pos", Field, 1}, + {"Mode", Type, 16}, + {"New", Func, 0}, + {"NewIdentifier", Func, 0}, + {"NilNode", Type, 1}, + {"NilNode.NodeType", Field, 4}, + {"NilNode.Pos", Field, 1}, + {"Node", Type, 0}, + {"NodeAction", Const, 0}, + {"NodeBool", Const, 0}, + {"NodeBreak", Const, 18}, + {"NodeChain", Const, 1}, + {"NodeCommand", Const, 0}, + {"NodeComment", Const, 16}, + {"NodeContinue", Const, 18}, + {"NodeDot", Const, 0}, + {"NodeField", Const, 0}, + {"NodeIdentifier", Const, 0}, + {"NodeIf", Const, 0}, + {"NodeList", Const, 0}, + {"NodeNil", Const, 1}, + {"NodeNumber", Const, 0}, + {"NodePipe", Const, 0}, + {"NodeRange", Const, 0}, + {"NodeString", Const, 0}, + {"NodeTemplate", Const, 0}, + {"NodeText", Const, 0}, + {"NodeType", Type, 0}, + {"NodeVariable", Const, 0}, + {"NodeWith", Const, 0}, + {"NumberNode", Type, 0}, + {"NumberNode.Complex128", Field, 0}, + {"NumberNode.Float64", Field, 0}, + {"NumberNode.Int64", Field, 0}, + {"NumberNode.IsComplex", Field, 0}, + {"NumberNode.IsFloat", Field, 0}, + {"NumberNode.IsInt", Field, 0}, + {"NumberNode.IsUint", Field, 0}, + {"NumberNode.NodeType", Field, 0}, + {"NumberNode.Pos", Field, 1}, + {"NumberNode.Text", Field, 0}, + {"NumberNode.Uint64", Field, 0}, + {"Parse", Func, 0}, + {"ParseComments", Const, 16}, + {"PipeNode", Type, 0}, + {"PipeNode.Cmds", Field, 0}, + {"PipeNode.Decl", Field, 0}, + {"PipeNode.IsAssign", Field, 11}, + {"PipeNode.Line", Field, 0}, + {"PipeNode.NodeType", Field, 0}, + {"PipeNode.Pos", Field, 1}, + {"Pos", Type, 1}, + {"RangeNode", Type, 0}, + {"RangeNode.BranchNode", Field, 0}, + {"SkipFuncCheck", Const, 17}, + {"StringNode", Type, 0}, + {"StringNode.NodeType", Field, 0}, + {"StringNode.Pos", Field, 1}, + {"StringNode.Quoted", Field, 0}, + {"StringNode.Text", Field, 0}, + {"TemplateNode", Type, 0}, + {"TemplateNode.Line", Field, 0}, + {"TemplateNode.Name", Field, 0}, + {"TemplateNode.NodeType", Field, 0}, + {"TemplateNode.Pipe", Field, 0}, + {"TemplateNode.Pos", Field, 1}, + {"TextNode", Type, 0}, + {"TextNode.NodeType", Field, 0}, + {"TextNode.Pos", Field, 1}, + {"TextNode.Text", Field, 0}, + {"Tree", Type, 0}, + {"Tree.Mode", Field, 16}, + {"Tree.Name", Field, 0}, + {"Tree.ParseName", Field, 1}, + {"Tree.Root", Field, 0}, + {"VariableNode", Type, 0}, + {"VariableNode.Ident", Field, 0}, + {"VariableNode.NodeType", Field, 0}, + {"VariableNode.Pos", Field, 1}, + {"WithNode", Type, 0}, + {"WithNode.BranchNode", Field, 0}, + }, + "time": { + {"(*Location).String", Method, 0}, + {"(*ParseError).Error", Method, 0}, + {"(*Ticker).Reset", Method, 15}, + {"(*Ticker).Stop", Method, 0}, + {"(*Time).GobDecode", Method, 0}, + {"(*Time).UnmarshalBinary", Method, 2}, + {"(*Time).UnmarshalJSON", Method, 0}, + {"(*Time).UnmarshalText", Method, 2}, + {"(*Timer).Reset", Method, 1}, + {"(*Timer).Stop", Method, 0}, + {"(Duration).Abs", Method, 19}, + {"(Duration).Hours", Method, 0}, + {"(Duration).Microseconds", Method, 13}, + {"(Duration).Milliseconds", Method, 13}, + {"(Duration).Minutes", Method, 0}, + {"(Duration).Nanoseconds", Method, 0}, + {"(Duration).Round", Method, 9}, + {"(Duration).Seconds", Method, 0}, + {"(Duration).String", Method, 0}, + {"(Duration).Truncate", Method, 9}, + {"(Month).String", Method, 0}, + {"(Time).Add", Method, 0}, + {"(Time).AddDate", Method, 0}, + {"(Time).After", Method, 0}, + {"(Time).AppendFormat", Method, 5}, + {"(Time).Before", Method, 0}, + {"(Time).Clock", Method, 0}, + {"(Time).Compare", Method, 20}, + {"(Time).Date", Method, 0}, + {"(Time).Day", Method, 0}, + {"(Time).Equal", Method, 0}, + {"(Time).Format", Method, 0}, + {"(Time).GoString", Method, 17}, + {"(Time).GobEncode", Method, 0}, + {"(Time).Hour", Method, 0}, + {"(Time).ISOWeek", Method, 0}, + {"(Time).In", Method, 0}, + {"(Time).IsDST", Method, 17}, + {"(Time).IsZero", Method, 0}, + {"(Time).Local", Method, 0}, + {"(Time).Location", Method, 0}, + {"(Time).MarshalBinary", Method, 2}, + {"(Time).MarshalJSON", Method, 0}, + {"(Time).MarshalText", Method, 2}, + {"(Time).Minute", Method, 0}, + {"(Time).Month", Method, 0}, + {"(Time).Nanosecond", Method, 0}, + {"(Time).Round", Method, 1}, + {"(Time).Second", Method, 0}, + {"(Time).String", Method, 0}, + {"(Time).Sub", Method, 0}, + {"(Time).Truncate", Method, 1}, + {"(Time).UTC", Method, 0}, + {"(Time).Unix", Method, 0}, + {"(Time).UnixMicro", Method, 17}, + {"(Time).UnixMilli", Method, 17}, + {"(Time).UnixNano", Method, 0}, + {"(Time).Weekday", Method, 0}, + {"(Time).Year", Method, 0}, + {"(Time).YearDay", Method, 1}, + {"(Time).Zone", Method, 0}, + {"(Time).ZoneBounds", Method, 19}, + {"(Weekday).String", Method, 0}, + {"ANSIC", Const, 0}, + {"After", Func, 0}, + {"AfterFunc", Func, 0}, + {"April", Const, 0}, + {"August", Const, 0}, + {"Date", Func, 0}, + {"DateOnly", Const, 20}, + {"DateTime", Const, 20}, + {"December", Const, 0}, + {"Duration", Type, 0}, + {"February", Const, 0}, + {"FixedZone", Func, 0}, + {"Friday", Const, 0}, + {"Hour", Const, 0}, + {"January", Const, 0}, + {"July", Const, 0}, + {"June", Const, 0}, + {"Kitchen", Const, 0}, + {"Layout", Const, 17}, + {"LoadLocation", Func, 0}, + {"LoadLocationFromTZData", Func, 10}, + {"Local", Var, 0}, + {"Location", Type, 0}, + {"March", Const, 0}, + {"May", Const, 0}, + {"Microsecond", Const, 0}, + {"Millisecond", Const, 0}, + {"Minute", Const, 0}, + {"Monday", Const, 0}, + {"Month", Type, 0}, + {"Nanosecond", Const, 0}, + {"NewTicker", Func, 0}, + {"NewTimer", Func, 0}, + {"November", Const, 0}, + {"Now", Func, 0}, + {"October", Const, 0}, + {"Parse", Func, 0}, + {"ParseDuration", Func, 0}, + {"ParseError", Type, 0}, + {"ParseError.Layout", Field, 0}, + {"ParseError.LayoutElem", Field, 0}, + {"ParseError.Message", Field, 0}, + {"ParseError.Value", Field, 0}, + {"ParseError.ValueElem", Field, 0}, + {"ParseInLocation", Func, 1}, + {"RFC1123", Const, 0}, + {"RFC1123Z", Const, 0}, + {"RFC3339", Const, 0}, + {"RFC3339Nano", Const, 0}, + {"RFC822", Const, 0}, + {"RFC822Z", Const, 0}, + {"RFC850", Const, 0}, + {"RubyDate", Const, 0}, + {"Saturday", Const, 0}, + {"Second", Const, 0}, + {"September", Const, 0}, + {"Since", Func, 0}, + {"Sleep", Func, 0}, + {"Stamp", Const, 0}, + {"StampMicro", Const, 0}, + {"StampMilli", Const, 0}, + {"StampNano", Const, 0}, + {"Sunday", Const, 0}, + {"Thursday", Const, 0}, + {"Tick", Func, 0}, + {"Ticker", Type, 0}, + {"Ticker.C", Field, 0}, + {"Time", Type, 0}, + {"TimeOnly", Const, 20}, + {"Timer", Type, 0}, + {"Timer.C", Field, 0}, + {"Tuesday", Const, 0}, + {"UTC", Var, 0}, + {"Unix", Func, 0}, + {"UnixDate", Const, 0}, + {"UnixMicro", Func, 17}, + {"UnixMilli", Func, 17}, + {"Until", Func, 8}, + {"Wednesday", Const, 0}, + {"Weekday", Type, 0}, + }, + "unicode": { + {"(SpecialCase).ToLower", Method, 0}, + {"(SpecialCase).ToTitle", Method, 0}, + {"(SpecialCase).ToUpper", Method, 0}, + {"ASCII_Hex_Digit", Var, 0}, + {"Adlam", Var, 7}, + {"Ahom", Var, 5}, + {"Anatolian_Hieroglyphs", Var, 5}, + {"Arabic", Var, 0}, + {"Armenian", Var, 0}, + {"Avestan", Var, 0}, + {"AzeriCase", Var, 0}, + {"Balinese", Var, 0}, + {"Bamum", Var, 0}, + {"Bassa_Vah", Var, 4}, + {"Batak", Var, 0}, + {"Bengali", Var, 0}, + {"Bhaiksuki", Var, 7}, + {"Bidi_Control", Var, 0}, + {"Bopomofo", Var, 0}, + {"Brahmi", Var, 0}, + {"Braille", Var, 0}, + {"Buginese", Var, 0}, + {"Buhid", Var, 0}, + {"C", Var, 0}, + {"Canadian_Aboriginal", Var, 0}, + {"Carian", Var, 0}, + {"CaseRange", Type, 0}, + {"CaseRange.Delta", Field, 0}, + {"CaseRange.Hi", Field, 0}, + {"CaseRange.Lo", Field, 0}, + {"CaseRanges", Var, 0}, + {"Categories", Var, 0}, + {"Caucasian_Albanian", Var, 4}, + {"Cc", Var, 0}, + {"Cf", Var, 0}, + {"Chakma", Var, 1}, + {"Cham", Var, 0}, + {"Cherokee", Var, 0}, + {"Chorasmian", Var, 16}, + {"Co", Var, 0}, + {"Common", Var, 0}, + {"Coptic", Var, 0}, + {"Cs", Var, 0}, + {"Cuneiform", Var, 0}, + {"Cypriot", Var, 0}, + {"Cypro_Minoan", Var, 21}, + {"Cyrillic", Var, 0}, + {"Dash", Var, 0}, + {"Deprecated", Var, 0}, + {"Deseret", Var, 0}, + {"Devanagari", Var, 0}, + {"Diacritic", Var, 0}, + {"Digit", Var, 0}, + {"Dives_Akuru", Var, 16}, + {"Dogra", Var, 13}, + {"Duployan", Var, 4}, + {"Egyptian_Hieroglyphs", Var, 0}, + {"Elbasan", Var, 4}, + {"Elymaic", Var, 14}, + {"Ethiopic", Var, 0}, + {"Extender", Var, 0}, + {"FoldCategory", Var, 0}, + {"FoldScript", Var, 0}, + {"Georgian", Var, 0}, + {"Glagolitic", Var, 0}, + {"Gothic", Var, 0}, + {"Grantha", Var, 4}, + {"GraphicRanges", Var, 0}, + {"Greek", Var, 0}, + {"Gujarati", Var, 0}, + {"Gunjala_Gondi", Var, 13}, + {"Gurmukhi", Var, 0}, + {"Han", Var, 0}, + {"Hangul", Var, 0}, + {"Hanifi_Rohingya", Var, 13}, + {"Hanunoo", Var, 0}, + {"Hatran", Var, 5}, + {"Hebrew", Var, 0}, + {"Hex_Digit", Var, 0}, + {"Hiragana", Var, 0}, + {"Hyphen", Var, 0}, + {"IDS_Binary_Operator", Var, 0}, + {"IDS_Trinary_Operator", Var, 0}, + {"Ideographic", Var, 0}, + {"Imperial_Aramaic", Var, 0}, + {"In", Func, 2}, + {"Inherited", Var, 0}, + {"Inscriptional_Pahlavi", Var, 0}, + {"Inscriptional_Parthian", Var, 0}, + {"Is", Func, 0}, + {"IsControl", Func, 0}, + {"IsDigit", Func, 0}, + {"IsGraphic", Func, 0}, + {"IsLetter", Func, 0}, + {"IsLower", Func, 0}, + {"IsMark", Func, 0}, + {"IsNumber", Func, 0}, + {"IsOneOf", Func, 0}, + {"IsPrint", Func, 0}, + {"IsPunct", Func, 0}, + {"IsSpace", Func, 0}, + {"IsSymbol", Func, 0}, + {"IsTitle", Func, 0}, + {"IsUpper", Func, 0}, + {"Javanese", Var, 0}, + {"Join_Control", Var, 0}, + {"Kaithi", Var, 0}, + {"Kannada", Var, 0}, + {"Katakana", Var, 0}, + {"Kawi", Var, 21}, + {"Kayah_Li", Var, 0}, + {"Kharoshthi", Var, 0}, + {"Khitan_Small_Script", Var, 16}, + {"Khmer", Var, 0}, + {"Khojki", Var, 4}, + {"Khudawadi", Var, 4}, + {"L", Var, 0}, + {"Lao", Var, 0}, + {"Latin", Var, 0}, + {"Lepcha", Var, 0}, + {"Letter", Var, 0}, + {"Limbu", Var, 0}, + {"Linear_A", Var, 4}, + {"Linear_B", Var, 0}, + {"Lisu", Var, 0}, + {"Ll", Var, 0}, + {"Lm", Var, 0}, + {"Lo", Var, 0}, + {"Logical_Order_Exception", Var, 0}, + {"Lower", Var, 0}, + {"LowerCase", Const, 0}, + {"Lt", Var, 0}, + {"Lu", Var, 0}, + {"Lycian", Var, 0}, + {"Lydian", Var, 0}, + {"M", Var, 0}, + {"Mahajani", Var, 4}, + {"Makasar", Var, 13}, + {"Malayalam", Var, 0}, + {"Mandaic", Var, 0}, + {"Manichaean", Var, 4}, + {"Marchen", Var, 7}, + {"Mark", Var, 0}, + {"Masaram_Gondi", Var, 10}, + {"MaxASCII", Const, 0}, + {"MaxCase", Const, 0}, + {"MaxLatin1", Const, 0}, + {"MaxRune", Const, 0}, + {"Mc", Var, 0}, + {"Me", Var, 0}, + {"Medefaidrin", Var, 13}, + {"Meetei_Mayek", Var, 0}, + {"Mende_Kikakui", Var, 4}, + {"Meroitic_Cursive", Var, 1}, + {"Meroitic_Hieroglyphs", Var, 1}, + {"Miao", Var, 1}, + {"Mn", Var, 0}, + {"Modi", Var, 4}, + {"Mongolian", Var, 0}, + {"Mro", Var, 4}, + {"Multani", Var, 5}, + {"Myanmar", Var, 0}, + {"N", Var, 0}, + {"Nabataean", Var, 4}, + {"Nag_Mundari", Var, 21}, + {"Nandinagari", Var, 14}, + {"Nd", Var, 0}, + {"New_Tai_Lue", Var, 0}, + {"Newa", Var, 7}, + {"Nko", Var, 0}, + {"Nl", Var, 0}, + {"No", Var, 0}, + {"Noncharacter_Code_Point", Var, 0}, + {"Number", Var, 0}, + {"Nushu", Var, 10}, + {"Nyiakeng_Puachue_Hmong", Var, 14}, + {"Ogham", Var, 0}, + {"Ol_Chiki", Var, 0}, + {"Old_Hungarian", Var, 5}, + {"Old_Italic", Var, 0}, + {"Old_North_Arabian", Var, 4}, + {"Old_Permic", Var, 4}, + {"Old_Persian", Var, 0}, + {"Old_Sogdian", Var, 13}, + {"Old_South_Arabian", Var, 0}, + {"Old_Turkic", Var, 0}, + {"Old_Uyghur", Var, 21}, + {"Oriya", Var, 0}, + {"Osage", Var, 7}, + {"Osmanya", Var, 0}, + {"Other", Var, 0}, + {"Other_Alphabetic", Var, 0}, + {"Other_Default_Ignorable_Code_Point", Var, 0}, + {"Other_Grapheme_Extend", Var, 0}, + {"Other_ID_Continue", Var, 0}, + {"Other_ID_Start", Var, 0}, + {"Other_Lowercase", Var, 0}, + {"Other_Math", Var, 0}, + {"Other_Uppercase", Var, 0}, + {"P", Var, 0}, + {"Pahawh_Hmong", Var, 4}, + {"Palmyrene", Var, 4}, + {"Pattern_Syntax", Var, 0}, + {"Pattern_White_Space", Var, 0}, + {"Pau_Cin_Hau", Var, 4}, + {"Pc", Var, 0}, + {"Pd", Var, 0}, + {"Pe", Var, 0}, + {"Pf", Var, 0}, + {"Phags_Pa", Var, 0}, + {"Phoenician", Var, 0}, + {"Pi", Var, 0}, + {"Po", Var, 0}, + {"Prepended_Concatenation_Mark", Var, 7}, + {"PrintRanges", Var, 0}, + {"Properties", Var, 0}, + {"Ps", Var, 0}, + {"Psalter_Pahlavi", Var, 4}, + {"Punct", Var, 0}, + {"Quotation_Mark", Var, 0}, + {"Radical", Var, 0}, + {"Range16", Type, 0}, + {"Range16.Hi", Field, 0}, + {"Range16.Lo", Field, 0}, + {"Range16.Stride", Field, 0}, + {"Range32", Type, 0}, + {"Range32.Hi", Field, 0}, + {"Range32.Lo", Field, 0}, + {"Range32.Stride", Field, 0}, + {"RangeTable", Type, 0}, + {"RangeTable.LatinOffset", Field, 1}, + {"RangeTable.R16", Field, 0}, + {"RangeTable.R32", Field, 0}, + {"Regional_Indicator", Var, 10}, + {"Rejang", Var, 0}, + {"ReplacementChar", Const, 0}, + {"Runic", Var, 0}, + {"S", Var, 0}, + {"STerm", Var, 0}, + {"Samaritan", Var, 0}, + {"Saurashtra", Var, 0}, + {"Sc", Var, 0}, + {"Scripts", Var, 0}, + {"Sentence_Terminal", Var, 7}, + {"Sharada", Var, 1}, + {"Shavian", Var, 0}, + {"Siddham", Var, 4}, + {"SignWriting", Var, 5}, + {"SimpleFold", Func, 0}, + {"Sinhala", Var, 0}, + {"Sk", Var, 0}, + {"Sm", Var, 0}, + {"So", Var, 0}, + {"Soft_Dotted", Var, 0}, + {"Sogdian", Var, 13}, + {"Sora_Sompeng", Var, 1}, + {"Soyombo", Var, 10}, + {"Space", Var, 0}, + {"SpecialCase", Type, 0}, + {"Sundanese", Var, 0}, + {"Syloti_Nagri", Var, 0}, + {"Symbol", Var, 0}, + {"Syriac", Var, 0}, + {"Tagalog", Var, 0}, + {"Tagbanwa", Var, 0}, + {"Tai_Le", Var, 0}, + {"Tai_Tham", Var, 0}, + {"Tai_Viet", Var, 0}, + {"Takri", Var, 1}, + {"Tamil", Var, 0}, + {"Tangsa", Var, 21}, + {"Tangut", Var, 7}, + {"Telugu", Var, 0}, + {"Terminal_Punctuation", Var, 0}, + {"Thaana", Var, 0}, + {"Thai", Var, 0}, + {"Tibetan", Var, 0}, + {"Tifinagh", Var, 0}, + {"Tirhuta", Var, 4}, + {"Title", Var, 0}, + {"TitleCase", Const, 0}, + {"To", Func, 0}, + {"ToLower", Func, 0}, + {"ToTitle", Func, 0}, + {"ToUpper", Func, 0}, + {"Toto", Var, 21}, + {"TurkishCase", Var, 0}, + {"Ugaritic", Var, 0}, + {"Unified_Ideograph", Var, 0}, + {"Upper", Var, 0}, + {"UpperCase", Const, 0}, + {"UpperLower", Const, 0}, + {"Vai", Var, 0}, + {"Variation_Selector", Var, 0}, + {"Version", Const, 0}, + {"Vithkuqi", Var, 21}, + {"Wancho", Var, 14}, + {"Warang_Citi", Var, 4}, + {"White_Space", Var, 0}, + {"Yezidi", Var, 16}, + {"Yi", Var, 0}, + {"Z", Var, 0}, + {"Zanabazar_Square", Var, 10}, + {"Zl", Var, 0}, + {"Zp", Var, 0}, + {"Zs", Var, 0}, + }, + "unicode/utf16": { + {"AppendRune", Func, 20}, + {"Decode", Func, 0}, + {"DecodeRune", Func, 0}, + {"Encode", Func, 0}, + {"EncodeRune", Func, 0}, + {"IsSurrogate", Func, 0}, + {"RuneLen", Func, 23}, + }, + "unicode/utf8": { + {"AppendRune", Func, 18}, + {"DecodeLastRune", Func, 0}, + {"DecodeLastRuneInString", Func, 0}, + {"DecodeRune", Func, 0}, + {"DecodeRuneInString", Func, 0}, + {"EncodeRune", Func, 0}, + {"FullRune", Func, 0}, + {"FullRuneInString", Func, 0}, + {"MaxRune", Const, 0}, + {"RuneCount", Func, 0}, + {"RuneCountInString", Func, 0}, + {"RuneError", Const, 0}, + {"RuneLen", Func, 0}, + {"RuneSelf", Const, 0}, + {"RuneStart", Func, 0}, + {"UTFMax", Const, 0}, + {"Valid", Func, 0}, + {"ValidRune", Func, 1}, + {"ValidString", Func, 0}, + }, + "unique": { + {"(Handle).Value", Method, 23}, + {"Handle", Type, 23}, + {"Make", Func, 23}, + }, + "unsafe": { + {"Add", Func, 0}, + {"Alignof", Func, 0}, + {"Offsetof", Func, 0}, + {"Pointer", Type, 0}, + {"Sizeof", Func, 0}, + {"Slice", Func, 0}, + {"SliceData", Func, 0}, + {"String", Func, 0}, + {"StringData", Func, 0}, + }, +} diff --git a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go new file mode 100644 index 0000000000..98904017f2 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go @@ -0,0 +1,97 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run generate.go + +// Package stdlib provides a table of all exported symbols in the +// standard library, along with the version at which they first +// appeared. +package stdlib + +import ( + "fmt" + "strings" +) + +type Symbol struct { + Name string + Kind Kind + Version Version // Go version that first included the symbol +} + +// A Kind indicates the kind of a symbol: +// function, variable, constant, type, and so on. +type Kind int8 + +const ( + Invalid Kind = iota // Example name: + Type // "Buffer" + Func // "Println" + Var // "EOF" + Const // "Pi" + Field // "Point.X" + Method // "(*Buffer).Grow" +) + +func (kind Kind) String() string { + return [...]string{ + Invalid: "invalid", + Type: "type", + Func: "func", + Var: "var", + Const: "const", + Field: "field", + Method: "method", + }[kind] +} + +// A Version represents a version of Go of the form "go1.%d". +type Version int8 + +// String returns a version string of the form "go1.23", without allocating. +func (v Version) String() string { return versions[v] } + +var versions [30]string // (increase constant as needed) + +func init() { + for i := range versions { + versions[i] = fmt.Sprintf("go1.%d", i) + } +} + +// HasPackage reports whether the specified package path is part of +// the standard library's public API. +func HasPackage(path string) bool { + _, ok := PackageSymbols[path] + return ok +} + +// SplitField splits the field symbol name into type and field +// components. It must be called only on Field symbols. +// +// Example: "File.Package" -> ("File", "Package") +func (sym *Symbol) SplitField() (typename, name string) { + if sym.Kind != Field { + panic("not a field") + } + typename, name, _ = strings.Cut(sym.Name, ".") + return +} + +// SplitMethod splits the method symbol name into pointer, receiver, +// and method components. It must be called only on Method symbols. +// +// Example: "(*Buffer).Grow" -> (true, "Buffer", "Grow") +func (sym *Symbol) SplitMethod() (ptr bool, recv, name string) { + if sym.Kind != Method { + panic("not a method") + } + recv, name, _ = strings.Cut(sym.Name, ".") + recv = recv[len("(") : len(recv)-len(")")] + ptr = recv[0] == '*' + if ptr { + recv = recv[len("*"):] + } + return +} diff --git a/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go b/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go index 7e638ec24f..ff9437a36c 100644 --- a/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go +++ b/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go @@ -34,30 +34,16 @@ func GetLines(file *token.File) []int { lines []int _ []struct{} } - type tokenFile118 struct { - _ *token.FileSet // deleted in go1.19 - tokenFile119 - } - - type uP = unsafe.Pointer - switch unsafe.Sizeof(*file) { - case unsafe.Sizeof(tokenFile118{}): - var ptr *tokenFile118 - *(*uP)(uP(&ptr)) = uP(file) - ptr.mu.Lock() - defer ptr.mu.Unlock() - return ptr.lines - case unsafe.Sizeof(tokenFile119{}): - var ptr *tokenFile119 - *(*uP)(uP(&ptr)) = uP(file) - ptr.mu.Lock() - defer ptr.mu.Unlock() - return ptr.lines - - default: + if unsafe.Sizeof(*file) != unsafe.Sizeof(tokenFile119{}) { panic("unexpected token.File size") } + var ptr *tokenFile119 + type uP = unsafe.Pointer + *(*uP)(uP(&ptr)) = uP(file) + ptr.mu.Lock() + defer ptr.mu.Unlock() + return ptr.lines } // AddExistingFiles adds the specified files to the FileSet if they diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go deleted file mode 100644 index d0d0649fe2..0000000000 --- a/vendor/golang.org/x/tools/internal/typeparams/common.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package typeparams contains common utilities for writing tools that interact -// with generic Go code, as introduced with Go 1.18. -// -// Many of the types and functions in this package are proxies for the new APIs -// introduced in the standard library with Go 1.18. For example, the -// typeparams.Union type is an alias for go/types.Union, and the ForTypeSpec -// function returns the value of the go/ast.TypeSpec.TypeParams field. At Go -// versions older than 1.18 these helpers are implemented as stubs, allowing -// users of this package to write code that handles generic constructs inline, -// even if the Go version being used to compile does not support generics. -// -// Additionally, this package contains common utilities for working with the -// new generic constructs, to supplement the standard library APIs. Notably, -// the StructuralTerms API computes a minimal representation of the structural -// restrictions on a type parameter. -// -// An external version of these APIs is available in the -// golang.org/x/exp/typeparams module. -package typeparams - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" -) - -// UnpackIndexExpr extracts data from AST nodes that represent index -// expressions. -// -// For an ast.IndexExpr, the resulting indices slice will contain exactly one -// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable -// number of index expressions. -// -// For nodes that don't represent index expressions, the first return value of -// UnpackIndexExpr will be nil. -func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) { - switch e := n.(type) { - case *ast.IndexExpr: - return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack - case *IndexListExpr: - return e.X, e.Lbrack, e.Indices, e.Rbrack - } - return nil, token.NoPos, nil, token.NoPos -} - -// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on -// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0 -// will panic. -func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr { - switch len(indices) { - case 0: - panic("empty indices") - case 1: - return &ast.IndexExpr{ - X: x, - Lbrack: lbrack, - Index: indices[0], - Rbrack: rbrack, - } - default: - return &IndexListExpr{ - X: x, - Lbrack: lbrack, - Indices: indices, - Rbrack: rbrack, - } - } -} - -// IsTypeParam reports whether t is a type parameter. -func IsTypeParam(t types.Type) bool { - _, ok := t.(*TypeParam) - return ok -} - -// OriginMethod returns the origin method associated with the method fn. -// For methods on a non-generic receiver base type, this is just -// fn. However, for methods with a generic receiver, OriginMethod returns the -// corresponding method in the method set of the origin type. -// -// As a special case, if fn is not a method (has no receiver), OriginMethod -// returns fn. -func OriginMethod(fn *types.Func) *types.Func { - recv := fn.Type().(*types.Signature).Recv() - if recv == nil { - return fn - } - base := recv.Type() - p, isPtr := base.(*types.Pointer) - if isPtr { - base = p.Elem() - } - named, isNamed := base.(*types.Named) - if !isNamed { - // Receiver is a *types.Interface. - return fn - } - if ForNamed(named).Len() == 0 { - // Receiver base has no type parameters, so we can avoid the lookup below. - return fn - } - orig := NamedTypeOrigin(named) - gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name()) - - // This is a fix for a gopls crash (#60628) due to a go/types bug (#60634). In: - // package p - // type T *int - // func (*T) f() {} - // LookupFieldOrMethod(T, true, p, f)=nil, but NewMethodSet(*T)={(*T).f}. - // Here we make them consistent by force. - // (The go/types bug is general, but this workaround is reached only - // for generic T thanks to the early return above.) - if gfn == nil { - mset := types.NewMethodSet(types.NewPointer(orig)) - for i := 0; i < mset.Len(); i++ { - m := mset.At(i) - if m.Obj().Id() == fn.Id() { - gfn = m.Obj() - break - } - } - } - - // In golang/go#61196, we observe another crash, this time inexplicable. - if gfn == nil { - panic(fmt.Sprintf("missing origin method for %s.%s; named == origin: %t, named.NumMethods(): %d, origin.NumMethods(): %d", named, fn, named == orig, named.NumMethods(), orig.NumMethods())) - } - - return gfn.(*types.Func) -} - -// GenericAssignableTo is a generalization of types.AssignableTo that -// implements the following rule for uninstantiated generic types: -// -// If V and T are generic named types, then V is considered assignable to T if, -// for every possible instantation of V[A_1, ..., A_N], the instantiation -// T[A_1, ..., A_N] is valid and V[A_1, ..., A_N] implements T[A_1, ..., A_N]. -// -// If T has structural constraints, they must be satisfied by V. -// -// For example, consider the following type declarations: -// -// type Interface[T any] interface { -// Accept(T) -// } -// -// type Container[T any] struct { -// Element T -// } -// -// func (c Container[T]) Accept(t T) { c.Element = t } -// -// In this case, GenericAssignableTo reports that instantiations of Container -// are assignable to the corresponding instantiation of Interface. -func GenericAssignableTo(ctxt *Context, V, T types.Type) bool { - // If V and T are not both named, or do not have matching non-empty type - // parameter lists, fall back on types.AssignableTo. - - VN, Vnamed := V.(*types.Named) - TN, Tnamed := T.(*types.Named) - if !Vnamed || !Tnamed { - return types.AssignableTo(V, T) - } - - vtparams := ForNamed(VN) - ttparams := ForNamed(TN) - if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || NamedTypeArgs(VN).Len() != 0 || NamedTypeArgs(TN).Len() != 0 { - return types.AssignableTo(V, T) - } - - // V and T have the same (non-zero) number of type params. Instantiate both - // with the type parameters of V. This must always succeed for V, and will - // succeed for T if and only if the type set of each type parameter of V is a - // subset of the type set of the corresponding type parameter of T, meaning - // that every instantiation of V corresponds to a valid instantiation of T. - - // Minor optimization: ensure we share a context across the two - // instantiations below. - if ctxt == nil { - ctxt = NewContext() - } - - var targs []types.Type - for i := 0; i < vtparams.Len(); i++ { - targs = append(targs, vtparams.At(i)) - } - - vinst, err := Instantiate(ctxt, V, targs, true) - if err != nil { - panic("type parameters should satisfy their own constraints") - } - - tinst, err := Instantiate(ctxt, T, targs, true) - if err != nil { - return false - } - - return types.AssignableTo(vinst, tinst) -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go deleted file mode 100644 index 71248209ee..0000000000 --- a/vendor/golang.org/x/tools/internal/typeparams/coretype.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeparams - -import ( - "go/types" -) - -// CoreType returns the core type of T or nil if T does not have a core type. -// -// See https://go.dev/ref/spec#Core_types for the definition of a core type. -func CoreType(T types.Type) types.Type { - U := T.Underlying() - if _, ok := U.(*types.Interface); !ok { - return U // for non-interface types, - } - - terms, err := _NormalTerms(U) - if len(terms) == 0 || err != nil { - // len(terms) -> empty type set of interface. - // err != nil => U is invalid, exceeds complexity bounds, or has an empty type set. - return nil // no core type. - } - - U = terms[0].Type().Underlying() - var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying()) - for identical = 1; identical < len(terms); identical++ { - if !types.Identical(U, terms[identical].Type().Underlying()) { - break - } - } - - if identical == len(terms) { - // https://go.dev/ref/spec#Core_types - // "There is a single type U which is the underlying type of all types in the type set of T" - return U - } - ch, ok := U.(*types.Chan) - if !ok { - return nil // no core type as identical < len(terms) and U is not a channel. - } - // https://go.dev/ref/spec#Core_types - // "the type chan E if T contains only bidirectional channels, or the type chan<- E or - // <-chan E depending on the direction of the directional channels present." - for chans := identical; chans < len(terms); chans++ { - curr, ok := terms[chans].Type().Underlying().(*types.Chan) - if !ok { - return nil - } - if !types.Identical(ch.Elem(), curr.Elem()) { - return nil // channel elements are not identical. - } - if ch.Dir() == types.SendRecv { - // ch is bidirectional. We can safely always use curr's direction. - ch = curr - } else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() { - // ch and curr are not bidirectional and not the same direction. - return nil - } - } - return ch -} - -// _NormalTerms returns a slice of terms representing the normalized structural -// type restrictions of a type, if any. -// -// For all types other than *types.TypeParam, *types.Interface, and -// *types.Union, this is just a single term with Tilde() == false and -// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see -// below. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration type -// T[P interface{~int; m()}] int the structural restriction of the type -// parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// _NormalTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, _NormalTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the type is -// invalid, exceeds complexity bounds, or has an empty type set. In the latter -// case, _NormalTerms returns ErrEmptyTypeSet. -// -// _NormalTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func _NormalTerms(typ types.Type) ([]*Term, error) { - switch typ := typ.(type) { - case *TypeParam: - return StructuralTerms(typ) - case *Union: - return UnionTermSet(typ) - case *types.Interface: - return InterfaceTermSet(typ) - default: - return []*Term{NewTerm(false, typ)}, nil - } -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go b/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go deleted file mode 100644 index 18212390e1..0000000000 --- a/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.18 -// +build !go1.18 - -package typeparams - -// Enabled reports whether type parameters are enabled in the current build -// environment. -const Enabled = false diff --git a/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go b/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go deleted file mode 100644 index d67148823c..0000000000 --- a/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.18 -// +build go1.18 - -package typeparams - -// Note: this constant is in a separate file as this is the only acceptable -// diff between the <1.18 API of this package and the 1.18 API. - -// Enabled reports whether type parameters are enabled in the current build -// environment. -const Enabled = true diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go deleted file mode 100644 index 9c631b6512..0000000000 --- a/vendor/golang.org/x/tools/internal/typeparams/normalize.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeparams - -import ( - "errors" - "fmt" - "go/types" - "os" - "strings" -) - -//go:generate go run copytermlist.go - -const debug = false - -var ErrEmptyTypeSet = errors.New("empty type set") - -// StructuralTerms returns a slice of terms representing the normalized -// structural type restrictions of a type parameter, if any. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration -// -// type T[P interface{~int; m()}] int -// -// the structural restriction of the type parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// StructuralTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, StructuralTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the -// constraint interface is invalid, exceeds complexity bounds, or has an empty -// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. -// -// StructuralTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func StructuralTerms(tparam *TypeParam) ([]*Term, error) { - constraint := tparam.Constraint() - if constraint == nil { - return nil, fmt.Errorf("%s has nil constraint", tparam) - } - iface, _ := constraint.Underlying().(*types.Interface) - if iface == nil { - return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) - } - return InterfaceTermSet(iface) -} - -// InterfaceTermSet computes the normalized terms for a constraint interface, -// returning an error if the term set cannot be computed or is empty. In the -// latter case, the error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func InterfaceTermSet(iface *types.Interface) ([]*Term, error) { - return computeTermSet(iface) -} - -// UnionTermSet computes the normalized terms for a union, returning an error -// if the term set cannot be computed or is empty. In the latter case, the -// error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func UnionTermSet(union *Union) ([]*Term, error) { - return computeTermSet(union) -} - -func computeTermSet(typ types.Type) ([]*Term, error) { - tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) - if err != nil { - return nil, err - } - if tset.terms.isEmpty() { - return nil, ErrEmptyTypeSet - } - if tset.terms.isAll() { - return nil, nil - } - var terms []*Term - for _, term := range tset.terms { - terms = append(terms, NewTerm(term.tilde, term.typ)) - } - return terms, nil -} - -// A termSet holds the normalized set of terms for a given type. -// -// The name termSet is intentionally distinct from 'type set': a type set is -// all types that implement a type (and includes method restrictions), whereas -// a term set just represents the structural restrictions on a type. -type termSet struct { - complete bool - terms termlist -} - -func indentf(depth int, format string, args ...interface{}) { - fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) -} - -func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { - if t == nil { - panic("nil type") - } - - if debug { - indentf(depth, "%s", t.String()) - defer func() { - if err != nil { - indentf(depth, "=> %s", err) - } else { - indentf(depth, "=> %s", res.terms.String()) - } - }() - } - - const maxTermCount = 100 - if tset, ok := seen[t]; ok { - if !tset.complete { - return nil, fmt.Errorf("cycle detected in the declaration of %s", t) - } - return tset, nil - } - - // Mark the current type as seen to avoid infinite recursion. - tset := new(termSet) - defer func() { - tset.complete = true - }() - seen[t] = tset - - switch u := t.Underlying().(type) { - case *types.Interface: - // The term set of an interface is the intersection of the term sets of its - // embedded types. - tset.terms = allTermlist - for i := 0; i < u.NumEmbeddeds(); i++ { - embedded := u.EmbeddedType(i) - if _, ok := embedded.Underlying().(*TypeParam); ok { - return nil, fmt.Errorf("invalid embedded type %T", embedded) - } - tset2, err := computeTermSetInternal(embedded, seen, depth+1) - if err != nil { - return nil, err - } - tset.terms = tset.terms.intersect(tset2.terms) - } - case *Union: - // The term set of a union is the union of term sets of its terms. - tset.terms = nil - for i := 0; i < u.Len(); i++ { - t := u.Term(i) - var terms termlist - switch t.Type().Underlying().(type) { - case *types.Interface: - tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) - if err != nil { - return nil, err - } - terms = tset2.terms - case *TypeParam, *Union: - // A stand-alone type parameter or union is not permitted as union - // term. - return nil, fmt.Errorf("invalid union term %T", t) - default: - if t.Type() == types.Typ[types.Invalid] { - continue - } - terms = termlist{{t.Tilde(), t.Type()}} - } - tset.terms = tset.terms.union(terms) - if len(tset.terms) > maxTermCount { - return nil, fmt.Errorf("exceeded max term count %d", maxTermCount) - } - } - case *TypeParam: - panic("unreachable") - default: - // For all other types, the term set is just a single non-tilde term - // holding the type itself. - if u != types.Typ[types.Invalid] { - tset.terms = termlist{{false, t}} - } - } - return tset, nil -} - -// under is a facade for the go/types internal function of the same name. It is -// used by typeterm.go. -func under(t types.Type) types.Type { - return t.Underlying() -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/termlist.go b/vendor/golang.org/x/tools/internal/typeparams/termlist.go deleted file mode 100644 index cbd12f8013..0000000000 --- a/vendor/golang.org/x/tools/internal/typeparams/termlist.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import ( - "bytes" - "go/types" -) - -// A termlist represents the type set represented by the union -// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn. -// A termlist is in normal form if all terms are disjoint. -// termlist operations don't require the operands to be in -// normal form. -type termlist []*term - -// allTermlist represents the set of all types. -// It is in normal form. -var allTermlist = termlist{new(term)} - -// String prints the termlist exactly (without normalization). -func (xl termlist) String() string { - if len(xl) == 0 { - return "∅" - } - var buf bytes.Buffer - for i, x := range xl { - if i > 0 { - buf.WriteString(" | ") - } - buf.WriteString(x.String()) - } - return buf.String() -} - -// isEmpty reports whether the termlist xl represents the empty set of types. -func (xl termlist) isEmpty() bool { - // If there's a non-nil term, the entire list is not empty. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil { - return false - } - } - return true -} - -// isAll reports whether the termlist xl represents the set of all types. -func (xl termlist) isAll() bool { - // If there's a 𝓤 term, the entire list is 𝓤. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil && x.typ == nil { - return true - } - } - return false -} - -// norm returns the normal form of xl. -func (xl termlist) norm() termlist { - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - used := make([]bool, len(xl)) - var rl termlist - for i, xi := range xl { - if xi == nil || used[i] { - continue - } - for j := i + 1; j < len(xl); j++ { - xj := xl[j] - if xj == nil || used[j] { - continue - } - if u1, u2 := xi.union(xj); u2 == nil { - // If we encounter a 𝓤 term, the entire list is 𝓤. - // Exit early. - // (Note that this is not just an optimization; - // if we continue, we may end up with a 𝓤 term - // and other terms and the result would not be - // in normal form.) - if u1.typ == nil { - return allTermlist - } - xi = u1 - used[j] = true // xj is now unioned into xi - ignore it in future iterations - } - } - rl = append(rl, xi) - } - return rl -} - -// union returns the union xl ∪ yl. -func (xl termlist) union(yl termlist) termlist { - return append(xl, yl...).norm() -} - -// intersect returns the intersection xl ∩ yl. -func (xl termlist) intersect(yl termlist) termlist { - if xl.isEmpty() || yl.isEmpty() { - return nil - } - - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - var rl termlist - for _, x := range xl { - for _, y := range yl { - if r := x.intersect(y); r != nil { - rl = append(rl, r) - } - } - } - return rl.norm() -} - -// equal reports whether xl and yl represent the same type set. -func (xl termlist) equal(yl termlist) bool { - // TODO(gri) this should be more efficient - return xl.subsetOf(yl) && yl.subsetOf(xl) -} - -// includes reports whether t ∈ xl. -func (xl termlist) includes(t types.Type) bool { - for _, x := range xl { - if x.includes(t) { - return true - } - } - return false -} - -// supersetOf reports whether y ⊆ xl. -func (xl termlist) supersetOf(y *term) bool { - for _, x := range xl { - if y.subsetOf(x) { - return true - } - } - return false -} - -// subsetOf reports whether xl ⊆ yl. -func (xl termlist) subsetOf(yl termlist) bool { - if yl.isEmpty() { - return xl.isEmpty() - } - - // each term x of xl must be a subset of yl - for _, x := range xl { - if !yl.supersetOf(x) { - return false // x is not a subset yl - } - } - return true -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go deleted file mode 100644 index 7ed86e1711..0000000000 --- a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.18 -// +build !go1.18 - -package typeparams - -import ( - "go/ast" - "go/token" - "go/types" -) - -func unsupported() { - panic("type parameters are unsupported at this go version") -} - -// IndexListExpr is a placeholder type, as type parameters are not supported at -// this Go version. Its methods panic on use. -type IndexListExpr struct { - ast.Expr - X ast.Expr // expression - Lbrack token.Pos // position of "[" - Indices []ast.Expr // index expressions - Rbrack token.Pos // position of "]" -} - -// ForTypeSpec returns an empty field list, as type parameters on not supported -// at this Go version. -func ForTypeSpec(*ast.TypeSpec) *ast.FieldList { - return nil -} - -// ForFuncType returns an empty field list, as type parameters are not -// supported at this Go version. -func ForFuncType(*ast.FuncType) *ast.FieldList { - return nil -} - -// TypeParam is a placeholder type, as type parameters are not supported at -// this Go version. Its methods panic on use. -type TypeParam struct{ types.Type } - -func (*TypeParam) Index() int { unsupported(); return 0 } -func (*TypeParam) Constraint() types.Type { unsupported(); return nil } -func (*TypeParam) Obj() *types.TypeName { unsupported(); return nil } - -// TypeParamList is a placeholder for an empty type parameter list. -type TypeParamList struct{} - -func (*TypeParamList) Len() int { return 0 } -func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil } - -// TypeList is a placeholder for an empty type list. -type TypeList struct{} - -func (*TypeList) Len() int { return 0 } -func (*TypeList) At(int) types.Type { unsupported(); return nil } - -// NewTypeParam is unsupported at this Go version, and panics. -func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam { - unsupported() - return nil -} - -// SetTypeParamConstraint is unsupported at this Go version, and panics. -func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) { - unsupported() -} - -// NewSignatureType calls types.NewSignature, panicking if recvTypeParams or -// typeParams is non-empty. -func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature { - if len(recvTypeParams) != 0 || len(typeParams) != 0 { - panic("signatures cannot have type parameters at this Go version") - } - return types.NewSignature(recv, params, results, variadic) -} - -// ForSignature returns an empty slice. -func ForSignature(*types.Signature) *TypeParamList { - return nil -} - -// RecvTypeParams returns a nil slice. -func RecvTypeParams(sig *types.Signature) *TypeParamList { - return nil -} - -// IsComparable returns false, as no interfaces are type-restricted at this Go -// version. -func IsComparable(*types.Interface) bool { - return false -} - -// IsMethodSet returns true, as no interfaces are type-restricted at this Go -// version. -func IsMethodSet(*types.Interface) bool { - return true -} - -// IsImplicit returns false, as no interfaces are implicit at this Go version. -func IsImplicit(*types.Interface) bool { - return false -} - -// MarkImplicit does nothing, because this Go version does not have implicit -// interfaces. -func MarkImplicit(*types.Interface) {} - -// ForNamed returns an empty type parameter list, as type parameters are not -// supported at this Go version. -func ForNamed(*types.Named) *TypeParamList { - return nil -} - -// SetForNamed panics if tparams is non-empty. -func SetForNamed(_ *types.Named, tparams []*TypeParam) { - if len(tparams) > 0 { - unsupported() - } -} - -// NamedTypeArgs returns nil. -func NamedTypeArgs(*types.Named) *TypeList { - return nil -} - -// NamedTypeOrigin is the identity method at this Go version. -func NamedTypeOrigin(named *types.Named) *types.Named { - return named -} - -// Term holds information about a structural type restriction. -type Term struct { - tilde bool - typ types.Type -} - -func (m *Term) Tilde() bool { return m.tilde } -func (m *Term) Type() types.Type { return m.typ } -func (m *Term) String() string { - pre := "" - if m.tilde { - pre = "~" - } - return pre + m.typ.String() -} - -// NewTerm is unsupported at this Go version, and panics. -func NewTerm(tilde bool, typ types.Type) *Term { - return &Term{tilde, typ} -} - -// Union is a placeholder type, as type parameters are not supported at this Go -// version. Its methods panic on use. -type Union struct{ types.Type } - -func (*Union) Len() int { return 0 } -func (*Union) Term(i int) *Term { unsupported(); return nil } - -// NewUnion is unsupported at this Go version, and panics. -func NewUnion(terms []*Term) *Union { - unsupported() - return nil -} - -// InitInstanceInfo is a noop at this Go version. -func InitInstanceInfo(*types.Info) {} - -// Instance is a placeholder type, as type parameters are not supported at this -// Go version. -type Instance struct { - TypeArgs *TypeList - Type types.Type -} - -// GetInstances returns a nil map, as type parameters are not supported at this -// Go version. -func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil } - -// Context is a placeholder type, as type parameters are not supported at -// this Go version. -type Context struct{} - -// NewContext returns a placeholder Context instance. -func NewContext() *Context { - return &Context{} -} - -// Instantiate is unsupported on this Go version, and panics. -func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) { - unsupported() - return nil, nil -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go deleted file mode 100644 index cf301af1db..0000000000 --- a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.18 -// +build go1.18 - -package typeparams - -import ( - "go/ast" - "go/types" -) - -// IndexListExpr is an alias for ast.IndexListExpr. -type IndexListExpr = ast.IndexListExpr - -// ForTypeSpec returns n.TypeParams. -func ForTypeSpec(n *ast.TypeSpec) *ast.FieldList { - if n == nil { - return nil - } - return n.TypeParams -} - -// ForFuncType returns n.TypeParams. -func ForFuncType(n *ast.FuncType) *ast.FieldList { - if n == nil { - return nil - } - return n.TypeParams -} - -// TypeParam is an alias for types.TypeParam -type TypeParam = types.TypeParam - -// TypeParamList is an alias for types.TypeParamList -type TypeParamList = types.TypeParamList - -// TypeList is an alias for types.TypeList -type TypeList = types.TypeList - -// NewTypeParam calls types.NewTypeParam. -func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam { - return types.NewTypeParam(name, constraint) -} - -// SetTypeParamConstraint calls tparam.SetConstraint(constraint). -func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) { - tparam.SetConstraint(constraint) -} - -// NewSignatureType calls types.NewSignatureType. -func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature { - return types.NewSignatureType(recv, recvTypeParams, typeParams, params, results, variadic) -} - -// ForSignature returns sig.TypeParams() -func ForSignature(sig *types.Signature) *TypeParamList { - return sig.TypeParams() -} - -// RecvTypeParams returns sig.RecvTypeParams(). -func RecvTypeParams(sig *types.Signature) *TypeParamList { - return sig.RecvTypeParams() -} - -// IsComparable calls iface.IsComparable(). -func IsComparable(iface *types.Interface) bool { - return iface.IsComparable() -} - -// IsMethodSet calls iface.IsMethodSet(). -func IsMethodSet(iface *types.Interface) bool { - return iface.IsMethodSet() -} - -// IsImplicit calls iface.IsImplicit(). -func IsImplicit(iface *types.Interface) bool { - return iface.IsImplicit() -} - -// MarkImplicit calls iface.MarkImplicit(). -func MarkImplicit(iface *types.Interface) { - iface.MarkImplicit() -} - -// ForNamed extracts the (possibly empty) type parameter object list from -// named. -func ForNamed(named *types.Named) *TypeParamList { - return named.TypeParams() -} - -// SetForNamed sets the type params tparams on n. Each tparam must be of -// dynamic type *types.TypeParam. -func SetForNamed(n *types.Named, tparams []*TypeParam) { - n.SetTypeParams(tparams) -} - -// NamedTypeArgs returns named.TypeArgs(). -func NamedTypeArgs(named *types.Named) *TypeList { - return named.TypeArgs() -} - -// NamedTypeOrigin returns named.Orig(). -func NamedTypeOrigin(named *types.Named) *types.Named { - return named.Origin() -} - -// Term is an alias for types.Term. -type Term = types.Term - -// NewTerm calls types.NewTerm. -func NewTerm(tilde bool, typ types.Type) *Term { - return types.NewTerm(tilde, typ) -} - -// Union is an alias for types.Union -type Union = types.Union - -// NewUnion calls types.NewUnion. -func NewUnion(terms []*Term) *Union { - return types.NewUnion(terms) -} - -// InitInstanceInfo initializes info to record information about type and -// function instances. -func InitInstanceInfo(info *types.Info) { - info.Instances = make(map[*ast.Ident]types.Instance) -} - -// Instance is an alias for types.Instance. -type Instance = types.Instance - -// GetInstances returns info.Instances. -func GetInstances(info *types.Info) map[*ast.Ident]Instance { - return info.Instances -} - -// Context is an alias for types.Context. -type Context = types.Context - -// NewContext calls types.NewContext. -func NewContext() *Context { - return types.NewContext() -} - -// Instantiate calls types.Instantiate. -func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) { - return types.Instantiate(ctxt, typ, targs, validate) -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go b/vendor/golang.org/x/tools/internal/typeparams/typeterm.go deleted file mode 100644 index 7350bb702a..0000000000 --- a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import "go/types" - -// A term describes elementary type sets: -// -// ∅: (*term)(nil) == ∅ // set of no types (empty set) -// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse) -// T: &term{false, T} == {T} // set of type T -// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t -type term struct { - tilde bool // valid if typ != nil - typ types.Type -} - -func (x *term) String() string { - switch { - case x == nil: - return "∅" - case x.typ == nil: - return "𝓤" - case x.tilde: - return "~" + x.typ.String() - default: - return x.typ.String() - } -} - -// equal reports whether x and y represent the same type set. -func (x *term) equal(y *term) bool { - // easy cases - switch { - case x == nil || y == nil: - return x == y - case x.typ == nil || y.typ == nil: - return x.typ == y.typ - } - // ∅ ⊂ x, y ⊂ 𝓤 - - return x.tilde == y.tilde && types.Identical(x.typ, y.typ) -} - -// union returns the union x ∪ y: zero, one, or two non-nil terms. -func (x *term) union(y *term) (_, _ *term) { - // easy cases - switch { - case x == nil && y == nil: - return nil, nil // ∅ ∪ ∅ == ∅ - case x == nil: - return y, nil // ∅ ∪ y == y - case y == nil: - return x, nil // x ∪ ∅ == x - case x.typ == nil: - return x, nil // 𝓤 ∪ y == 𝓤 - case y.typ == nil: - return y, nil // x ∪ 𝓤 == 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return x, y // x ∪ y == (x, y) if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∪ ~t == ~t - // ~t ∪ T == ~t - // T ∪ ~t == ~t - // T ∪ T == T - if x.tilde || !y.tilde { - return x, nil - } - return y, nil -} - -// intersect returns the intersection x ∩ y. -func (x *term) intersect(y *term) *term { - // easy cases - switch { - case x == nil || y == nil: - return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ - case x.typ == nil: - return y // 𝓤 ∩ y == y - case y.typ == nil: - return x // x ∩ 𝓤 == x - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return nil // x ∩ y == ∅ if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∩ ~t == ~t - // ~t ∩ T == T - // T ∩ ~t == T - // T ∩ T == T - if !x.tilde || y.tilde { - return x - } - return y -} - -// includes reports whether t ∈ x. -func (x *term) includes(t types.Type) bool { - // easy cases - switch { - case x == nil: - return false // t ∈ ∅ == false - case x.typ == nil: - return true // t ∈ 𝓤 == true - } - // ∅ ⊂ x ⊂ 𝓤 - - u := t - if x.tilde { - u = under(u) - } - return types.Identical(x.typ, u) -} - -// subsetOf reports whether x ⊆ y. -func (x *term) subsetOf(y *term) bool { - // easy cases - switch { - case x == nil: - return true // ∅ ⊆ y == true - case y == nil: - return false // x ⊆ ∅ == false since x != ∅ - case y.typ == nil: - return true // x ⊆ 𝓤 == true - case x.typ == nil: - return false // 𝓤 ⊆ y == false since y != 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return false // x ⊆ y == false if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ⊆ ~t == true - // ~t ⊆ T == false - // T ⊆ ~t == true - // T ⊆ T == true - return !x.tilde || y.tilde -} - -// disjoint reports whether x ∩ y == ∅. -// x.typ and y.typ must not be nil. -func (x *term) disjoint(y *term) bool { - if debug && (x.typ == nil || y.typ == nil) { - panic("invalid argument(s)") - } - ux := x.typ - if y.tilde { - ux = under(ux) - } - uy := y.typ - if x.tilde { - uy = under(uy) - } - return !types.Identical(ux, uy) -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go index 07484073a5..131caab284 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go @@ -167,7 +167,7 @@ const ( UntypedNilUse // WrongAssignCount occurs when the number of values on the right-hand side - // of an assignment or or initialization expression does not match the number + // of an assignment or initialization expression does not match the number // of variables on the left-hand side. // // Example: @@ -838,7 +838,7 @@ const ( // InvalidCap occurs when an argument to the cap built-in function is not of // supported type. // - // See https://golang.org/ref/spec#Lengthand_capacity for information on + // See https://golang.org/ref/spec#Length_and_capacity for information on // which underlying types are supported as arguments to cap and len. // // Example: @@ -859,7 +859,7 @@ const ( // InvalidCopy occurs when the arguments are not of slice type or do not // have compatible type. // - // See https://golang.org/ref/spec#Appendingand_copying_slices for more + // See https://golang.org/ref/spec#Appending_and_copying_slices for more // information on the type requirements for the copy built-in. // // Example: @@ -897,7 +897,7 @@ const ( // InvalidLen occurs when an argument to the len built-in function is not of // supported type. // - // See https://golang.org/ref/spec#Lengthand_capacity for information on + // See https://golang.org/ref/spec#Length_and_capacity for information on // which underlying types are supported as arguments to cap and len. // // Example: @@ -914,7 +914,7 @@ const ( // InvalidMake occurs when make is called with an unsupported type argument. // - // See https://golang.org/ref/spec#Makingslices_maps_and_channels for + // See https://golang.org/ref/spec#Making_slices_maps_and_channels for // information on the types that may be created using make. // // Example: @@ -1449,10 +1449,10 @@ const ( NotAGenericType // WrongTypeArgCount occurs when a type or function is instantiated with an - // incorrent number of type arguments, including when a generic type or + // incorrect number of type arguments, including when a generic type or // function is used without instantiation. // - // Errors inolving failed type inference are assigned other error codes. + // Errors involving failed type inference are assigned other error codes. // // Example: // type T[p any] int diff --git a/vendor/golang.org/x/tools/internal/typesinternal/objectpath.go b/vendor/golang.org/x/tools/internal/typesinternal/objectpath.go deleted file mode 100644 index 5e96e89557..0000000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/objectpath.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import "go/types" - -// This file contains back doors that allow gopls to avoid method sorting when -// using the objectpath package. -// -// This is performance-critical in certain repositories, but changing the -// behavior of the objectpath package is still being discussed in -// golang/go#61443. If we decide to remove the sorting in objectpath we can -// simply delete these back doors. Otherwise, we should add a new API to -// objectpath that allows controlling the sorting. - -// SkipEncoderMethodSorting marks enc (which must be an *objectpath.Encoder) as -// not requiring sorted methods. -var SkipEncoderMethodSorting func(enc interface{}) - -// ObjectpathObject is like objectpath.Object, but allows suppressing method -// sorting. -var ObjectpathObject func(pkg *types.Package, p string, skipMethodSorting bool) (types.Object, error) diff --git a/vendor/golang.org/x/tools/internal/typesinternal/recv.go b/vendor/golang.org/x/tools/internal/typesinternal/recv.go new file mode 100644 index 0000000000..fea7c8b75e --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/recv.go @@ -0,0 +1,43 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typesinternal + +import ( + "go/types" + + "golang.org/x/tools/internal/aliases" +) + +// ReceiverNamed returns the named type (if any) associated with the +// type of recv, which may be of the form N or *N, or aliases thereof. +// It also reports whether a Pointer was present. +func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) { + t := recv.Type() + if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok { + isPtr = true + t = ptr.Elem() + } + named, _ = aliases.Unalias(t).(*types.Named) + return +} + +// Unpointer returns T given *T or an alias thereof. +// For all other types it is the identity function. +// It does not look at underlying types. +// The result may be an alias. +// +// Use this function to strip off the optional pointer on a receiver +// in a field or method selection, without losing the named type +// (which is needed to compute the method set). +// +// See also [typeparams.MustDeref], which removes one level of +// indirection from the type, regardless of named types (analogous to +// a LOAD instruction). +func Unpointer(t types.Type) types.Type { + if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok { + return ptr.Elem() + } + return t +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go new file mode 100644 index 0000000000..cc86487eaa --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go @@ -0,0 +1,89 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typesinternal + +import ( + "go/types" + + "golang.org/x/tools/internal/stdlib" + "golang.org/x/tools/internal/versions" +) + +// TooNewStdSymbols computes the set of package-level symbols +// exported by pkg that are not available at the specified version. +// The result maps each symbol to its minimum version. +// +// The pkg is allowed to contain type errors. +func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]string { + disallowed := make(map[types.Object]string) + + // Pass 1: package-level symbols. + symbols := stdlib.PackageSymbols[pkg.Path()] + for _, sym := range symbols { + symver := sym.Version.String() + if versions.Before(version, symver) { + switch sym.Kind { + case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type: + disallowed[pkg.Scope().Lookup(sym.Name)] = symver + } + } + } + + // Pass 2: fields and methods. + // + // We allow fields and methods if their associated type is + // disallowed, as otherwise we would report false positives + // for compatibility shims. Consider: + // + // //go:build go1.22 + // type T struct { F std.Real } // correct new API + // + // //go:build !go1.22 + // type T struct { F fake } // shim + // type fake struct { ... } + // func (fake) M () {} + // + // These alternative declarations of T use either the std.Real + // type, introduced in go1.22, or a fake type, for the field + // F. (The fakery could be arbitrarily deep, involving more + // nested fields and methods than are shown here.) Clients + // that use the compatibility shim T will compile with any + // version of go, whether older or newer than go1.22, but only + // the newer version will use the std.Real implementation. + // + // Now consider a reference to method M in new(T).F.M() in a + // module that requires a minimum of go1.21. The analysis may + // occur using a version of Go higher than 1.21, selecting the + // first version of T, so the method M is Real.M. This would + // spuriously cause the analyzer to report a reference to a + // too-new symbol even though this expression compiles just + // fine (with the fake implementation) using go1.21. + for _, sym := range symbols { + symVersion := sym.Version.String() + if !versions.Before(version, symVersion) { + continue // allowed + } + + var obj types.Object + switch sym.Kind { + case stdlib.Field: + typename, name := sym.SplitField() + if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == "" { + obj, _, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name) + } + + case stdlib.Method: + ptr, recvname, name := sym.SplitMethod() + if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == "" { + obj, _, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name) + } + } + if obj != nil { + disallowed[obj] = symVersion + } + } + + return disallowed +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go index ce7d4351b2..8392328612 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -49,4 +49,17 @@ func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true } -var SetGoVersion = func(conf *types.Config, version string) bool { return false } +// NameRelativeTo returns a types.Qualifier that qualifies members of +// all packages other than pkg, using only the package name. +// (By contrast, [types.RelativeTo] uses the complete package path, +// which is often excessive.) +// +// If pkg is nil, it is equivalent to [*types.Package.Name]. +func NameRelativeTo(pkg *types.Package) types.Qualifier { + return func(other *types.Package) string { + if pkg != nil && pkg == other { + return "" // same package; unqualified + } + return other.Name() + } +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types_118.go b/vendor/golang.org/x/tools/internal/typesinternal/types_118.go deleted file mode 100644 index a42b072a67..0000000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/types_118.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.18 -// +build go1.18 - -package typesinternal - -import ( - "go/types" -) - -func init() { - SetGoVersion = func(conf *types.Config, version string) bool { - conf.GoVersion = version - return true - } -} diff --git a/vendor/golang.org/x/tools/internal/versions/constraint.go b/vendor/golang.org/x/tools/internal/versions/constraint.go new file mode 100644 index 0000000000..179063d484 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/constraint.go @@ -0,0 +1,13 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package versions + +import "go/build/constraint" + +// ConstraintGoVersion is constraint.GoVersion (if built with go1.21+). +// Otherwise nil. +// +// Deprecate once x/tools is after go1.21. +var ConstraintGoVersion func(x constraint.Expr) string diff --git a/vendor/golang.org/x/tools/internal/versions/constraint_go121.go b/vendor/golang.org/x/tools/internal/versions/constraint_go121.go new file mode 100644 index 0000000000..38011407d5 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/constraint_go121.go @@ -0,0 +1,14 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.21 +// +build go1.21 + +package versions + +import "go/build/constraint" + +func init() { + ConstraintGoVersion = constraint.GoVersion +} diff --git a/vendor/golang.org/x/tools/internal/versions/features.go b/vendor/golang.org/x/tools/internal/versions/features.go new file mode 100644 index 0000000000..b53f178616 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/features.go @@ -0,0 +1,43 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package versions + +// This file contains predicates for working with file versions to +// decide when a tool should consider a language feature enabled. + +// GoVersions that features in x/tools can be gated to. +const ( + Go1_18 = "go1.18" + Go1_19 = "go1.19" + Go1_20 = "go1.20" + Go1_21 = "go1.21" + Go1_22 = "go1.22" +) + +// Future is an invalid unknown Go version sometime in the future. +// Do not use directly with Compare. +const Future = "" + +// AtLeast reports whether the file version v comes after a Go release. +// +// Use this predicate to enable a behavior once a certain Go release +// has happened (and stays enabled in the future). +func AtLeast(v, release string) bool { + if v == Future { + return true // an unknown future version is always after y. + } + return Compare(Lang(v), Lang(release)) >= 0 +} + +// Before reports whether the file version v is strictly before a Go release. +// +// Use this predicate to disable a behavior once a certain Go release +// has happened (and stays enabled in the future). +func Before(v, release string) bool { + if v == Future { + return false // an unknown future version happens after y. + } + return Compare(Lang(v), Lang(release)) < 0 +} diff --git a/vendor/golang.org/x/tools/internal/versions/gover.go b/vendor/golang.org/x/tools/internal/versions/gover.go new file mode 100644 index 0000000000..bbabcd22e9 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/gover.go @@ -0,0 +1,172 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This is a fork of internal/gover for use by x/tools until +// go1.21 and earlier are no longer supported by x/tools. + +package versions + +import "strings" + +// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]] +// The numbers are the original decimal strings to avoid integer overflows +// and since there is very little actual math. (Probably overflow doesn't matter in practice, +// but at the time this code was written, there was an existing test that used +// go1.99999999999, which does not fit in an int on 32-bit platforms. +// The "big decimal" representation avoids the problem entirely.) +type gover struct { + major string // decimal + minor string // decimal or "" + patch string // decimal or "" + kind string // "", "alpha", "beta", "rc" + pre string // decimal or "" +} + +// compare returns -1, 0, or +1 depending on whether +// x < y, x == y, or x > y, interpreted as toolchain versions. +// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21". +// Malformed versions compare less than well-formed versions and equal to each other. +// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0". +func compare(x, y string) int { + vx := parse(x) + vy := parse(y) + + if c := cmpInt(vx.major, vy.major); c != 0 { + return c + } + if c := cmpInt(vx.minor, vy.minor); c != 0 { + return c + } + if c := cmpInt(vx.patch, vy.patch); c != 0 { + return c + } + if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc + return c + } + if c := cmpInt(vx.pre, vy.pre); c != 0 { + return c + } + return 0 +} + +// lang returns the Go language version. For example, lang("1.2.3") == "1.2". +func lang(x string) string { + v := parse(x) + if v.minor == "" || v.major == "1" && v.minor == "0" { + return v.major + } + return v.major + "." + v.minor +} + +// isValid reports whether the version x is valid. +func isValid(x string) bool { + return parse(x) != gover{} +} + +// parse parses the Go version string x into a version. +// It returns the zero version if x is malformed. +func parse(x string) gover { + var v gover + + // Parse major version. + var ok bool + v.major, x, ok = cutInt(x) + if !ok { + return gover{} + } + if x == "" { + // Interpret "1" as "1.0.0". + v.minor = "0" + v.patch = "0" + return v + } + + // Parse . before minor version. + if x[0] != '.' { + return gover{} + } + + // Parse minor version. + v.minor, x, ok = cutInt(x[1:]) + if !ok { + return gover{} + } + if x == "" { + // Patch missing is same as "0" for older versions. + // Starting in Go 1.21, patch missing is different from explicit .0. + if cmpInt(v.minor, "21") < 0 { + v.patch = "0" + } + return v + } + + // Parse patch if present. + if x[0] == '.' { + v.patch, x, ok = cutInt(x[1:]) + if !ok || x != "" { + // Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != ""). + // Allowing them would be a bit confusing because we already have: + // 1.21 < 1.21rc1 + // But a prerelease of a patch would have the opposite effect: + // 1.21.3rc1 < 1.21.3 + // We've never needed them before, so let's not start now. + return gover{} + } + return v + } + + // Parse prerelease. + i := 0 + for i < len(x) && (x[i] < '0' || '9' < x[i]) { + if x[i] < 'a' || 'z' < x[i] { + return gover{} + } + i++ + } + if i == 0 { + return gover{} + } + v.kind, x = x[:i], x[i:] + if x == "" { + return v + } + v.pre, x, ok = cutInt(x) + if !ok || x != "" { + return gover{} + } + + return v +} + +// cutInt scans the leading decimal number at the start of x to an integer +// and returns that value and the rest of the string. +func cutInt(x string) (n, rest string, ok bool) { + i := 0 + for i < len(x) && '0' <= x[i] && x[i] <= '9' { + i++ + } + if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero + return "", "", false + } + return x[:i], x[i:], true +} + +// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers. +// (Copied from golang.org/x/mod/semver's compareInt.) +func cmpInt(x, y string) int { + if x == y { + return 0 + } + if len(x) < len(y) { + return -1 + } + if len(x) > len(y) { + return +1 + } + if x < y { + return -1 + } else { + return +1 + } +} diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain.go b/vendor/golang.org/x/tools/internal/versions/toolchain.go new file mode 100644 index 0000000000..377bf7a53b --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/toolchain.go @@ -0,0 +1,14 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package versions + +// toolchain is maximum version (<1.22) that the go toolchain used +// to build the current tool is known to support. +// +// When a tool is built with >=1.22, the value of toolchain is unused. +// +// x/tools does not support building with go <1.18. So we take this +// as the minimum possible maximum. +var toolchain string = Go1_18 diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go b/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go new file mode 100644 index 0000000000..f65beed9d8 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go @@ -0,0 +1,14 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.19 +// +build go1.19 + +package versions + +func init() { + if Compare(toolchain, Go1_19) < 0 { + toolchain = Go1_19 + } +} diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go b/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go new file mode 100644 index 0000000000..1a9efa126c --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go @@ -0,0 +1,14 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.20 +// +build go1.20 + +package versions + +func init() { + if Compare(toolchain, Go1_20) < 0 { + toolchain = Go1_20 + } +} diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go b/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go new file mode 100644 index 0000000000..b7ef216dfe --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go @@ -0,0 +1,14 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.21 +// +build go1.21 + +package versions + +func init() { + if Compare(toolchain, Go1_21) < 0 { + toolchain = Go1_21 + } +} diff --git a/vendor/golang.org/x/tools/internal/versions/types.go b/vendor/golang.org/x/tools/internal/versions/types.go new file mode 100644 index 0000000000..562eef21fa --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/types.go @@ -0,0 +1,19 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package versions + +import ( + "go/types" +) + +// GoVersion returns the Go version of the type package. +// It returns zero if no version can be determined. +func GoVersion(pkg *types.Package) string { + // TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25. + if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok { + return pkg.GoVersion() + } + return "" +} diff --git a/vendor/golang.org/x/tools/internal/versions/types_go121.go b/vendor/golang.org/x/tools/internal/versions/types_go121.go new file mode 100644 index 0000000000..b4345d3349 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/types_go121.go @@ -0,0 +1,30 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.22 +// +build !go1.22 + +package versions + +import ( + "go/ast" + "go/types" +) + +// FileVersion returns a language version (<=1.21) derived from runtime.Version() +// or an unknown future version. +func FileVersion(info *types.Info, file *ast.File) string { + // In x/tools built with Go <= 1.21, we do not have Info.FileVersions + // available. We use a go version derived from the toolchain used to + // compile the tool by default. + // This will be <= go1.21. We take this as the maximum version that + // this tool can support. + // + // There are no features currently in x/tools that need to tell fine grained + // differences for versions <1.22. + return toolchain +} + +// InitFileVersions is a noop when compiled with this Go version. +func InitFileVersions(*types.Info) {} diff --git a/vendor/golang.org/x/tools/internal/versions/types_go122.go b/vendor/golang.org/x/tools/internal/versions/types_go122.go new file mode 100644 index 0000000000..aac5db62c9 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/types_go122.go @@ -0,0 +1,41 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.22 +// +build go1.22 + +package versions + +import ( + "go/ast" + "go/types" +) + +// FileVersion returns a file's Go version. +// The reported version is an unknown Future version if a +// version cannot be determined. +func FileVersion(info *types.Info, file *ast.File) string { + // In tools built with Go >= 1.22, the Go version of a file + // follow a cascades of sources: + // 1) types.Info.FileVersion, which follows the cascade: + // 1.a) file version (ast.File.GoVersion), + // 1.b) the package version (types.Config.GoVersion), or + // 2) is some unknown Future version. + // + // File versions require a valid package version to be provided to types + // in Config.GoVersion. Config.GoVersion is either from the package's module + // or the toolchain (go run). This value should be provided by go/packages + // or unitchecker.Config.GoVersion. + if v := info.FileVersions[file]; IsValid(v) { + return v + } + // Note: we could instead return runtime.Version() [if valid]. + // This would act as a max version on what a tool can support. + return Future +} + +// InitFileVersions initializes info to record Go versions for Go files. +func InitFileVersions(info *types.Info) { + info.FileVersions = make(map[*ast.File]string) +} diff --git a/vendor/golang.org/x/tools/internal/versions/versions.go b/vendor/golang.org/x/tools/internal/versions/versions.go new file mode 100644 index 0000000000..8d1f7453db --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/versions.go @@ -0,0 +1,57 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package versions + +import ( + "strings" +) + +// Note: If we use build tags to use go/versions when go >=1.22, +// we run into go.dev/issue/53737. Under some operations users would see an +// import of "go/versions" even if they would not compile the file. +// For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include +// For this reason, this library just a clone of go/versions for the moment. + +// Lang returns the Go language version for version x. +// If x is not a valid version, Lang returns the empty string. +// For example: +// +// Lang("go1.21rc2") = "go1.21" +// Lang("go1.21.2") = "go1.21" +// Lang("go1.21") = "go1.21" +// Lang("go1") = "go1" +// Lang("bad") = "" +// Lang("1.21") = "" +func Lang(x string) string { + v := lang(stripGo(x)) + if v == "" { + return "" + } + return x[:2+len(v)] // "go"+v without allocation +} + +// Compare returns -1, 0, or +1 depending on whether +// x < y, x == y, or x > y, interpreted as Go versions. +// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21". +// Invalid versions, including the empty string, compare less than +// valid versions and equal to each other. +// The language version "go1.21" compares less than the +// release candidate and eventual releases "go1.21rc1" and "go1.21.0". +// Custom toolchain suffixes are ignored during comparison: +// "go1.21.0" and "go1.21.0-bigcorp" are equal. +func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) } + +// IsValid reports whether the version x is valid. +func IsValid(x string) bool { return isValid(stripGo(x)) } + +// stripGo converts from a "go1.21" version to a "1.21" version. +// If v does not start with "go", stripGo returns the empty string (a known invalid version). +func stripGo(v string) string { + v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix. + if len(v) < 2 || v[:2] != "go" { + return "" + } + return v[2:] +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 8bed2ca0a8..f5aa52ed7c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,8 +1,8 @@ # dario.cat/mergo v1.0.0 ## explicit; go 1.13 dario.cat/mergo -# github.com/99designs/gqlgen v0.17.19 -## explicit; go 1.16 +# github.com/99designs/gqlgen v0.17.54 +## explicit; go 1.22.5 github.com/99designs/gqlgen/complexity github.com/99designs/gqlgen/graphql github.com/99designs/gqlgen/graphql/errcode @@ -22,14 +22,14 @@ github.com/ActiveState/graphql # github.com/ActiveState/pty v0.0.0-20230628221854-6fb90eb08a14 ## explicit; go 1.13 github.com/ActiveState/pty -# github.com/ActiveState/termtest v0.7.3-0.20240522153407-fcd066736664 +# github.com/ActiveState/termtest v0.7.3-0.20240703202616-34f7899287a4 ## explicit; go 1.18 github.com/ActiveState/termtest # github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 ## explicit github.com/Azure/go-ansiterm github.com/Azure/go-ansiterm/winterm -# github.com/BurntSushi/toml v1.2.1 +# github.com/BurntSushi/toml v1.3.2 ## explicit; go 1.16 # github.com/Microsoft/go-winio v0.6.1 ## explicit; go 1.17 @@ -151,6 +151,15 @@ github.com/aymanbagabas/go-osc52/v2 # github.com/blang/semver v3.5.1+incompatible ## explicit github.com/blang/semver +# github.com/bmatcuk/doublestar/v4 v4.7.1 +## explicit; go 1.16 +github.com/bmatcuk/doublestar/v4 +# github.com/brunoga/deep v1.2.4 +## explicit; go 1.20.0 +github.com/brunoga/deep +# github.com/cespare/xxhash v1.1.0 +## explicit +github.com/cespare/xxhash # github.com/charmbracelet/bubbles v0.18.0 ## explicit; go 1.18 github.com/charmbracelet/bubbles/key @@ -206,11 +215,8 @@ github.com/emirpasic/gods/lists/arraylist github.com/emirpasic/gods/trees github.com/emirpasic/gods/trees/binaryheap github.com/emirpasic/gods/utils -# github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 -## explicit -github.com/faiface/mainthread -# github.com/fatih/color v1.10.0 -## explicit; go 1.13 +# github.com/fatih/color v1.16.0 +## explicit; go 1.17 github.com/fatih/color # github.com/fatih/structs v1.1.0 ## explicit @@ -359,25 +365,29 @@ github.com/google/go-querystring/query # github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99 ## explicit; go 1.14 github.com/google/pprof/profile -# github.com/google/uuid v1.3.0 +# github.com/google/uuid v1.6.0 ## explicit github.com/google/uuid # github.com/gorilla/websocket v1.5.0 ## explicit; go 1.12 github.com/gorilla/websocket -# github.com/hashicorp/go-cleanhttp v0.5.1 -## explicit -github.com/hashicorp/go-cleanhttp -# github.com/hashicorp/go-retryablehttp v0.6.7 +# github.com/gowebpki/jcs v1.0.1 +## explicit; go 1.15 +github.com/gowebpki/jcs +# github.com/hashicorp/go-cleanhttp v0.5.2 ## explicit; go 1.13 +github.com/hashicorp/go-cleanhttp +# github.com/hashicorp/go-retryablehttp v0.7.7 +## explicit; go 1.19 github.com/hashicorp/go-retryablehttp # github.com/hashicorp/go-version v1.1.0 ## explicit github.com/hashicorp/go-version -# github.com/hashicorp/golang-lru v0.5.4 -## explicit; go 1.12 -github.com/hashicorp/golang-lru -github.com/hashicorp/golang-lru/simplelru +# github.com/hashicorp/golang-lru/v2 v2.0.7 +## explicit; go 1.18 +github.com/hashicorp/golang-lru/v2 +github.com/hashicorp/golang-lru/v2/internal +github.com/hashicorp/golang-lru/v2/simplelru # github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 ## explicit; go 1.14 github.com/hinshun/vt10x @@ -388,9 +398,6 @@ github.com/hpcloud/tail/ratelimiter github.com/hpcloud/tail/util github.com/hpcloud/tail/watch github.com/hpcloud/tail/winfile -# github.com/imacks/bitflags-go v1.0.0 -## explicit; go 1.18 -github.com/imacks/bitflags-go # github.com/imdario/mergo v0.3.11 ## explicit; go 1.13 github.com/imdario/mergo @@ -465,10 +472,10 @@ github.com/maruel/natural github.com/mash/go-tempfile-suffix # github.com/matryer/is v1.2.0 ## explicit -# github.com/mattn/go-colorable v0.1.12 -## explicit; go 1.13 +# github.com/mattn/go-colorable v0.1.13 +## explicit; go 1.15 github.com/mattn/go-colorable -# github.com/mattn/go-isatty v0.0.18 +# github.com/mattn/go-isatty v0.0.20 ## explicit; go 1.15 github.com/mattn/go-isatty # github.com/mattn/go-localereader v0.0.1 @@ -589,6 +596,9 @@ github.com/skeema/knownhosts # github.com/skratchdot/open-golang v0.0.0-20190104022628-a2dfa6d0dab6 ## explicit github.com/skratchdot/open-golang/open +# github.com/sosodev/duration v1.3.1 +## explicit; go 1.17 +github.com/sosodev/duration # github.com/spf13/cast v1.3.0 ## explicit github.com/spf13/cast @@ -638,8 +648,8 @@ github.com/vbauerster/mpb/v7 github.com/vbauerster/mpb/v7/cwriter github.com/vbauerster/mpb/v7/decor github.com/vbauerster/mpb/v7/internal -# github.com/vektah/gqlparser/v2 v2.5.1 -## explicit; go 1.16 +# github.com/vektah/gqlparser/v2 v2.5.16 +## explicit; go 1.19 github.com/vektah/gqlparser/v2 github.com/vektah/gqlparser/v2/ast github.com/vektah/gqlparser/v2/gqlerror @@ -668,11 +678,8 @@ go.mongodb.org/mongo-driver/bson/bsonrw go.mongodb.org/mongo-driver/bson/bsontype go.mongodb.org/mongo-driver/bson/primitive go.mongodb.org/mongo-driver/x/bsonx/bsoncore -# go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 -## explicit; go 1.11 -go.mozilla.org/pkcs7 -# golang.org/x/crypto v0.23.0 -## explicit; go 1.18 +# golang.org/x/crypto v0.27.0 +## explicit; go 1.20 golang.org/x/crypto/acme golang.org/x/crypto/acme/autocert golang.org/x/crypto/argon2 @@ -681,7 +688,6 @@ golang.org/x/crypto/blowfish golang.org/x/crypto/cast5 golang.org/x/crypto/chacha20 golang.org/x/crypto/curve25519 -golang.org/x/crypto/curve25519/internal/field golang.org/x/crypto/hkdf golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 @@ -696,10 +702,10 @@ golang.org/x/crypto/ssh golang.org/x/crypto/ssh/agent golang.org/x/crypto/ssh/internal/bcrypt_pbkdf golang.org/x/crypto/ssh/knownhosts -# golang.org/x/mod v0.12.0 -## explicit; go 1.17 +# golang.org/x/mod v0.21.0 +## explicit; go 1.22.0 golang.org/x/mod/semver -# golang.org/x/net v0.25.0 +# golang.org/x/net v0.29.0 ## explicit; go 1.18 golang.org/x/net/context golang.org/x/net/http/httpguts @@ -709,10 +715,10 @@ golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/internal/socks golang.org/x/net/proxy -# golang.org/x/sync v0.3.0 -## explicit; go 1.17 +# golang.org/x/sync v0.8.0 +## explicit; go 1.18 golang.org/x/sync/errgroup -# golang.org/x/sys v0.20.0 +# golang.org/x/sys v0.25.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/execabs @@ -720,10 +726,10 @@ golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/term v0.20.0 +# golang.org/x/term v0.24.0 ## explicit; go 1.18 golang.org/x/term -# golang.org/x/text v0.15.0 +# golang.org/x/text v0.18.0 ## explicit; go 1.18 golang.org/x/text/cases golang.org/x/text/internal @@ -739,25 +745,25 @@ golang.org/x/text/width # golang.org/x/time v0.1.0 ## explicit golang.org/x/time/rate -# golang.org/x/tools v0.13.0 -## explicit; go 1.18 +# golang.org/x/tools v0.25.0 +## explicit; go 1.22.0 golang.org/x/tools/cmd/stringer golang.org/x/tools/go/gcexportdata -golang.org/x/tools/go/internal/packagesdriver golang.org/x/tools/go/packages golang.org/x/tools/go/types/objectpath +golang.org/x/tools/internal/aliases golang.org/x/tools/internal/event golang.org/x/tools/internal/event/core golang.org/x/tools/internal/event/keys golang.org/x/tools/internal/event/label -golang.org/x/tools/internal/event/tag golang.org/x/tools/internal/gcimporter golang.org/x/tools/internal/gocommand golang.org/x/tools/internal/packagesinternal golang.org/x/tools/internal/pkgbits +golang.org/x/tools/internal/stdlib golang.org/x/tools/internal/tokeninternal -golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal +golang.org/x/tools/internal/versions # gopkg.in/AlecAivazis/survey.v1 v1.8.8 ## explicit; go 1.13 gopkg.in/AlecAivazis/survey.v1 @@ -837,4 +843,3 @@ modernc.org/strutil # modernc.org/token v1.0.0 ## explicit modernc.org/token -# cloud.google.com/go => cloud.google.com/go v0.110.0 diff --git a/version.txt b/version.txt index d13267b825..f7ccf07ba8 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.45.1-RC1 \ No newline at end of file +0.47.0-RC1