├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── feature_request.md │ └── question.md ├── PULL_REQUEST_TEMPLATE.md ├── release.yml └── workflows │ ├── analysis.yml │ ├── cla.yml │ ├── frogbot-scan-and-fix.yml │ ├── frogbot-scan-pr.yml │ ├── monitorIssues.yml │ └── test.yml ├── .gitignore ├── .jfrog └── jfrog-apps-config.yml ├── LICENSE ├── README.md ├── RELEASE.md ├── build-info.json ├── build ├── build.go ├── build_test.go ├── dotnet.go ├── dotnet_test.go ├── golang.go ├── golang_test.go ├── gradle.go ├── gradle_test.go ├── init-gradle-extractor-4.gradle ├── init-gradle-extractor-5.gradle ├── maven.go ├── maven_test.go ├── npm.go ├── npm_test.go ├── python.go ├── python_test.go ├── service.go ├── testdata │ ├── dotnet │ │ └── slnDir │ │ │ ├── packages.config │ │ │ ├── proj.csproj │ │ │ ├── projTwo.vbproj │ │ │ └── sol.sln │ ├── golang │ │ └── project │ │ │ ├── dependency.go │ │ │ ├── go.mod │ │ │ └── go.sum │ ├── gradle │ │ ├── gradle-6.8.1 │ │ │ ├── .gitattributes │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── gradle │ │ │ │ └── wrapper │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── gradle-6.8 │ │ │ ├── .gitattributes │ │ │ ├── .gitignore │ │ │ ├── build.gradle.kts │ │ │ ├── gradle │ │ │ │ └── wrapper │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle.kts │ │ └── gradle-7.0 │ │ │ ├── .gitattributes │ │ │ ├── .gitignore │ │ │ ├── build.gradle.kts │ │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle.kts │ ├── maven │ │ ├── expected_maven_buildinfo.json │ │ └── project │ │ │ ├── multi1 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ └── java │ │ │ │ │ └── artifactory │ │ │ │ │ └── test │ │ │ │ │ └── Multi1.java │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── artifactory │ │ │ │ └── test │ │ │ │ └── AppTest.java │ │ │ ├── multi2 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ └── java │ │ │ │ │ └── artifactory │ │ │ │ │ └── test │ │ │ │ │ └── App.java │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── artifactory │ │ │ │ └── test │ │ │ │ └── AppTest.java │ │ │ ├── multi3 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── artifactory │ │ │ │ │ │ └── test │ │ │ │ │ │ └── Multi3.java │ │ │ │ └── webapp │ │ │ │ │ └── WEB-INF │ │ │ │ │ └── web.xml │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── artifactory │ │ │ │ └── test │ │ │ │ └── AppTest.java │ │ │ └── pom.xml │ ├── npm │ │ ├── _cacache │ │ │ ├── content-v2 │ │ │ │ ├── sha1 │ │ │ │ │ └── 67 │ │ │ │ │ │ └── 6f │ │ │ │ │ │ └── 6eb3c39997c2ee1ac3a924fd6124748f578d │ │ │ │ └── sha512 │ │ │ │ │ ├── 32 │ │ │ │ │ └── d8 │ │ │ │ │ │ └── be7fd96924d730178b5657cfcead34ed1758198be7fc16a97201da2eada95c156150585dbe3600874a18e409bf881412eaf5bb99c04d71724414e29792b9 │ │ │ │ │ └── 75 │ │ │ │ │ └── 67 │ │ │ │ │ └── b89d63bfaee10e63b1e4509e6016dd4308557dccf46826bf29574fc04907ab98e663b6af233233a9ac2d0a775d062cdfa5ef16943efc732455adc46bbc16 │ │ │ └── index-v5 │ │ │ │ └── 81 │ │ │ │ └── fd │ │ │ │ └── fae35857dd2515812284fc5c6ed232049d79503dc73bd919842c593dd6a2 │ │ ├── dependenciesList.json │ │ ├── noBuildProject │ │ │ └── package.json │ │ ├── project1 │ │ │ ├── npmv6 │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ ├── npmv7 │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ └── npmv8 │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ ├── project2 │ │ │ ├── npmv6 │ │ │ │ ├── linux │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ ├── macos │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ └── windows │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ ├── npmv7 │ │ │ │ ├── linux │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ ├── macos │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ └── windows │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ └── npmv8 │ │ │ │ ├── linux │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ │ ├── macos │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ │ └── windows │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ ├── project3 │ │ │ ├── npmv6 │ │ │ │ ├── expected_npm_buildinfo.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ ├── npmv7 │ │ │ │ ├── expected_npm_buildinfo.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ └── npmv8 │ │ │ │ ├── expected_npm_buildinfo.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ ├── project4 │ │ │ ├── npmv6 │ │ │ │ ├── linux │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ ├── macos │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ └── windows │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ ├── npmv7 │ │ │ │ ├── linux │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ ├── macos │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ └── windows │ │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ └── npmv8 │ │ │ │ ├── linux │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ │ ├── macos │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ │ └── windows │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ ├── project5 │ │ │ └── npmv6 │ │ │ │ ├── linux │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ │ ├── macos │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ │ │ └── windows │ │ │ │ ├── excpected_dependencies_list.json │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ └── project6 │ │ │ ├── node_modules │ │ │ └── dummy-file │ │ │ ├── package-lock_test.json │ │ │ └── package.json │ ├── python │ │ ├── pip │ │ │ ├── expected_pip_buildinfo_with_module_name.json │ │ │ ├── expected_pip_buildinfo_without_module_name.json │ │ │ └── setup.py │ │ └── pipenv │ │ │ ├── Pipfile │ │ │ ├── expected_pipenv_buildinfo_with_module_name.json │ │ │ └── expected_pipenv_buildinfo_without_module_name.json │ └── yarn │ │ ├── v1 │ │ └── project │ │ │ ├── package.json │ │ │ └── yarn.lock │ │ └── v2 │ │ └── project │ │ ├── .yarn │ │ └── releases │ │ │ └── yarn-3.1.1.cjs │ │ ├── .yarnrc.yml │ │ ├── package.json │ │ └── yarn.lock ├── utils │ ├── dotnet │ │ ├── configfiletemplate.go │ │ ├── dependencies │ │ │ ├── assetsjson.go │ │ │ ├── assetsjson_test.go │ │ │ ├── dependencies.go │ │ │ ├── packagesconfig.go │ │ │ ├── packagesconfig_test.go │ │ │ └── testdata │ │ │ │ ├── assetsproject │ │ │ │ ├── dep1.nupkg │ │ │ │ ├── dep2.nupkg │ │ │ │ └── obj │ │ │ │ │ └── project.assets.json │ │ │ │ └── packagesproject │ │ │ │ ├── localcache │ │ │ │ ├── id1 │ │ │ │ │ └── 1.0.0 │ │ │ │ │ │ ├── id1.1.0.0.nupkg │ │ │ │ │ │ └── id1.nuspec │ │ │ │ ├── id2 │ │ │ │ │ └── 2.0.0 │ │ │ │ │ │ ├── id2.2.0.0.nupkg │ │ │ │ │ │ └── id2.nuspec │ │ │ │ └── microsoft.web.infrastructure │ │ │ │ │ └── 1.0.0.0 │ │ │ │ │ ├── microsoft.web.infrastructure.1.0.0.0.nupkg │ │ │ │ │ └── microsoft.web.infrastructure.nuspec │ │ │ │ └── packages.config │ │ ├── dependenciestree │ │ │ └── dependencies.go │ │ ├── solution │ │ │ ├── project │ │ │ │ └── project.go │ │ │ ├── solution.go │ │ │ ├── solution_test.go │ │ │ └── testdata │ │ │ │ ├── multilinesproject.sln │ │ │ │ ├── multiprojects.sln │ │ │ │ ├── nugetproj │ │ │ │ ├── proj1 │ │ │ │ │ ├── packages.config │ │ │ │ │ ├── proj1.cs │ │ │ │ │ └── proj1.csproj │ │ │ │ ├── proj2 │ │ │ │ │ ├── proj2.cs │ │ │ │ │ └── proj2.csproj │ │ │ │ └── solutions │ │ │ │ │ ├── nugetproj.sln │ │ │ │ │ └── proj2 │ │ │ │ │ └── packages.config │ │ │ │ ├── oneproject.sln │ │ │ │ └── visualbasic.sln │ │ └── toolchaincmd.go │ ├── npm.go │ ├── npm_test.go │ ├── npmcacache.go │ ├── npmcacache_test.go │ ├── yarn.go │ └── yarn_test.go ├── utils_test.go ├── yarn.go └── yarn_test.go ├── buildinfo-schema.json ├── buildinfoschema_test.go ├── buildscripts ├── build.bat └── build.sh ├── cli ├── cli.go └── cli_test.go ├── docs └── CNAME ├── entities ├── buildinfo.go └── buildinfo_test.go ├── go.mod ├── go.sum ├── images ├── dark.gif ├── light.gif ├── linux.png ├── mac.png └── windows.png ├── main.go ├── release ├── build.sh ├── pipelines.yml └── specs │ └── bi-rbc-spec.json ├── tests └── test_helpers.go └── utils ├── buildutils.go ├── cliutils └── consts.go ├── compare_test.go ├── compareutils └── compare.go ├── dependenciesutils.go ├── error.go ├── fileutils.go ├── fileutils_test.go ├── goutils.go ├── goutils_test.go ├── ioutils.go ├── logger.go ├── masking.go ├── pythonutils ├── deptreescript.go ├── pipdeptree │ ├── pipdeptree.py │ └── scriptcreator.go ├── pipenvutils.go ├── piputils.go ├── piputils_test.go ├── poetryutils.go ├── poetryutils_test.go ├── pyprojectutils.go ├── pyprojectutils_test.go ├── twineutils.go ├── twineutils_test.go ├── utils.go └── utils_test.go ├── testdata ├── mods │ ├── testBadGoList │ │ ├── go.mod.txt │ │ ├── go.sum.txt │ │ └── test.go.txt │ └── testGoList │ │ ├── go.mod.txt │ │ ├── go.sum.txt │ │ └── test.go.txt ├── noproject │ └── f ├── oneline ├── pip │ ├── pyproject │ │ └── pyproject.toml │ ├── requirementsproject │ │ └── requirements.txt │ └── setuppyproject │ │ └── setup.py ├── poetry │ ├── nodevdeps │ │ ├── poetry.lock │ │ └── pyproject.toml │ └── project │ │ ├── poetry.lock │ │ └── pyproject.toml ├── project │ ├── dir │ │ └── f │ └── go.mod ├── threelines └── twolines └── utils.go /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "🐛 Bug Report" 3 | description: Create a report to help us improve 4 | labels: [bug] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Describe the bug 10 | description: What is the problem? A clear and concise description of the bug. 11 | validations: 12 | required: true 13 | 14 | - type: textarea 15 | id: current 16 | attributes: 17 | label: Current behavior 18 | description: | 19 | Please include full errors, uncaught exceptions, screenshots, and relevant logs. 20 | validations: 21 | required: true 22 | 23 | - type: textarea 24 | id: reproduction 25 | attributes: 26 | label: Reproduction steps 27 | description: | 28 | Provide steps to reproduce the behavior. 29 | validations: 30 | required: false 31 | 32 | - type: textarea 33 | id: expected 34 | attributes: 35 | label: Expected behavior 36 | description: | 37 | What did you expect to happen? 38 | validations: 39 | required: false 40 | 41 | - type: input 42 | id: os-version 43 | attributes: 44 | label: Operating system type and version 45 | validations: 46 | required: true 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ⭐️ Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: feature request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like to see** 14 | A clear and concise description of the new feature. 15 | 16 | **Describe alternatives you've considered** 17 | If applicable, a clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ❓ Question 3 | about: Ask a question 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | - [ ] All [tests](https://github.com/jfrog/build-info-go#tests) passed. If this feature is not already covered by the tests, I added new tests. 2 | - [ ] All [static analysis checks](https://github.com/jfrog/build-info-go/actions/workflows/analysis.yml) passed. 3 | - [ ] This pull request is on the dev branch. 4 | - [ ] I used gofmt for formatting the code before submitting the pull request. 5 | ----- 6 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - ignore for release 5 | categories: 6 | - title: Breaking Changes 🚨 7 | labels: 8 | - breaking change 9 | - title: Exciting New Features 🎉 10 | labels: 11 | - new feature 12 | - title: Improvements 🌱 13 | labels: 14 | - improvement 15 | - title: Bug Fixes 🛠 16 | labels: 17 | - bug 18 | - title: Other Changes 📚 19 | labels: 20 | - "*" 21 | -------------------------------------------------------------------------------- /.github/workflows/analysis.yml: -------------------------------------------------------------------------------- 1 | name: "Static Analysis" 2 | on: 3 | push: 4 | branches: 5 | - '**' 6 | tags-ignore: 7 | - '**' 8 | pull_request: 9 | jobs: 10 | Static-Check: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout Source 14 | uses: actions/checkout@v4 15 | 16 | - name: Setup Go with cache 17 | uses: jfrog/.github/actions/install-go-with-cache@main 18 | 19 | - name: Run Go-Sec scanner 20 | uses: jfrog/.github/actions/gosec-scanner@main 21 | 22 | Go-Sec: 23 | runs-on: ubuntu-latest 24 | steps: 25 | - name: Checkout Source 26 | uses: actions/checkout@v4 27 | 28 | - name: Setup Go with cache 29 | uses: jfrog/.github/actions/install-go-with-cache@main 30 | 31 | - name: Run golangci lint 32 | uses: jfrog/.github/actions/golangci-lint@main 33 | 34 | ShellCheck: 35 | runs-on: ubuntu-latest 36 | steps: 37 | - name: Checkout Source 38 | uses: actions/checkout@v4 39 | - name: Run ShellCheck 40 | uses: ludeeus/action-shellcheck@master 41 | with: 42 | ignore_paths: '*test*' -------------------------------------------------------------------------------- /.github/workflows/cla.yml: -------------------------------------------------------------------------------- 1 | name: "CLA Assistant" 2 | on: 3 | # issue_comment triggers this action on each comment on issues and pull requests 4 | issue_comment: 5 | types: [ created ] 6 | pull_request_target: 7 | types: [ opened,synchronize ] 8 | 9 | jobs: 10 | CLAssistant: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Run CLA Check 14 | uses: jfrog/.github/actions/cla@main 15 | with: 16 | event_comment_body: ${{ github.event.comment.body }} 17 | event_name: ${{ github.event_name }} 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | CLA_SIGN_TOKEN: ${{ secrets.CLA_SIGN_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/frogbot-scan-and-fix.yml: -------------------------------------------------------------------------------- 1 | name: "Frogbot Scan and Fix" 2 | on: 3 | schedule: 4 | # The repository will be scanned once a day at 00:00 GMT. 5 | - cron: "0 0 * * *" 6 | permissions: 7 | contents: write 8 | pull-requests: write 9 | security-events: write 10 | jobs: 11 | create-fix-pull-requests: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | # The repository scanning will be triggered periodically on the following branches. 16 | branch: [ "dev" ] 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | ref: ${{ matrix.branch }} 21 | 22 | - name: Setup Go with cache 23 | uses: jfrog/.github/actions/install-go-with-cache@main 24 | 25 | - uses: jfrog/frogbot@v2 26 | env: 27 | # [Mandatory] 28 | # JFrog platform URL 29 | JF_URL: ${{ secrets.FROGBOT_URL }} 30 | 31 | # [Mandatory if JF_USER and JF_PASSWORD are not provided] 32 | # JFrog access token with 'read' permissions on Xray service 33 | JF_ACCESS_TOKEN: ${{ secrets.FROGBOT_ACCESS_TOKEN }} 34 | 35 | # [Mandatory] 36 | # The GitHub token automatically generated for the job 37 | JF_GIT_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /.github/workflows/frogbot-scan-pr.yml: -------------------------------------------------------------------------------- 1 | name: "Frogbot Scan Pull Request" 2 | on: 3 | pull_request_target: 4 | types: [ opened, synchronize ] 5 | permissions: 6 | pull-requests: write 7 | contents: read 8 | jobs: 9 | scan-pull-request: 10 | runs-on: ubuntu-latest 11 | # A pull request needs to be approved, before Frogbot scans it. Any GitHub user who is associated with the 12 | # "frogbot" GitHub environment can approve the pull request to be scanned. 13 | environment: frogbot 14 | steps: 15 | - name: Setup Go with cache 16 | uses: jfrog/.github/actions/install-go-with-cache@main 17 | 18 | - uses: jfrog/frogbot@v2 19 | env: 20 | # [Mandatory] 21 | # JFrog platform URL (This functionality requires version 3.29.0 or above of Xray) 22 | JF_URL: ${{ secrets.FROGBOT_URL }} 23 | 24 | # [Mandatory if JF_USER and JF_PASSWORD are not provided] 25 | # JFrog access token with 'read' permissions on Xray service 26 | JF_ACCESS_TOKEN: ${{ secrets.FROGBOT_ACCESS_TOKEN }} 27 | 28 | # [Mandatory] 29 | # The GitHub token automatically generated for the job 30 | JF_GIT_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | -------------------------------------------------------------------------------- /.github/workflows/monitorIssues.yml: -------------------------------------------------------------------------------- 1 | name: Monitor Issues 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | operations-per-run: 6 | description: 'Number of operations per run' 7 | required: false 8 | default: '30' 9 | schedule: 10 | - cron: "0 0 * * *" # Runs once a day at midnight 11 | jobs: 12 | monitor-issues: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | issues: write 16 | steps: 17 | - uses: actions/stale@v9 18 | with: 19 | # Ignore issues with these labels 20 | exempt-issue-labels: 'feature request,question' 21 | # Days of inactivity before marking an issue as stale 22 | days-before-issue-stale: 180 23 | # Days of inactivity before closing an issue 24 | days-before-issue-close: 7 25 | # Name of the stale label 26 | stale-issue-label: "stale" 27 | stale-issue-message: "This issue has been marked as stale due to 6 months of inactivity. As part of our effort to address every issue properly, please feel free to remove the stale label or keep this issue active by leaving a comment. Otherwise, it will be closed in 7 days" 28 | close-issue-message: "This issue was closed due to 7 days of inactivity after being marked as stale. Feel free to reopen it if it remains relevant." 29 | # Ignore pull requests 30 | days-before-pr-close: false 31 | days-before-pr-stale: false 32 | ascending: true 33 | # Get from input or resolve to default 34 | operations-per-run: ${{ github.event.inputs.operations-per-run || '30' }} 35 | repo-token: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: 3 | push: 4 | branches: 5 | - '**' 6 | tags-ignore: 7 | - '**' 8 | pull_request: 9 | # Ensures that only the latest commit is running for each PR at a time. 10 | # Ignores this rule for push events. 11 | concurrency: 12 | group: ${{ github.event.pull_request.number || github.sha }} 13 | cancel-in-progress: true 14 | jobs: 15 | unit-test: 16 | name: ${{ matrix.os }}, node ${{ matrix.node }}, python ${{ matrix.python }} 17 | runs-on: ${{ matrix.os }} 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | # macos-latest = arm64, macos-14-large = amd64 22 | os: [ ubuntu-latest, windows-latest, macos-latest, macos-14-large ] 23 | node: [ 14, 16, 16.9 ] 24 | include: 25 | - node: "14" 26 | python: "3.8" 27 | - node: "16" 28 | python: "3.9" 29 | - node: "16.9" 30 | python: "3.x" 31 | exclude: 32 | # MacOS with ARM does not support node 14 33 | - os: macos-latest 34 | node: 14 35 | 36 | steps: 37 | - uses: actions/checkout@v4 38 | 39 | - name: Setup Python3 40 | uses: actions/setup-python@v5 41 | with: 42 | python-version: ${{ matrix.python }} 43 | 44 | - name: Setup Pipenv 45 | run: pip3 install pipenv 46 | 47 | - name: Setup Node.js 48 | uses: actions/setup-node@v4 49 | with: 50 | node-version: ${{ matrix.node }} 51 | check-latest: true 52 | 53 | - name: Setup Go with cache 54 | uses: jfrog/.github/actions/install-go-with-cache@main 55 | 56 | - name: Install NuGet 57 | uses: nuget/setup-nuget@v2 58 | with: 59 | nuget-version: 6.x 60 | 61 | - name: Install dotnet 62 | uses: actions/setup-dotnet@v4 63 | with: 64 | dotnet-version: '6.x' 65 | 66 | # Install Mono on Ubuntu to run nuget.exe (due to this issue on Ubuntu 24 that hasn't been fixed yet - https://github.com/NuGet/setup-nuget/issues/168) 67 | - name: Install Mono on Ubuntu 68 | if: matrix.os == 'ubuntu-latest' 69 | run: | 70 | sudo apt-get update 71 | sudo apt-get install -y apt-transport-https dirmngr gnupg ca-certificates 72 | sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF 73 | echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list 74 | sudo apt-get update 75 | sudo apt-get install -y mono-complete 76 | 77 | - name: Lint 78 | run: go vet ./... 79 | 80 | - name: Tests 81 | run: go test -v -race -timeout 0 -cover ./... 82 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDEs 2 | .idea 3 | .vscode 4 | *.iml 5 | 6 | # Test binary, built with `go test -c` 7 | *.test 8 | 9 | # Output of the go coverage tool, specifically when used with LiteIDE 10 | *.out 11 | 12 | # build-info-go executable 13 | build-info-go 14 | build-info-go.exe 15 | bi 16 | bi.exe 17 | 18 | # Gradle 19 | .gradle 20 | -------------------------------------------------------------------------------- /.jfrog/jfrog-apps-config.yml: -------------------------------------------------------------------------------- 1 | version: "1.0" 2 | modules: 3 | - exclude_patterns: 4 | - "**/.git/**" 5 | - "**/node_modules/**" 6 | 7 | # Included in .gitignore: 8 | - "**/.vscode/**" 9 | - "**/.idea/**" 10 | exclude_scanners: 11 | - "iac" 12 | - "sast" 13 | scanners: 14 | secrets: 15 | exclude_patterns: 16 | - "**/build/utils/dotnet/configfiletemplate.go**" 17 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | | Release notes moved to https://github.com/jfrog/build-info-go/releases | 4 | |----------------------------------------------------------------------------------------------------------------------------------------------------------| 5 | 6 | ## 1.6.0 (September 18, 2022) 7 | - Add support for the Poetry package manager 8 | 9 | ## 1.5.2 (September 13, 2022) 10 | - Breaking change: Removed the redundant `SetArgsAndFlags` setter from `DotnetModule`. 11 | - Add `DotnetModule` getters. 12 | 13 | ## 1.5.1 (September 5, 2022) 14 | - Fix Nuget requestedBy calculation. 15 | 16 | ## 1.5.0 (Aug 28, 2022) 17 | - Update dependencies 18 | - Update go to 1.18 19 | - Update jfrog-ecosystem-integration-env to latest 20 | - Fix multi lines NuGet project definition 21 | 22 | ## 1.4.1 (July 3, 2022) 23 | - Move IsStringInSlice out from fileutils 24 | - The latest npm tests have been updated to work with npm versions 8.11.0 and above 25 | 26 | ## 1.4.0 (July 3, 2022) 27 | - Changed RunCmdWithOutputParser to run in silent mode 28 | - Changes for Yarn Audit 29 | 30 | ## 1.3.0 (June 7, 2022) 31 | - Add Dotnet support 32 | - Bug: Duplicate artifacts are counted by their paths instead of their names 33 | 34 | ## 1.2.6 (May 8, 2022) 35 | - Added pip & pipenv usage to the README 36 | - Bug fix - Missing npm dependencies cause an error 37 | 38 | ## 1.2.5 (April 21, 2022) 39 | - Upgrade build-info-extractor-maven to 2.36.2 40 | - Upgrade build-info-extractor-gradle to 4.28.2 41 | - Bug fix - Build-info collection for npm nay fail due to peer dependencies conflicts 42 | 43 | ## 1.2.4 (April 14, 2022) 44 | - Bug fix - Missing npm depedencies should not return an error 45 | 46 | ## 1.2.3 (April 11, 2022) 47 | - Support for Python 48 | 49 | ## 1.2.2 (March 31, 2022) 50 | - Bug fix - Avoid adding optional npm dependencies to the build-info 51 | 52 | ## 1.2.1 (March 27, 2022) 53 | - Upgrade build-info-extractor-maven to 2.36.1 and gradle-artifactory-plugin 4.28.1 54 | 55 | ## 1.2.0 (March 24, 2022) 56 | - Allow calculating npm deps without checksums 57 | - Move build-info schema to a file and allow validating it 58 | 59 | ## 1.1.1 (March 18, 2022) 60 | - Upgrade maven & gradle build-info extractors 61 | - New static code analysis badges added to README 62 | 63 | ## 1.1.0 (February 24, 2022) 64 | - Support for yarn 65 | - Add checksum to npm dependencies 66 | - Bug fix - Limit the total for RequestedBy, to avoid out-of-memory errors 67 | 68 | ## 1.0.1 (January 30, 2022) 69 | - Bug fix - Gradle - Avoid potential ambigues task error 70 | - Bug fix - Go - Change Go dependency ID syntax to '{dependencyName}:v{dependecyVersion) 71 | - Bug fix - Add build name/number/project to Maven & Gradle extractors 72 | - Bug fix - Avoid creating a redundant build-info module in some scenarios 73 | - Bug fix - Implicit memory aliasing in for loop whereby the targetBuildInfo modules may be reused accidentally 74 | 75 | ## 1.0.0 (January 6, 2022) 76 | - Support for generating build-info for npm 77 | - Generate and populate sha256 78 | - Populate requestedBy field 79 | - Allow converting to CycloneDX BOM 80 | - Upgrade build-info to 2.33.0 / 4.26.0 81 | 82 | ## 0.1.6 (December 31, 2021) 83 | - Added isEqual func to module, artifact & dependency structs 84 | - Allow ignoring go list errors 85 | 86 | ## 0.1.5 (December 13, 2021) 87 | - Upgrade dependencies 88 | 89 | ## 0.1.4 (November 30, 2021) 90 | - Upgrade dependencies 91 | 92 | ## 0.1.3 (November 29, 2021) 93 | - Upgrade dependencies 94 | 95 | ## 0.1.2 (November 25, 2021) 96 | - Bug fix - Publishing build-info can fail, if a previous build-info collection action left an empty cache file 97 | 98 | ## 0.1.1 (November 21, 2021) 99 | - Hash build dir with sha256 100 | 101 | ## 0.1.0 (November 10, 2021) 102 | - Initial release: support in generating build-info for Go, Maven and Gradle 103 | -------------------------------------------------------------------------------- /build/build_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "github.com/jfrog/build-info-go/entities" 5 | "github.com/stretchr/testify/assert" 6 | "os" 7 | "testing" 8 | ) 9 | 10 | func TestCollectEnv(t *testing.T) { 11 | tests := []struct { 12 | description string 13 | include []string 14 | exclude []string 15 | expected entities.Env 16 | expectError bool 17 | }{ 18 | { 19 | description: "just include", 20 | include: []string{"BI_TEST_COLLECT_*", "BI_TEST_ALSO_cOLLeCt"}, 21 | exclude: nil, 22 | expected: entities.Env{ 23 | "buildInfo.env.BI_TEST_COLLECT_1": "val", 24 | "buildInfo.env.BI_TEST_COLLECT_2": "val", 25 | "buildInfo.env.BI_TEST_ALSO_COLLECT": "val", 26 | }, 27 | expectError: false, 28 | }, 29 | { 30 | description: "include and exclude", 31 | include: []string{"BI_TEST_*"}, 32 | exclude: []string{"BI_TEST_DoNt_*", "*ALSO*"}, 33 | expected: entities.Env{ 34 | "buildInfo.env.BI_TEST_COLLECT_1": "val", 35 | "buildInfo.env.BI_TEST_COLLECT_2": "val", 36 | }, 37 | expectError: false, 38 | }, 39 | } 40 | 41 | env := entities.Env{ 42 | "BI_TEST_COLLECT_1": "val", 43 | "BI_TEST_COLLECT_2": "val", 44 | "BI_TEST_ALSO_COLLECT": "val", 45 | "BI_TEST_DONT_COLLECT": "val", 46 | "BI_TEST_ALSO_DONT_COLLECT": "val", 47 | } 48 | 49 | // Set environment variables 50 | defer func() { 51 | for key := range env { 52 | assert.NoError(t, os.Unsetenv(key)) 53 | } 54 | }() 55 | for key, value := range env { 56 | assert.NoError(t, os.Setenv(key, value)) 57 | } 58 | 59 | service := NewBuildInfoService() 60 | for _, tc := range tests { 61 | t.Run(tc.description, func(t *testing.T) { 62 | build, err := service.GetOrCreateBuild("bi-test", "1") 63 | assert.NoError(t, err) 64 | assert.NoError(t, build.CollectEnv()) 65 | buildInfo, err := build.ToBuildInfo() 66 | assert.NoError(t, err) 67 | err = buildInfo.IncludeEnv(tc.include...) 68 | if tc.expectError { 69 | assert.Error(t, err) 70 | return 71 | } 72 | assert.NoError(t, err) 73 | err = buildInfo.ExcludeEnv(tc.exclude...) 74 | assert.NoError(t, err) 75 | assert.Equal(t, tc.expected, buildInfo.Properties) 76 | assert.Empty(t, buildInfo.Modules) 77 | err = build.Clean() 78 | assert.NoError(t, err) 79 | }) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /build/dotnet_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "os" 6 | "path/filepath" 7 | "testing" 8 | ) 9 | 10 | func TestUpdateSolutionPathAndGetFileName(t *testing.T) { 11 | workingDir, err := os.Getwd() 12 | assert.NoError(t, err) 13 | tests := []struct { 14 | name string 15 | flags []string 16 | solutionPath string 17 | expectedSlnFile string 18 | expectedSolutionPath string 19 | }{ 20 | {"emptyFlags", []string{}, workingDir, "", workingDir}, 21 | {"justFlags", []string{"-flag1", "value1", "-flag2", "value2"}, workingDir, "", workingDir}, 22 | {"relFileArgRelPath1", []string{filepath.Join("testdata", "dotnet", "slnDir", "sol.sln")}, filepath.Join("rel", "path"), "sol.sln", filepath.Join("rel", "path", "testdata", "dotnet", "slnDir")}, 23 | {"relDirArgRelPath2", []string{filepath.Join("testdata", "dotnet", "slnDir")}, filepath.Join("rel", "path"), "", filepath.Join("rel", "path", "testdata", "dotnet", "slnDir")}, 24 | {"absFileArgRelPath1", []string{filepath.Join(workingDir, "testdata", "dotnet", "slnDir", "sol.sln")}, filepath.Join(".", "rel", "path"), "sol.sln", filepath.Join(workingDir, "testdata", "dotnet", "slnDir")}, 25 | {"absDirArgRelPath2", []string{filepath.Join(workingDir, "testdata", "dotnet", "slnDir"), "-flag", "value"}, filepath.Join(".", "rel", "path"), "", filepath.Join(workingDir, "testdata", "dotnet", "slnDir")}, 26 | {"nonExistingFile", []string{filepath.Join(".", "dir1", "sol.sln")}, workingDir, "", workingDir}, 27 | {"nonExistingPath", []string{filepath.Join(workingDir, "non", "existing", "path")}, workingDir, "", workingDir}, 28 | {"relCsprojFile", []string{filepath.Join("testdata", "dotnet", "slnDir", "proj.csproj")}, filepath.Join("rel", "path"), "", filepath.Join("rel", "path", "testdata", "dotnet", "slnDir")}, 29 | {"relVbprojFile", []string{filepath.Join("testdata", "dotnet", "slnDir", "projTwo.vbproj")}, filepath.Join("rel", "path"), "", filepath.Join("rel", "path", "testdata", "dotnet", "slnDir")}, 30 | {"absCsprojFile", []string{filepath.Join(workingDir, "testdata", "dotnet", "slnDir", "proj.csproj")}, filepath.Join("rel", "path"), "", filepath.Join(workingDir, "testdata", "dotnet", "slnDir")}, 31 | {"absVbprojFile", []string{filepath.Join(workingDir, "testdata", "dotnet", "slnDir", "projTwo.vbproj")}, filepath.Join("rel", "path"), "", filepath.Join(workingDir, "testdata", "dotnet", "slnDir")}, 32 | {"relPackagesConfigFile", []string{filepath.Join("testdata", "dotnet", "slnDir", "packages.config")}, filepath.Join("rel", "path"), "", filepath.Join("rel", "path", "testdata", "dotnet", "slnDir")}, 33 | {"absPackagesConfigFile", []string{filepath.Join(workingDir, "testdata", "dotnet", "slnDir", "packages.config")}, filepath.Join("rel", "path"), "", filepath.Join(workingDir, "testdata", "dotnet", "slnDir")}, 34 | } 35 | for _, test := range tests { 36 | t.Run(test.name, func(t *testing.T) { 37 | dc := DotnetModule{solutionPath: test.solutionPath, argAndFlags: test.flags} 38 | slnFile, err := dc.updateSolutionPathAndGetFileName() 39 | assert.NoError(t, err) 40 | assert.Equal(t, test.expectedSlnFile, slnFile) 41 | assert.Equal(t, test.expectedSolutionPath, dc.solutionPath) 42 | }) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /build/golang_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "path/filepath" 5 | "testing" 6 | 7 | "github.com/jfrog/build-info-go/entities" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestGenerateBuildInfoForGoProject(t *testing.T) { 12 | service := NewBuildInfoService() 13 | goBuild, err := service.GetOrCreateBuild("build-info-go-test-golang", "1") 14 | assert.NoError(t, err) 15 | defer func() { 16 | assert.NoError(t, goBuild.Clean()) 17 | }() 18 | goModule, err := goBuild.AddGoModule(filepath.Join("testdata", "golang", "project")) 19 | if assert.NoError(t, err) { 20 | err = goModule.CalcDependencies() 21 | assert.NoError(t, err) 22 | err = goModule.AddArtifacts(entities.Artifact{Name: "artifactName", Type: "artifactType", Path: "artifactPath", Checksum: entities.Checksum{Sha1: "123", Md5: "456", Sha256: "789"}}) 23 | assert.NoError(t, err) 24 | buildInfo, err := goBuild.ToBuildInfo() 25 | assert.NoError(t, err) 26 | assert.Len(t, buildInfo.Modules, 1) 27 | validateModule(t, buildInfo.Modules[0], 6, 1, "github.com/jfrog/dependency", entities.Go, true) 28 | validateRequestedBy(t, buildInfo.Modules[0]) 29 | } 30 | } 31 | 32 | func validateRequestedBy(t *testing.T, module entities.Module) { 33 | for _, dep := range module.Dependencies { 34 | if assert.NotEmpty(t, dep.RequestedBy, dep.Id+" RequestedBy field is empty") { 35 | switch dep.Id { 36 | // Direct dependencies: 37 | case "rsc.io/quote:v1.5.2", "github.com/jfrog/gofrog:v1.1.1": 38 | assert.Equal(t, [][]string{{module.Id}}, dep.RequestedBy) 39 | 40 | // Indirect dependencies: 41 | case "golang.org/x/text:v0.0.0-20170915032832-14c0d48ead0c": 42 | assert.Equal(t, [][]string{{"rsc.io/sampler:v1.3.0", "rsc.io/quote:v1.5.2", module.Id}}, dep.RequestedBy) 43 | 44 | case "rsc.io/sampler:v1.3.0": 45 | assert.Equal(t, [][]string{{"rsc.io/quote:v1.5.2", module.Id}}, dep.RequestedBy) 46 | 47 | // 2 requestedBy lists: 48 | case "github.com/pkg/errors:v0.8.0": 49 | assert.Equal(t, [][]string{ 50 | {"github.com/jfrog/gofrog:v1.1.1", module.Id}, 51 | {module.Id}, 52 | }, dep.RequestedBy) 53 | 54 | // Uppercase encoded module (!burnt!sushi --> BurntSushi) 55 | case "github.com/!burnt!sushi/toml:v0.4.2-0.20211125115023-7d0236fe7476": 56 | assert.Equal(t, [][]string{{module.Id}}, dep.RequestedBy) 57 | 58 | default: 59 | assert.Fail(t, "Unexpected dependency "+dep.Id) 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /build/init-gradle-extractor-4.gradle: -------------------------------------------------------------------------------- 1 | import org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin 2 | import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask 3 | 4 | initscript { 5 | dependencies { 6 | classpath fileTree('${pluginLibDir}') 7 | } 8 | } 9 | 10 | addListener(new BuildInfoPluginListener()) 11 | 12 | class BuildInfoPluginListener extends BuildAdapter { 13 | 14 | def void projectsLoaded(Gradle gradle) { 15 | Map projectProperties = new HashMap(gradle.startParameter.getProjectProperties()) 16 | projectProperties.put("build.start", Long.toString(System.currentTimeMillis())) 17 | gradle.startParameter.setProjectProperties(projectProperties) 18 | Project root = gradle.getRootProject() 19 | root.logger.debug("Artifactory plugin: projectsEvaluated: ${root.name}") 20 | if (!"buildSrc".equals(root.name)) { 21 | root.allprojects { 22 | apply { 23 | apply plugin: ArtifactoryPlugin 24 | } 25 | } 26 | } 27 | 28 | // Set the "mavenJava" and "ivyJava" publications or 29 | // "archives" configuration to all Artifactory tasks. 30 | for (Project p : root.getAllprojects()) { 31 | Task t = p.getTasks().findByName(ArtifactoryTask.ARTIFACTORY_PUBLISH_TASK_NAME) 32 | if (t != null) { 33 | ArtifactoryTask task = (ArtifactoryTask) t 34 | task.setCiServerBuild() 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /build/init-gradle-extractor-5.gradle: -------------------------------------------------------------------------------- 1 | import org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin 2 | import org.jfrog.gradle.plugin.artifactory.ArtifactoryPluginSettings 3 | import org.jfrog.gradle.plugin.artifactory.Constant 4 | import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask 5 | 6 | initscript { 7 | dependencies { 8 | classpath fileTree('${pluginLibDir}') 9 | } 10 | } 11 | 12 | beforeSettings { Settings settings -> 13 | settings.apply plugin: ArtifactoryPluginSettings 14 | } 15 | 16 | projectsLoaded { Gradle gradle -> 17 | Map projectProperties = new HashMap(gradle.startParameter.getProjectProperties()) 18 | projectProperties.put("build.start", Long.toString(System.currentTimeMillis())) 19 | gradle.startParameter.setProjectProperties(projectProperties) 20 | Project root = gradle.getRootProject() 21 | root.logger.debug("Artifactory plugin: projectsEvaluated: ${root.name}") 22 | if (!"buildSrc".equals(root.name)) { 23 | root.allprojects { 24 | apply { 25 | apply plugin: ArtifactoryPlugin 26 | } 27 | } 28 | } 29 | 30 | // Set the CI Server mode to all Artifactory tasks. 31 | for (Project p : root.getAllprojects()) { 32 | try { 33 | TaskProvider subCollectInfoTask = p.getTasks().named(Constant.ARTIFACTORY_PUBLISH_TASK_NAME, ArtifactoryTask.class); 34 | subCollectInfoTask.configure { task -> 35 | task.setCiServerBuild() 36 | } 37 | } catch (UnknownTaskException ignored) { 38 | root.logger.debug("Can't find sub project configured for {}", p.getPath()); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /build/npm_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "path/filepath" 5 | "strconv" 6 | "testing" 7 | "time" 8 | 9 | buildutils "github.com/jfrog/build-info-go/build/utils" 10 | "github.com/jfrog/build-info-go/entities" 11 | "github.com/jfrog/build-info-go/tests" 12 | "github.com/jfrog/build-info-go/utils" 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | var logger = utils.NewDefaultLogger(utils.INFO) 17 | 18 | func TestGenerateBuildInfoForNpm(t *testing.T) { 19 | service := NewBuildInfoService() 20 | npmBuild, err := service.GetOrCreateBuild("build-info-go-test-npm", strconv.FormatInt(time.Now().Unix(), 10)) 21 | assert.NoError(t, err) 22 | defer func() { 23 | assert.NoError(t, npmBuild.Clean()) 24 | }() 25 | npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(logger) 26 | assert.NoError(t, err) 27 | 28 | // Create npm project. 29 | path, err := filepath.Abs(filepath.Join(".", "testdata")) 30 | assert.NoError(t, err) 31 | projectPath, cleanup := tests.CreateNpmTest(t, path, "project3", false, npmVersion) 32 | defer cleanup() 33 | 34 | // Install dependencies in the npm project. 35 | npmArgs := []string{"--cache=" + filepath.Join(projectPath, "tmpcache")} 36 | _, _, err = buildutils.RunNpmCmd("npm", projectPath, buildutils.AppendNpmCommand(npmArgs, "install"), logger) 37 | assert.NoError(t, err) 38 | npmModule, err := npmBuild.AddNpmModule(projectPath) 39 | assert.NoError(t, err) 40 | npmModule.SetNpmArgs(npmArgs) 41 | err = npmModule.CalcDependencies() 42 | assert.NoError(t, err) 43 | buildInfo, err := npmBuild.ToBuildInfo() 44 | assert.NoError(t, err) 45 | 46 | // Verify results. 47 | expectedBuildInfoJson := filepath.Join(projectPath, "expected_npm_buildinfo.json") 48 | expectedBuildInfo := tests.GetBuildInfo(t, expectedBuildInfoJson) 49 | match, err := entities.IsEqualModuleSlices(buildInfo.Modules, expectedBuildInfo.Modules) 50 | assert.NoError(t, err) 51 | if !match { 52 | tests.PrintBuildInfoMismatch(t, expectedBuildInfo.Modules, buildInfo.Modules) 53 | } 54 | } 55 | 56 | func TestFilterNpmArgsFlags(t *testing.T) { 57 | service := NewBuildInfoService() 58 | npmBuild, err := service.GetOrCreateBuild("build-info-go-test-npm", strconv.FormatInt(time.Now().Unix(), 10)) 59 | assert.NoError(t, err) 60 | defer func() { 61 | assert.NoError(t, npmBuild.Clean()) 62 | }() 63 | npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(logger) 64 | assert.NoError(t, err) 65 | 66 | // Create npm project. 67 | path, err := filepath.Abs(filepath.Join(".", "testdata")) 68 | assert.NoError(t, err) 69 | projectPath, cleanup := tests.CreateNpmTest(t, path, "project3", false, npmVersion) 70 | defer cleanup() 71 | 72 | // Set arguments in npmArgs. 73 | npmArgs := []string{"ls", "--package-lock-only"} 74 | _, _, err = buildutils.RunNpmCmd("npm", projectPath, buildutils.AppendNpmCommand(npmArgs, "install"), logger) 75 | assert.NoError(t, err) 76 | npmModule, err := npmBuild.AddNpmModule(projectPath) 77 | assert.NoError(t, err) 78 | npmModule.SetNpmArgs(npmArgs) 79 | npmModule.filterNpmArgsFlags() 80 | expected := []string{"--package-lock-only"} 81 | assert.Equal(t, expected, npmModule.npmArgs) 82 | npmArgs = []string{"config", "cache", "--json", "--all"} 83 | npmModule.SetNpmArgs(npmArgs) 84 | npmModule.filterNpmArgsFlags() 85 | expected = []string{"--json", "--all"} 86 | assert.Equal(t, expected, npmModule.npmArgs) 87 | } 88 | -------------------------------------------------------------------------------- /build/python_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "path/filepath" 5 | "strconv" 6 | "testing" 7 | "time" 8 | 9 | "github.com/jfrog/build-info-go/entities" 10 | "github.com/jfrog/build-info-go/utils/pythonutils" 11 | 12 | "github.com/jfrog/build-info-go/tests" 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | func TestGenerateBuildInfoForPython(t *testing.T) { 17 | allTests := []struct { 18 | name string 19 | pythonTool pythonutils.PythonTool 20 | cmdArgs []string 21 | moduleName string 22 | expectedResultsJson string 23 | }{ 24 | {"pip-with-module", pythonutils.Pip, []string{".", "--no-cache-dir", "--force-reinstall"}, "testModuleName:1.0.0", "expected_pip_buildinfo_with_module_name.json"}, 25 | {"pip-without-module", pythonutils.Pip, []string{".", "--no-cache-dir", "--force-reinstall"}, "", "expected_pip_buildinfo_without_module_name.json"}, 26 | 27 | {"pipenv-with-module", pythonutils.Pipenv, []string{}, "testModuleName:1.0.0", "expected_pipenv_buildinfo_with_module_name.json"}, 28 | {"pipenv-without-module", pythonutils.Pipenv, []string{}, "", "expected_pipenv_buildinfo_without_module_name.json"}, 29 | } 30 | // Run test cases. 31 | for _, test := range allTests { 32 | t.Run(test.name, func(t *testing.T) { 33 | testGenerateBuildInfoForPython(t, test.pythonTool, test.cmdArgs, test.moduleName, test.expectedResultsJson) 34 | }) 35 | } 36 | } 37 | 38 | func testGenerateBuildInfoForPython(t *testing.T, pythonTool pythonutils.PythonTool, cmdArgs []string, moduleName, expectedResultsJson string) { 39 | service := NewBuildInfoService() 40 | pythonBuild, err := service.GetOrCreateBuild("build-info-go-test-"+string(pythonTool), strconv.FormatInt(time.Now().Unix(), 10)) 41 | assert.NoError(t, err) 42 | defer func() { 43 | assert.NoError(t, pythonBuild.Clean()) 44 | }() 45 | // Create npm project. 46 | testdataDir, err := filepath.Abs(filepath.Join(".", "testdata")) 47 | assert.NoError(t, err) 48 | // Create python project 49 | projectPath := filepath.Join(testdataDir, "python", string(pythonTool)) 50 | tmpProjectPath, cleanup := tests.CreateTestProject(t, projectPath) 51 | defer cleanup() 52 | 53 | // Install dependencies in the pip project. 54 | pythonModule, err := pythonBuild.AddPythonModule(tmpProjectPath, pythonTool) 55 | assert.NoError(t, err) 56 | pythonModule.SetName(moduleName) 57 | assert.NoError(t, pythonModule.RunInstallAndCollectDependencies(cmdArgs)) 58 | buildInfo, err := pythonBuild.ToBuildInfo() 59 | if assert.NoError(t, err) { 60 | // Verify results. 61 | expectedBuildInfoJson := filepath.Join(projectPath, expectedResultsJson) 62 | expectedBuildInfo := tests.GetBuildInfo(t, expectedBuildInfoJson) 63 | match, err := entities.IsEqualModuleSlices(buildInfo.Modules, expectedBuildInfo.Modules) 64 | assert.NoError(t, err) 65 | if !match { 66 | tests.PrintBuildInfoMismatch(t, expectedBuildInfo.Modules, buildInfo.Modules) 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /build/service.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "os" 7 | "path/filepath" 8 | "time" 9 | 10 | buildinfo "github.com/jfrog/build-info-go/entities" 11 | "github.com/jfrog/build-info-go/utils" 12 | ) 13 | 14 | const BuildsTempPath = "jfrog/builds/" 15 | 16 | type BuildInfoService struct { 17 | tempDirPath string 18 | logger utils.Log 19 | } 20 | 21 | func NewBuildInfoService() *BuildInfoService { 22 | return &BuildInfoService{tempDirPath: filepath.Join(os.TempDir(), BuildsTempPath), logger: &utils.NullLog{}} 23 | } 24 | 25 | func (bis *BuildInfoService) SetTempDirPath(tempDirPath string) { 26 | bis.tempDirPath = tempDirPath 27 | } 28 | 29 | func (bis *BuildInfoService) SetLogger(logger utils.Log) { 30 | bis.logger = logger 31 | } 32 | 33 | // GetOrCreateBuild gets a build from cache, or creates a new one if it doesn't exist. 34 | // It's important to invoke this function at the very beginning of the build, so that the start time property in the build-info will be accurate. 35 | func (bis *BuildInfoService) GetOrCreateBuild(buildName, buildNumber string) (*Build, error) { 36 | return bis.GetOrCreateBuildWithProject(buildName, buildNumber, "") 37 | } 38 | 39 | // GetOrCreateBuildWithProject gets a build from cache, or creates a new one if it doesn't exist. 40 | // It's important to invoke this function at the very beginning of the build, so that the start time property in the build-info will be accurate. 41 | func (bis *BuildInfoService) GetOrCreateBuildWithProject(buildName, buildNumber, projectKey string) (build *Build, err error) { 42 | buildTime := time.Now() 43 | if len(buildName) > 0 && len(buildNumber) > 0 { 44 | if buildTime, err = getOrCreateBuildGeneralDetails(buildName, buildNumber, buildTime, projectKey, bis.tempDirPath, bis.logger); err != nil { 45 | return 46 | } 47 | } 48 | return NewBuild(buildName, buildNumber, buildTime, projectKey, bis.tempDirPath, bis.logger), nil 49 | } 50 | 51 | func getOrCreateBuildGeneralDetails(buildName, buildNumber string, buildTime time.Time, projectKey, buildsDirPath string, log utils.Log) (time.Time, error) { 52 | partialsBuildDir, err := utils.GetPartialsBuildDir(buildName, buildNumber, projectKey, buildsDirPath) 53 | if err != nil { 54 | return buildTime, err 55 | } 56 | detailsFilePath := filepath.Join(partialsBuildDir, BuildInfoDetails) 57 | var exists bool 58 | exists, err = utils.IsFileExists(detailsFilePath, true) 59 | if err != nil { 60 | return buildTime, err 61 | } 62 | if exists { 63 | log.Debug("Reading build general details from: " + partialsBuildDir) 64 | var generalDetails *buildinfo.General 65 | generalDetails, err = ReadBuildInfoGeneralDetails(buildName, buildNumber, projectKey, buildsDirPath) 66 | return generalDetails.Timestamp, err 67 | } 68 | log.Debug("Saving build general details at: " + partialsBuildDir) 69 | meta := buildinfo.General{ 70 | Timestamp: buildTime, 71 | } 72 | b, err := json.Marshal(&meta) 73 | if err != nil { 74 | return buildTime, err 75 | } 76 | var content bytes.Buffer 77 | err = json.Indent(&content, b, "", " ") 78 | if err != nil { 79 | return buildTime, err 80 | } 81 | return buildTime, os.WriteFile(detailsFilePath, content.Bytes(), 0600) 82 | } 83 | -------------------------------------------------------------------------------- /build/testdata/dotnet/slnDir/packages.config: -------------------------------------------------------------------------------- 1 | This is a packages.config file for .Net tests -------------------------------------------------------------------------------- /build/testdata/dotnet/slnDir/proj.csproj: -------------------------------------------------------------------------------- 1 | This is a csproj file for .Net tests -------------------------------------------------------------------------------- /build/testdata/dotnet/slnDir/projTwo.vbproj: -------------------------------------------------------------------------------- 1 | This is a vbproj file for .Net tests -------------------------------------------------------------------------------- /build/testdata/dotnet/slnDir/sol.sln: -------------------------------------------------------------------------------- 1 | This is a solution file for .Net tests -------------------------------------------------------------------------------- /build/testdata/golang/project/dependency.go: -------------------------------------------------------------------------------- 1 | package dependency 2 | 3 | import ( 4 | "fmt" 5 | "github.com/BurntSushi/toml" 6 | "github.com/jfrog/gofrog/version" 7 | "github.com/pkg/errors" 8 | "rsc.io/quote" 9 | ) 10 | 11 | func PrintHello(ver *version.Version, re *toml.Key) error { 12 | fmt.Println(quote.Hello()) 13 | return errors.New("abc") 14 | } 15 | -------------------------------------------------------------------------------- /build/testdata/golang/project/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/jfrog/dependency 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/BurntSushi/toml v0.4.2-0.20211125115023-7d0236fe7476 7 | github.com/jfrog/gofrog v1.1.1 8 | github.com/pkg/errors v0.8.0 9 | rsc.io/quote v1.5.2 10 | ) -------------------------------------------------------------------------------- /build/testdata/golang/project/go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.4.2-0.20211125115023-7d0236fe7476 h1:AJe2An/bK0YZUpl4YCTlnZYUMMNMu+zB/oWPrKPdG64= 2 | github.com/BurntSushi/toml v0.4.2-0.20211125115023-7d0236fe7476/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/jfrog/gofrog v1.1.1 h1:uRjeZWidQl4FmKP4Zpj5hSKJp3gSIWW9VUwbQdVEVRU= 5 | github.com/jfrog/gofrog v1.1.1/go.mod h1:9YN5v4LlsCfLIXpwQnzSf1wVtgjdHM20FzuIu58RMI4= 6 | github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= 7 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 9 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 10 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 11 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8= 12 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 13 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 14 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 15 | rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= 16 | rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= 17 | rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= 18 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 19 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8.1/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # These are explicitly windows files and should use crlf 5 | *.bat text eol=crlf 6 | 7 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8.1/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | # Ignore Gradle build output directory 5 | build 6 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8.1/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * This is a general purpose Gradle build. 5 | * Learn more about Gradle by exploring our samples at https://docs.gradle.org/6.9.3/samples 6 | */ 7 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8.1/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/testdata/gradle/gradle-6.8.1/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8.1/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8.1/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8.1/settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/6.9.3/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = 'gradle-6.8.1' 11 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # These are explicitly windows files and should use crlf 5 | *.bat text eol=crlf 6 | 7 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | # Ignore Gradle build output directory 5 | build 6 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * This is a general purpose Gradle build. 5 | * Learn more about Gradle by exploring our samples at https://docs.gradle.org/6.9.3/samples 6 | */ 7 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/testdata/gradle/gradle-6.8/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-6.8/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/6.9.3/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = "gradle-6.8" 11 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-7.0/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # These are explicitly windows files and should use crlf 5 | *.bat text eol=crlf 6 | 7 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-7.0/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | # Ignore Gradle build output directory 5 | build 6 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-7.0/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * This is a general purpose Gradle build. 5 | * Learn more about Gradle by exploring our samples at https://docs.gradle.org/6.9.3/samples 6 | */ 7 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-7.0/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/testdata/gradle/gradle-7.0/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-7.0/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-7.0/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /build/testdata/gradle/gradle-7.0/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/6.9.3/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = "gradle-7.0" 11 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.jfrog.test 6 | multi 7 | 3.7-SNAPSHOT 8 | 9 | 10 | multi1 11 | jar 12 | Multi 1 13 | 14 | 15 | 16 | apache 17 | none 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-source-plugin 26 | 27 | 28 | attach-sources 29 | 30 | jar 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-jar-plugin 39 | 40 | 41 | 42 | test-jar 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.apache.commons 53 | commons-email 54 | 1.1 55 | compile 56 | 57 | 58 | org.codehaus.plexus 59 | plexus-utils 60 | 1.5.1 61 | 62 | 63 | javax.servlet.jsp 64 | jsp-api 65 | 2.1 66 | compile 67 | 68 | 69 | commons-io 70 | commons-io 71 | 1.4 72 | 73 | 74 | org.springframework 75 | spring-aop 76 | 2.5.6 77 | 78 | 79 | 80 | 81 | org.testng 82 | testng 83 | jdk15 84 | 5.9 85 | test 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi1/src/main/java/artifactory/test/Multi1.java: -------------------------------------------------------------------------------- 1 | package artifactory.test; 2 | 3 | /** 4 | * Hello world! 5 | */ 6 | public class Multi1 { 7 | public static void main(String[] args) { 8 | System.out.println("Hello World!"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi1/src/test/java/artifactory/test/AppTest.java: -------------------------------------------------------------------------------- 1 | package artifactory.test; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.jfrog.test 6 | multi 7 | 3.7-SNAPSHOT 8 | 9 | 10 | 11 | ${project.parent.version} 12 | 13 | 14 | multi2 15 | 3.7-SNAPSHOT 16 | jar 17 | Multi 2 18 | 19 | 20 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi2/src/main/java/artifactory/test/App.java: -------------------------------------------------------------------------------- 1 | package artifactory.test; 2 | 3 | /** 4 | * Hello world! 5 | * 6 | */ 7 | public class App 8 | { 9 | public static void main( String[] args ) 10 | { 11 | System.out.println( "Hello World!" ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi2/src/test/java/artifactory/test/AppTest.java: -------------------------------------------------------------------------------- 1 | package artifactory.test; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.jfrog.test 5 | multi 6 | 3.7-SNAPSHOT 7 | 8 | 9 | multi3 10 | war 11 | Multi 3 12 | 13 | 14 | 15 | 16 | ${project.groupId} 17 | multi1 18 | ${project.parent.version} 19 | 20 | 21 | 22 | 23 | 24 | hsqldb 25 | hsqldb 26 | 1.8.0.10 27 | runtime 28 | 29 | 30 | 31 | 32 | javax.servlet 33 | servlet-api 34 | 2.5 35 | provided 36 | 37 | 38 | 39 | 40 | 41 | assembly 42 | 43 | 44 | 45 | maven-assembly-plugin 46 | 2.2-beta-5 47 | 48 | 49 | jar-with-dependencies 50 | 51 | 52 | 53 | 54 | make-assembly 55 | package 56 | 57 | single 58 | 59 | 60 | 61 | 62 | 63 | org.apache.maven.plugins 64 | maven-war-plugin 65 | 66 | 67 | false 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi3/src/main/java/artifactory/test/Multi3.java: -------------------------------------------------------------------------------- 1 | package artifactory.test; 2 | 3 | /** 4 | * Hello world! 5 | */ 6 | public class Multi3 { 7 | public static void main(String[] args) { 8 | new Multi1(); 9 | System.out.println("Hello World!"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi3/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | test-webapp 8 | 9 | -------------------------------------------------------------------------------- /build/testdata/maven/project/multi3/src/test/java/artifactory/test/AppTest.java: -------------------------------------------------------------------------------- 1 | package artifactory.test; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /build/testdata/maven/project/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | org.jfrog.test 6 | multi 7 | 3.7-SNAPSHOT 8 | pom 9 | Simple Multi Modules Build 10 | 11 | 12 | multi1 13 | multi2 14 | multi3 15 | 16 | 17 | 18 | UTF-8 19 | 1.8 20 | 1.8 21 | 22 | 23 | 24 | 25 | junit 26 | junit 27 | 3.8.1 28 | test 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-jar-plugin 38 | 2.4 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-war-plugin 43 | 2.4 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-source-plugin 48 | 2.1.2 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-jar-plugin 56 | 57 | 58 | false 59 | 60 | 61 | 62 | 63 | org.apache.maven.plugins 64 | maven-war-plugin 65 | 66 | 67 | false 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /build/testdata/npm/_cacache/content-v2/sha1/67/6f/6eb3c39997c2ee1ac3a924fd6124748f578d: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/testdata/npm/_cacache/content-v2/sha1/67/6f/6eb3c39997c2ee1ac3a924fd6124748f578d -------------------------------------------------------------------------------- /build/testdata/npm/_cacache/content-v2/sha512/32/d8/be7fd96924d730178b5657cfcead34ed1758198be7fc16a97201da2eada95c156150585dbe3600874a18e409bf881412eaf5bb99c04d71724414e29792b9: -------------------------------------------------------------------------------- 1 | 123 -------------------------------------------------------------------------------- /build/testdata/npm/_cacache/content-v2/sha512/75/67/b89d63bfaee10e63b1e4509e6016dd4308557dccf46826bf29574fc04907ab98e663b6af233233a9ac2d0a775d062cdfa5ef16943efc732455adc46bbc16: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/testdata/npm/_cacache/content-v2/sha512/75/67/b89d63bfaee10e63b1e4509e6016dd4308557dccf46826bf29574fc04907ab98e663b6af233233a9ac2d0a775d062cdfa5ef16943efc732455adc46bbc16 -------------------------------------------------------------------------------- /build/testdata/npm/_cacache/index-v5/81/fd/fae35857dd2515812284fc5c6ed232049d79503dc73bd919842c593dd6a2: -------------------------------------------------------------------------------- 1 | 2 | 5963f278c6937723d99e9f27410b43297ded776f {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644315589888,"size":2821} 3 | 24e513e816e2fcabcc46029b375560548ae4a5a6 {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644397858890,"size":2821} 4 | 8fc26a42683de34b965546fc336ce79e46c5693d {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644397890584,"size":2821} 5 | 0c516acd118ecea3b053aa2d8c39d10115b9fa0b {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644397911093,"size":2821} 6 | 99ce3b6b794a0ad75bac90835e5a64a192aaeb0c {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644397942442,"size":2821} 7 | 4d4323b1bc3f8dce77c74b67516f9de93d5ed38f {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644397966886,"size":2821} 8 | 55ebabb3f01c8f0818e2a6f7a275c0bb21b3b8d9 {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644398038593,"size":2821} 9 | 0420a74e9b67dda681e31316b3f7f345cd588cf8 {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644398075379,"size":2821} 10 | 4b62997420de59624abad4e4709decc67676e4c3 {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644398101022,"size":2821} 11 | 631e438f8892d2ad9606a38f4abd72874032ab4f {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644398122516,"size":2821} 12 | 4edd6c6a053cd8eb0b75183452ac213e4092a3ef {"key":"pacote:tarball:ansi-regex@5.0.0","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644398452109,"size":2821} -------------------------------------------------------------------------------- /build/testdata/npm/noBuildProject/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm_test2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "lightweight": "^0.1.0", 13 | "minimist": "^0.1.0", 14 | "underscore": "^1.13.6", 15 | "cors.js": "0.0.1-security" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /build/testdata/npm/project1/npmv6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "description": "test package", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "yargs": "4.1.0", 13 | "xml": "1.0.1", 14 | "debug": "4.3.3" 15 | }, 16 | "devDependencies": { 17 | "@types/mocha": "^9.0.0", 18 | "nyc": "^15.1.0" 19 | }, 20 | "bundledDependencies": [ 21 | "yargs" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /build/testdata/npm/project1/npmv7/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "description": "test package", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "debug": "4.3.3", 13 | "xml": "1.0.1", 14 | "yargs": "4.1.0" 15 | }, 16 | "devDependencies": { 17 | "@types/mocha": "^9.0.0", 18 | "nyc": "^15.1.0" 19 | }, 20 | "bundledDependencies": [ 21 | "yargs" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /build/testdata/npm/project1/npmv8/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "description": "test package", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "yargs": "4.1.0", 13 | "xml": "1.0.1", 14 | "debug": "4.3.3" 15 | }, 16 | "devDependencies": { 17 | "@types/mocha": "^9.0.0", 18 | "nyc": "^15.1.0" 19 | }, 20 | "bundledDependencies": [ 21 | "yargs" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /build/testdata/npm/project2/npmv6/linux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jfrogtest", 3 | "version": "5.2.0", 4 | "description": "jfrogtest client for Node.js", 5 | "files": [ 6 | "dist/" 7 | ], 8 | "homepage": "https://jfrogtest.net", 9 | "main": "dist/index.js", 10 | "types": "dist/index.d.ts", 11 | "scripts": { 12 | "test": "cross-os _test ", 13 | "build": "tsc", 14 | "build:test": "tsc -p tsconfig.test.json", 15 | "watch": "tsc --watch", 16 | "watch:test": "tsc && tsc --watch -p tsconfig.test.json", 17 | "test:debug": "cross-os _test:debug", 18 | "lint": "tslint src/**/*.ts && tslint test/**/*.ts", 19 | "check-exports": "node ./scripts/reportMissingTopLevelExports.js", 20 | "check-imports": "node scripts/clearGlobalExports.js && tsc -p tsconfig.imports-check.json", 21 | "coverage": "tsc -p tsconfig.test.json && copy test\\Assets\\* .test\\test\\Assets && nyc --exclude=.test/test/** --reporter=html --reporter=text mocha .test\\test" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/jfrogtest/jfrogtest-nodejs-client" 26 | }, 27 | "bugs": { 28 | "email": "support@jfrogtest.net", 29 | "url": "http://issues.jfrogtest.com" 30 | }, 31 | "contributors": [ 32 | "jfrogtest" 33 | ], 34 | "engines": { 35 | "node": ">=6.0.0" 36 | }, 37 | "keywords": [ 38 | "jfrogtest", 39 | "jfrogtest-client", 40 | "typescript", 41 | "node", 42 | "nodejs", 43 | "nosql" 44 | ], 45 | "author": "jfrogtest", 46 | "license": "MIT", 47 | "devDependencies": { 48 | "@types/mocha": "^9.0.0", 49 | "mocha": "^9.1.3", 50 | "nyc": "^15.1.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /build/testdata/npm/project2/npmv6/macos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jfrogtest", 3 | "version": "5.2.0", 4 | "description": "jfrogtest client for Node.js", 5 | "files": [ 6 | "dist/" 7 | ], 8 | "homepage": "https://jfrogtest.net", 9 | "main": "dist/index.js", 10 | "types": "dist/index.d.ts", 11 | "scripts": { 12 | "test": "cross-os _test ", 13 | "build": "tsc", 14 | "build:test": "tsc -p tsconfig.test.json", 15 | "watch": "tsc --watch", 16 | "watch:test": "tsc && tsc --watch -p tsconfig.test.json", 17 | "test:debug": "cross-os _test:debug", 18 | "lint": "tslint src/**/*.ts && tslint test/**/*.ts", 19 | "check-exports": "node ./scripts/reportMissingTopLevelExports.js", 20 | "check-imports": "node scripts/clearGlobalExports.js && tsc -p tsconfig.imports-check.json", 21 | "coverage": "tsc -p tsconfig.test.json && copy test\\Assets\\* .test\\test\\Assets && nyc --exclude=.test/test/** --reporter=html --reporter=text mocha .test\\test" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/jfrogtest/jfrogtest-nodejs-client" 26 | }, 27 | "bugs": { 28 | "email": "support@jfrogtest.net", 29 | "url": "http://issues.jfrogtest.com" 30 | }, 31 | "contributors": [ 32 | "jfrogtest" 33 | ], 34 | "engines": { 35 | "node": ">=6.0.0" 36 | }, 37 | "keywords": [ 38 | "jfrogtest", 39 | "jfrogtest-client", 40 | "typescript", 41 | "node", 42 | "nodejs", 43 | "nosql" 44 | ], 45 | "author": "jfrogtest", 46 | "license": "MIT", 47 | "devDependencies": { 48 | "@types/mocha": "^9.0.0", 49 | "mocha": "^9.1.3", 50 | "nyc": "^15.1.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /build/testdata/npm/project2/npmv6/windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jfrogtest", 3 | "version": "5.2.0", 4 | "description": "jfrogtest client for Node.js", 5 | "files": [ 6 | "dist/" 7 | ], 8 | "homepage": "https://jfrogtest.net", 9 | "main": "dist/index.js", 10 | "types": "dist/index.d.ts", 11 | "scripts": { 12 | "test": "cross-os _test ", 13 | "build": "tsc", 14 | "build:test": "tsc -p tsconfig.test.json", 15 | "watch": "tsc --watch", 16 | "watch:test": "tsc && tsc --watch -p tsconfig.test.json", 17 | "test:debug": "cross-os _test:debug", 18 | "lint": "tslint src/**/*.ts && tslint test/**/*.ts", 19 | "check-exports": "node ./scripts/reportMissingTopLevelExports.js", 20 | "check-imports": "node scripts/clearGlobalExports.js && tsc -p tsconfig.imports-check.json", 21 | "coverage": "tsc -p tsconfig.test.json && copy test\\Assets\\* .test\\test\\Assets && nyc --exclude=.test/test/** --reporter=html --reporter=text mocha .test\\test" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/jfrogtest/jfrogtest-nodejs-client" 26 | }, 27 | "bugs": { 28 | "email": "support@jfrogtest.net", 29 | "url": "http://issues.jfrogtest.com" 30 | }, 31 | "contributors": [ 32 | "jfrogtest" 33 | ], 34 | "engines": { 35 | "node": ">=6.0.0" 36 | }, 37 | "keywords": [ 38 | "jfrogtest", 39 | "jfrogtest-client", 40 | "typescript", 41 | "node", 42 | "nodejs", 43 | "nosql" 44 | ], 45 | "author": "jfrogtest", 46 | "license": "MIT", 47 | "devDependencies": { 48 | "@types/mocha": "^9.0.0", 49 | "mocha": "^9.1.3", 50 | "nyc": "^15.1.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /build/testdata/npm/project2/npmv7/linux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jfrogtest", 3 | "version": "5.2.0", 4 | "description": "jfrogtest client for Node.js", 5 | "files": [ 6 | "dist/" 7 | ], 8 | "homepage": "https://jfrogtest.net", 9 | "main": "dist/index.js", 10 | "types": "dist/index.d.ts", 11 | "scripts": { 12 | "test": "cross-os _test ", 13 | "build": "tsc", 14 | "build:test": "tsc -p tsconfig.test.json", 15 | "watch": "tsc --watch", 16 | "watch:test": "tsc && tsc --watch -p tsconfig.test.json", 17 | "test:debug": "cross-os _test:debug", 18 | "lint": "tslint src/**/*.ts && tslint test/**/*.ts", 19 | "check-exports": "node ./scripts/reportMissingTopLevelExports.js", 20 | "check-imports": "node scripts/clearGlobalExports.js && tsc -p tsconfig.imports-check.json", 21 | "coverage": "tsc -p tsconfig.test.json && copy test\\Assets\\* .test\\test\\Assets && nyc --exclude=.test/test/** --reporter=html --reporter=text mocha .test\\test" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/jfrogtest/jfrogtest-nodejs-client" 26 | }, 27 | "bugs": { 28 | "email": "support@jfrogtest.net", 29 | "url": "http://issues.jfrogtest.com" 30 | }, 31 | "contributors": [ 32 | "jfrogtest" 33 | ], 34 | "engines": { 35 | "node": ">=6.0.0" 36 | }, 37 | "keywords": [ 38 | "jfrogtest", 39 | "jfrogtest-client", 40 | "typescript", 41 | "node", 42 | "nodejs", 43 | "nosql" 44 | ], 45 | "author": "jfrogtest", 46 | "license": "MIT", 47 | "devDependencies": { 48 | "@types/mocha": "^9.0.0", 49 | "mocha": "^9.1.3", 50 | "nyc": "^15.1.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /build/testdata/npm/project2/npmv7/macos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jfrogtest", 3 | "version": "5.2.0", 4 | "description": "jfrogtest client for Node.js", 5 | "files": [ 6 | "dist/" 7 | ], 8 | "homepage": "https://jfrogtest.net", 9 | "main": "dist/index.js", 10 | "types": "dist/index.d.ts", 11 | "scripts": { 12 | "test": "cross-os _test ", 13 | "build": "tsc", 14 | "build:test": "tsc -p tsconfig.test.json", 15 | "watch": "tsc --watch", 16 | "watch:test": "tsc && tsc --watch -p tsconfig.test.json", 17 | "test:debug": "cross-os _test:debug", 18 | "lint": "tslint src/**/*.ts && tslint test/**/*.ts", 19 | "check-exports": "node ./scripts/reportMissingTopLevelExports.js", 20 | "check-imports": "node scripts/clearGlobalExports.js && tsc -p tsconfig.imports-check.json", 21 | "coverage": "tsc -p tsconfig.test.json && copy test\\Assets\\* .test\\test\\Assets && nyc --exclude=.test/test/** --reporter=html --reporter=text mocha .test\\test" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/jfrogtest/jfrogtest-nodejs-client" 26 | }, 27 | "bugs": { 28 | "email": "support@jfrogtest.net", 29 | "url": "http://issues.jfrogtest.com" 30 | }, 31 | "contributors": [ 32 | "jfrogtest" 33 | ], 34 | "engines": { 35 | "node": ">=6.0.0" 36 | }, 37 | "keywords": [ 38 | "jfrogtest", 39 | "jfrogtest-client", 40 | "typescript", 41 | "node", 42 | "nodejs", 43 | "nosql" 44 | ], 45 | "author": "jfrogtest", 46 | "license": "MIT", 47 | "devDependencies": { 48 | "@types/mocha": "^9.0.0", 49 | "mocha": "^9.1.3", 50 | "nyc": "^15.1.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /build/testdata/npm/project2/npmv7/windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jfrogtest", 3 | "version": "5.2.0", 4 | "description": "jfrogtest client for Node.js", 5 | "files": [ 6 | "dist/" 7 | ], 8 | "homepage": "https://jfrogtest.net", 9 | "main": "dist/index.js", 10 | "types": "dist/index.d.ts", 11 | "scripts": { 12 | "test": "cross-os _test ", 13 | "build": "tsc", 14 | "build:test": "tsc -p tsconfig.test.json", 15 | "watch": "tsc --watch", 16 | "watch:test": "tsc && tsc --watch -p tsconfig.test.json", 17 | "test:debug": "cross-os _test:debug", 18 | "lint": "tslint src/**/*.ts && tslint test/**/*.ts", 19 | "check-exports": "node ./scripts/reportMissingTopLevelExports.js", 20 | "check-imports": "node scripts/clearGlobalExports.js && tsc -p tsconfig.imports-check.json", 21 | "coverage": "tsc -p tsconfig.test.json && copy test\\Assets\\* .test\\test\\Assets && nyc --exclude=.test/test/** --reporter=html --reporter=text mocha .test\\test" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/jfrogtest/jfrogtest-nodejs-client" 26 | }, 27 | "bugs": { 28 | "email": "support@jfrogtest.net", 29 | "url": "http://issues.jfrogtest.com" 30 | }, 31 | "contributors": [ 32 | "jfrogtest" 33 | ], 34 | "engines": { 35 | "node": ">=6.0.0" 36 | }, 37 | "keywords": [ 38 | "jfrogtest", 39 | "jfrogtest-client", 40 | "typescript", 41 | "node", 42 | "nodejs", 43 | "nosql" 44 | ], 45 | "author": "jfrogtest", 46 | "license": "MIT", 47 | "devDependencies": { 48 | "@types/mocha": "^9.0.0", 49 | "mocha": "^9.1.3", 50 | "nyc": "^15.1.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /build/testdata/npm/project2/npmv8/linux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jfrogtest", 3 | "version": "5.2.0", 4 | "description": "jfrogtest client for Node.js", 5 | "files": [ 6 | "dist/" 7 | ], 8 | "homepage": "https://jfrogtest.net", 9 | "main": "dist/index.js", 10 | "types": "dist/index.d.ts", 11 | "scripts": { 12 | "test": "cross-os _test ", 13 | "build": "tsc", 14 | "build:test": "tsc -p tsconfig.test.json", 15 | "watch": "tsc --watch", 16 | "watch:test": "tsc && tsc --watch -p tsconfig.test.json", 17 | "test:debug": "cross-os _test:debug", 18 | "lint": "tslint src/**/*.ts && tslint test/**/*.ts", 19 | "check-exports": "node ./scripts/reportMissingTopLevelExports.js", 20 | "check-imports": "node scripts/clearGlobalExports.js && tsc -p tsconfig.imports-check.json", 21 | "coverage": "tsc -p tsconfig.test.json && copy test\\Assets\\* .test\\test\\Assets && nyc --exclude=.test/test/** --reporter=html --reporter=text mocha .test\\test" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/jfrogtest/jfrogtest-nodejs-client" 26 | }, 27 | "bugs": { 28 | "email": "support@jfrogtest.net", 29 | "url": "http://issues.jfrogtest.com" 30 | }, 31 | "contributors": [ 32 | "jfrogtest" 33 | ], 34 | "engines": { 35 | "node": ">=6.0.0" 36 | }, 37 | "keywords": [ 38 | "jfrogtest", 39 | "jfrogtest-client", 40 | "typescript", 41 | "node", 42 | "nodejs", 43 | "nosql" 44 | ], 45 | "author": "jfrogtest", 46 | "license": "MIT", 47 | "devDependencies": { 48 | "@types/mocha": "^9.0.0", 49 | "mocha": "^9.1.3", 50 | "nyc": "^15.1.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /build/testdata/npm/project2/npmv8/macos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jfrogtest", 3 | "version": "5.2.0", 4 | "description": "jfrogtest client for Node.js", 5 | "files": [ 6 | "dist/" 7 | ], 8 | "homepage": "https://jfrogtest.net", 9 | "main": "dist/index.js", 10 | "types": "dist/index.d.ts", 11 | "scripts": { 12 | "test": "cross-os _test ", 13 | "build": "tsc", 14 | "build:test": "tsc -p tsconfig.test.json", 15 | "watch": "tsc --watch", 16 | "watch:test": "tsc && tsc --watch -p tsconfig.test.json", 17 | "test:debug": "cross-os _test:debug", 18 | "lint": "tslint src/**/*.ts && tslint test/**/*.ts", 19 | "check-exports": "node ./scripts/reportMissingTopLevelExports.js", 20 | "check-imports": "node scripts/clearGlobalExports.js && tsc -p tsconfig.imports-check.json", 21 | "coverage": "tsc -p tsconfig.test.json && copy test\\Assets\\* .test\\test\\Assets && nyc --exclude=.test/test/** --reporter=html --reporter=text mocha .test\\test" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/jfrogtest/jfrogtest-nodejs-client" 26 | }, 27 | "bugs": { 28 | "email": "support@jfrogtest.net", 29 | "url": "http://issues.jfrogtest.com" 30 | }, 31 | "contributors": [ 32 | "jfrogtest" 33 | ], 34 | "engines": { 35 | "node": ">=6.0.0" 36 | }, 37 | "keywords": [ 38 | "jfrogtest", 39 | "jfrogtest-client", 40 | "typescript", 41 | "node", 42 | "nodejs", 43 | "nosql" 44 | ], 45 | "author": "jfrogtest", 46 | "license": "MIT", 47 | "devDependencies": { 48 | "@types/mocha": "^9.0.0", 49 | "mocha": "^9.1.3", 50 | "nyc": "^15.1.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /build/testdata/npm/project2/npmv8/windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jfrogtest", 3 | "version": "5.2.0", 4 | "description": "jfrogtest client for Node.js", 5 | "files": [ 6 | "dist/" 7 | ], 8 | "homepage": "https://jfrogtest.net", 9 | "main": "dist/index.js", 10 | "types": "dist/index.d.ts", 11 | "scripts": { 12 | "test": "cross-os _test ", 13 | "build": "tsc", 14 | "build:test": "tsc -p tsconfig.test.json", 15 | "watch": "tsc --watch", 16 | "watch:test": "tsc && tsc --watch -p tsconfig.test.json", 17 | "test:debug": "cross-os _test:debug", 18 | "lint": "tslint src/**/*.ts && tslint test/**/*.ts", 19 | "check-exports": "node ./scripts/reportMissingTopLevelExports.js", 20 | "check-imports": "node scripts/clearGlobalExports.js && tsc -p tsconfig.imports-check.json", 21 | "coverage": "tsc -p tsconfig.test.json && copy test\\Assets\\* .test\\test\\Assets && nyc --exclude=.test/test/** --reporter=html --reporter=text mocha .test\\test" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/jfrogtest/jfrogtest-nodejs-client" 26 | }, 27 | "bugs": { 28 | "email": "support@jfrogtest.net", 29 | "url": "http://issues.jfrogtest.com" 30 | }, 31 | "contributors": [ 32 | "jfrogtest" 33 | ], 34 | "engines": { 35 | "node": ">=6.0.0" 36 | }, 37 | "keywords": [ 38 | "jfrogtest", 39 | "jfrogtest-client", 40 | "typescript", 41 | "node", 42 | "nodejs", 43 | "nosql" 44 | ], 45 | "author": "jfrogtest", 46 | "license": "MIT", 47 | "devDependencies": { 48 | "@types/mocha": "^9.0.0", 49 | "mocha": "^9.1.3", 50 | "nyc": "^15.1.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /build/testdata/npm/project3/npmv6/expected_npm_buildinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-test-npm", 3 | "agent": {}, 4 | "buildAgent": { 5 | "name": "GENERIC" 6 | }, 7 | "modules": [ 8 | { 9 | "type": "npm", 10 | "id": "build-info-go-tests:1.0.0", 11 | "dependencies": [ 12 | { 13 | "id": "json:9.0.6", 14 | "scopes": [ 15 | "dev" 16 | ], 17 | "requestedBy": [ 18 | [ 19 | "build-info-go-tests:1.0.0" 20 | ] 21 | ], 22 | "sha1": "7972c2a5a48a42678db2730c7c2c4ee6e4e24585", 23 | "md5": "6569c5e23ea8e451a2ab10a66b5814ee", 24 | "sha256": "6e8bfb5cbb7e7ee53231d3e3439b2ab1de58caed81b8abb30b9e1168e8ac01e2" 25 | }, 26 | { 27 | "id": "xml:1.0.1", 28 | "scopes": [ 29 | "prod" 30 | ], 31 | "requestedBy": [ 32 | [ 33 | "build-info-go-tests:1.0.0" 34 | ] 35 | ], 36 | "sha1": "78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5", 37 | "md5": "cd0657e89d77ec585fe29c9b568d16c9", 38 | "sha256": "38032bd701fa20427b2ee31ed55e6761ce1a881a6eabcd90005ebe74ab04a623" 39 | } 40 | ] 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /build/testdata/npm/project3/npmv6/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "json": { 8 | "version": "9.0.6", 9 | "resolved": "https://registry.npmjs.org/json/-/json-9.0.6.tgz", 10 | "integrity": "sha1-eXLCpaSKQmeNsnMMfCxO5uTiRYU=", 11 | "dev": true 12 | }, 13 | "xml": { 14 | "version": "1.0.1", 15 | "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", 16 | "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /build/testdata/npm/project3/npmv6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "description": "test package", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "xml": "1.0.1" 13 | }, 14 | "devDependencies": { 15 | "json": "9.0.6" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /build/testdata/npm/project3/npmv7/expected_npm_buildinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-test-npm", 3 | "number": "2", 4 | "agent": {}, 5 | "buildAgent": { 6 | "name": "GENERIC" 7 | }, 8 | "modules": [ 9 | { 10 | "type": "npm", 11 | "id": "build-info-go-tests:v1.0.0", 12 | "dependencies": [ 13 | { 14 | "id": "xml:1.0.1", 15 | "scopes": [ 16 | "prod" 17 | ], 18 | "requestedBy": [ 19 | [ 20 | "build-info-go-tests:v1.0.0" 21 | ] 22 | ], 23 | "sha1": "78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5", 24 | "md5": "cd0657e89d77ec585fe29c9b568d16c9", 25 | "sha256": "38032bd701fa20427b2ee31ed55e6761ce1a881a6eabcd90005ebe74ab04a623" 26 | }, 27 | { 28 | "id": "json:9.0.6", 29 | "scopes": [ 30 | "dev" 31 | ], 32 | "requestedBy": [ 33 | [ 34 | "build-info-go-tests:v1.0.0" 35 | ] 36 | ], 37 | "sha1": "7972c2a5a48a42678db2730c7c2c4ee6e4e24585", 38 | "md5": "6569c5e23ea8e451a2ab10a66b5814ee", 39 | "sha256": "6e8bfb5cbb7e7ee53231d3e3439b2ab1de58caed81b8abb30b9e1168e8ac01e2" 40 | } 41 | ] 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /build/testdata/npm/project3/npmv7/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "build-info-go-tests", 9 | "version": "v1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "xml": "1.0.1" 13 | }, 14 | "devDependencies": { 15 | "json": "9.0.6" 16 | } 17 | }, 18 | "node_modules/json": { 19 | "version": "9.0.6", 20 | "resolved": "https://registry.npmjs.org/json/-/json-9.0.6.tgz", 21 | "integrity": "sha1-eXLCpaSKQmeNsnMMfCxO5uTiRYU=", 22 | "dev": true, 23 | "bin": { 24 | "json": "lib/json.js" 25 | }, 26 | "engines": { 27 | "node": ">=0.10.0" 28 | } 29 | }, 30 | "node_modules/xml": { 31 | "version": "1.0.1", 32 | "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", 33 | "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=" 34 | } 35 | }, 36 | "dependencies": { 37 | "json": { 38 | "version": "9.0.6", 39 | "resolved": "https://registry.npmjs.org/json/-/json-9.0.6.tgz", 40 | "integrity": "sha1-eXLCpaSKQmeNsnMMfCxO5uTiRYU=", 41 | "dev": true 42 | }, 43 | "xml": { 44 | "version": "1.0.1", 45 | "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", 46 | "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=" 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /build/testdata/npm/project3/npmv7/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "description": "test package", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "xml": "1.0.1" 13 | }, 14 | "devDependencies": { 15 | "json": "9.0.6" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /build/testdata/npm/project3/npmv8/expected_npm_buildinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-test-npm", 3 | "number": "2", 4 | "agent": {}, 5 | "buildAgent": { 6 | "name": "GENERIC" 7 | }, 8 | "modules": [ 9 | { 10 | "type": "npm", 11 | "id": "build-info-go-tests:v1.0.0", 12 | "dependencies": [ 13 | { 14 | "id": "xml:1.0.1", 15 | "scopes": [ 16 | "prod" 17 | ], 18 | "requestedBy": [ 19 | [ 20 | "build-info-go-tests:v1.0.0" 21 | ] 22 | ], 23 | "sha1": "78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5", 24 | "md5": "cd0657e89d77ec585fe29c9b568d16c9", 25 | "sha256": "38032bd701fa20427b2ee31ed55e6761ce1a881a6eabcd90005ebe74ab04a623" 26 | }, 27 | { 28 | "id": "json:9.0.6", 29 | "scopes": [ 30 | "dev" 31 | ], 32 | "requestedBy": [ 33 | [ 34 | "build-info-go-tests:v1.0.0" 35 | ] 36 | ], 37 | "sha1": "7972c2a5a48a42678db2730c7c2c4ee6e4e24585", 38 | "md5": "6569c5e23ea8e451a2ab10a66b5814ee", 39 | "sha256": "6e8bfb5cbb7e7ee53231d3e3439b2ab1de58caed81b8abb30b9e1168e8ac01e2" 40 | } 41 | ] 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /build/testdata/npm/project3/npmv8/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "build-info-go-tests", 9 | "version": "v1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "xml": "1.0.1" 13 | }, 14 | "devDependencies": { 15 | "json": "9.0.6" 16 | } 17 | }, 18 | "node_modules/json": { 19 | "version": "9.0.6", 20 | "resolved": "https://registry.npmjs.org/json/-/json-9.0.6.tgz", 21 | "integrity": "sha512-Nx+4WwMM1xadgqjjteOVEyjoIVq7fGH1hAlRDoxoq2tFzYsBYZDIKwYbyxolkTYwxsSOgAZD2ACLkeGjhFW2Jw==", 22 | "dev": true, 23 | "bin": { 24 | "json": "lib/json.js" 25 | }, 26 | "engines": { 27 | "node": ">=0.10.0" 28 | } 29 | }, 30 | "node_modules/xml": { 31 | "version": "1.0.1", 32 | "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", 33 | "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" 34 | } 35 | }, 36 | "dependencies": { 37 | "json": { 38 | "version": "9.0.6", 39 | "resolved": "https://registry.npmjs.org/json/-/json-9.0.6.tgz", 40 | "integrity": "sha512-Nx+4WwMM1xadgqjjteOVEyjoIVq7fGH1hAlRDoxoq2tFzYsBYZDIKwYbyxolkTYwxsSOgAZD2ACLkeGjhFW2Jw==", 41 | "dev": true 42 | }, 43 | "xml": { 44 | "version": "1.0.1", 45 | "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", 46 | "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /build/testdata/npm/project3/npmv8/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "description": "test package", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "xml": "1.0.1" 13 | }, 14 | "devDependencies": { 15 | "json": "9.0.6" 16 | } 17 | } -------------------------------------------------------------------------------- /build/testdata/npm/project4/npmv6/linux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bundle-dependencies", 3 | "description": "Generates bundledDependencies package.json.", 4 | "version": "1.0.2", 5 | "main": "./dist/index.js", 6 | "bin": "./dist/bin/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/gajus/bundle-dependencies" 10 | }, 11 | "keywords": [ 12 | "npm", 13 | "bundle", 14 | "dependencies" 15 | ], 16 | "author": { 17 | "name": "JFROG", 18 | "email": "JFROG@JFROG.com", 19 | "url": "http://JFROG.com" 20 | }, 21 | "license": "MIT", 22 | "dependencies": { 23 | "yargs": "^4.1.0" 24 | }, 25 | "devDependencies": { 26 | "pragmatist": "^3.0.9" 27 | }, 28 | "bundledDependencies": [ 29 | "yargs" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /build/testdata/npm/project4/npmv6/macos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bundle-dependencies", 3 | "description": "Generates bundledDependencies package.json.", 4 | "version": "1.0.2", 5 | "main": "./dist/index.js", 6 | "bin": "./dist/bin/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/gajus/bundle-dependencies" 10 | }, 11 | "keywords": [ 12 | "npm", 13 | "bundle", 14 | "dependencies" 15 | ], 16 | "author": { 17 | "name": "JFROG", 18 | "email": "JFROG@JFROG.com", 19 | "url": "http://JFROG.com" 20 | }, 21 | "license": "MIT", 22 | "dependencies": { 23 | "yargs": "^4.1.0" 24 | }, 25 | "devDependencies": { 26 | "pragmatist": "^3.0.9" 27 | }, 28 | "bundledDependencies": [ 29 | "yargs" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /build/testdata/npm/project4/npmv6/windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bundle-dependencies", 3 | "description": "Generates bundledDependencies package.json.", 4 | "version": "1.0.2", 5 | "main": "./dist/index.js", 6 | "bin": "./dist/bin/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/gajus/bundle-dependencies" 10 | }, 11 | "keywords": [ 12 | "npm", 13 | "bundle", 14 | "dependencies" 15 | ], 16 | "author": { 17 | "name": "JFROG", 18 | "email": "JFROG@JFROG.com", 19 | "url": "http://JFROG.com" 20 | }, 21 | "license": "MIT", 22 | "dependencies": { 23 | "yargs": "^4.1.0" 24 | }, 25 | "devDependencies": { 26 | "pragmatist": "^3.0.9" 27 | }, 28 | "bundledDependencies": [ 29 | "yargs" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /build/testdata/npm/project4/npmv7/linux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bundle-dependencies", 3 | "description": "Generates bundledDependencies package.json.", 4 | "version": "1.0.2", 5 | "main": "./dist/index.js", 6 | "bin": "./dist/bin/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/gajus/bundle-dependencies" 10 | }, 11 | "keywords": [ 12 | "npm", 13 | "bundle", 14 | "dependencies" 15 | ], 16 | "author": { 17 | "name": "JFROG", 18 | "email": "JFROG@JFROG.com", 19 | "url": "http://JFROG.com" 20 | }, 21 | "license": "MIT", 22 | "dependencies": { 23 | "yargs": "^4.1.0" 24 | }, 25 | "devDependencies": { 26 | "pragmatist": "^3.0.9" 27 | }, 28 | "bundledDependencies": [ 29 | "yargs" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /build/testdata/npm/project4/npmv7/macos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bundle-dependencies", 3 | "description": "Generates bundledDependencies package.json.", 4 | "version": "1.0.2", 5 | "main": "./dist/index.js", 6 | "bin": "./dist/bin/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/gajus/bundle-dependencies" 10 | }, 11 | "keywords": [ 12 | "npm", 13 | "bundle", 14 | "dependencies" 15 | ], 16 | "author": { 17 | "name": "JFROG", 18 | "email": "JFROG@JFROG.com", 19 | "url": "http://JFROG.com" 20 | }, 21 | "license": "MIT", 22 | "dependencies": { 23 | "yargs": "^4.1.0" 24 | }, 25 | "devDependencies": { 26 | "pragmatist": "^3.0.9" 27 | }, 28 | "bundledDependencies": [ 29 | "yargs" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /build/testdata/npm/project4/npmv7/windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bundle-dependencies", 3 | "description": "Generates bundledDependencies package.json.", 4 | "version": "1.0.2", 5 | "main": "./dist/index.js", 6 | "bin": "./dist/bin/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/gajus/bundle-dependencies" 10 | }, 11 | "keywords": [ 12 | "npm", 13 | "bundle", 14 | "dependencies" 15 | ], 16 | "author": { 17 | "name": "JFROG", 18 | "email": "JFROG@JFROG.com", 19 | "url": "http://JFROG.com" 20 | }, 21 | "license": "MIT", 22 | "dependencies": { 23 | "yargs": "^4.1.0" 24 | }, 25 | "devDependencies": { 26 | "pragmatist": "^3.0.9" 27 | }, 28 | "bundledDependencies": [ 29 | "yargs" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /build/testdata/npm/project4/npmv8/linux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bundle-dependencies", 3 | "description": "Generates bundledDependencies package.json.", 4 | "version": "1.0.2", 5 | "main": "./dist/index.js", 6 | "bin": "./dist/bin/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/gajus/bundle-dependencies" 10 | }, 11 | "keywords": [ 12 | "npm", 13 | "bundle", 14 | "dependencies" 15 | ], 16 | "author": { 17 | "name": "JFROG", 18 | "email": "JFROG@JFROG.com", 19 | "url": "http://JFROG.com" 20 | }, 21 | "license": "MIT", 22 | "dependencies": { 23 | "yargs": "^4.1.0" 24 | }, 25 | "devDependencies": { 26 | "pragmatist": "^3.0.9" 27 | }, 28 | "bundledDependencies": [ 29 | "yargs" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /build/testdata/npm/project4/npmv8/macos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bundle-dependencies", 3 | "description": "Generates bundledDependencies package.json.", 4 | "version": "1.0.2", 5 | "main": "./dist/index.js", 6 | "bin": "./dist/bin/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/gajus/bundle-dependencies" 10 | }, 11 | "keywords": [ 12 | "npm", 13 | "bundle", 14 | "dependencies" 15 | ], 16 | "author": { 17 | "name": "JFROG", 18 | "email": "JFROG@JFROG.com", 19 | "url": "http://JFROG.com" 20 | }, 21 | "license": "MIT", 22 | "dependencies": { 23 | "yargs": "^4.1.0" 24 | }, 25 | "devDependencies": { 26 | "pragmatist": "^3.0.9" 27 | }, 28 | "bundledDependencies": [ 29 | "yargs" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /build/testdata/npm/project4/npmv8/windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bundle-dependencies", 3 | "description": "Generates bundledDependencies package.json.", 4 | "version": "1.0.2", 5 | "main": "./dist/index.js", 6 | "bin": "./dist/bin/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/gajus/bundle-dependencies" 10 | }, 11 | "keywords": [ 12 | "npm", 13 | "bundle", 14 | "dependencies" 15 | ], 16 | "author": { 17 | "name": "JFROG", 18 | "email": "JFROG@JFROG.com", 19 | "url": "http://JFROG.com" 20 | }, 21 | "license": "MIT", 22 | "dependencies": { 23 | "yargs": "^4.1.0" 24 | }, 25 | "devDependencies": { 26 | "pragmatist": "^3.0.9" 27 | }, 28 | "bundledDependencies": [ 29 | "yargs" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /build/testdata/npm/project5/npmv6/linux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jf-peer-bug", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "~10.2.4", 15 | "@angular/common": "~10.2.4", 16 | "@angular/compiler": "~10.2.4", 17 | "@angular/core": "~10.2.4", 18 | "@angular/forms": "~10.2.4", 19 | "@angular/platform-browser": "~10.2.4", 20 | "@angular/platform-browser-dynamic": "~10.2.4", 21 | "@angular/router": "~10.2.4", 22 | "@ngui/auto-complete": "^3.0.0", 23 | "rxjs": "~6.6.0", 24 | "tslib": "^2.0.0", 25 | "zone.js": "~0.10.2" 26 | }, 27 | "devDependencies": { 28 | "@angular-devkit/build-angular": "~0.1002.1", 29 | "@angular/cli": "~10.2.1", 30 | "@angular/compiler-cli": "~10.2.4", 31 | "@types/node": "^12.11.1", 32 | "@types/jasmine": "~3.5.0", 33 | "@types/jasminewd2": "~2.0.3", 34 | "codelyzer": "^6.0.0", 35 | "jasmine-core": "~3.6.0", 36 | "jasmine-spec-reporter": "~5.0.0", 37 | "karma": "~5.0.0", 38 | "karma-chrome-launcher": "~3.1.0", 39 | "karma-coverage-istanbul-reporter": "~3.0.2", 40 | "karma-jasmine": "~4.0.0", 41 | "karma-jasmine-html-reporter": "^1.5.0", 42 | "protractor": "~7.0.0", 43 | "ts-node": "~8.3.0", 44 | "tslint": "~6.1.0", 45 | "typescript": "~4.0.2" 46 | }, 47 | "volta": { 48 | "node": "14.19.1" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /build/testdata/npm/project5/npmv6/macos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jf-peer-bug", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "~10.2.4", 15 | "@angular/common": "~10.2.4", 16 | "@angular/compiler": "~10.2.4", 17 | "@angular/core": "~10.2.4", 18 | "@angular/forms": "~10.2.4", 19 | "@angular/platform-browser": "~10.2.4", 20 | "@angular/platform-browser-dynamic": "~10.2.4", 21 | "@angular/router": "~10.2.4", 22 | "@ngui/auto-complete": "^3.0.0", 23 | "rxjs": "~6.6.0", 24 | "tslib": "^2.0.0", 25 | "zone.js": "~0.10.2" 26 | }, 27 | "devDependencies": { 28 | "@angular-devkit/build-angular": "~0.1002.1", 29 | "@angular/cli": "~10.2.1", 30 | "@angular/compiler-cli": "~10.2.4", 31 | "@types/node": "^12.11.1", 32 | "@types/jasmine": "~3.5.0", 33 | "@types/jasminewd2": "~2.0.3", 34 | "codelyzer": "^6.0.0", 35 | "jasmine-core": "~3.6.0", 36 | "jasmine-spec-reporter": "~5.0.0", 37 | "karma": "~5.0.0", 38 | "karma-chrome-launcher": "~3.1.0", 39 | "karma-coverage-istanbul-reporter": "~3.0.2", 40 | "karma-jasmine": "~4.0.0", 41 | "karma-jasmine-html-reporter": "^1.5.0", 42 | "protractor": "~7.0.0", 43 | "ts-node": "~8.3.0", 44 | "tslint": "~6.1.0", 45 | "typescript": "~4.0.2" 46 | }, 47 | "volta": { 48 | "node": "14.19.1" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /build/testdata/npm/project5/npmv6/windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jf-peer-bug", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "~10.2.4", 15 | "@angular/common": "~10.2.4", 16 | "@angular/compiler": "~10.2.4", 17 | "@angular/core": "~10.2.4", 18 | "@angular/forms": "~10.2.4", 19 | "@angular/platform-browser": "~10.2.4", 20 | "@angular/platform-browser-dynamic": "~10.2.4", 21 | "@angular/router": "~10.2.4", 22 | "@ngui/auto-complete": "^3.0.0", 23 | "rxjs": "~6.6.0", 24 | "tslib": "^2.0.0", 25 | "zone.js": "~0.10.2" 26 | }, 27 | "devDependencies": { 28 | "@angular-devkit/build-angular": "~0.1002.1", 29 | "@angular/cli": "~10.2.1", 30 | "@angular/compiler-cli": "~10.2.4", 31 | "@types/node": "^12.11.1", 32 | "@types/jasmine": "~3.5.0", 33 | "@types/jasminewd2": "~2.0.3", 34 | "codelyzer": "^6.0.0", 35 | "jasmine-core": "~3.6.0", 36 | "jasmine-spec-reporter": "~5.0.0", 37 | "karma": "~5.0.0", 38 | "karma-chrome-launcher": "~3.1.0", 39 | "karma-coverage-istanbul-reporter": "~3.0.2", 40 | "karma-jasmine": "~4.0.0", 41 | "karma-jasmine-html-reporter": "^1.5.0", 42 | "protractor": "~7.0.0", 43 | "ts-node": "~8.3.0", 44 | "tslint": "~6.1.0", 45 | "typescript": "~4.0.2" 46 | }, 47 | "volta": { 48 | "node": "14.19.1" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /build/testdata/npm/project6/node_modules/dummy-file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/testdata/npm/project6/node_modules/dummy-file -------------------------------------------------------------------------------- /build/testdata/npm/project6/package-lock_test.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "project6", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "project6", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "lightweight": "^0.1.0", 13 | "minimist": "^0.1.0", 14 | "underscore": "^1.13.6" 15 | } 16 | }, 17 | "node_modules/lightweight": { 18 | "version": "0.1.0", 19 | "resolved": "https://registry.npmjs.org/lightweight/-/lightweight-0.1.0.tgz", 20 | "integrity": "sha512-10pYSQA9EJqZZnXDR0urhg8Z0Y1XnRfi41ZFj3ZFTKJ5PjRq82HzT7LKlPyxewy3w2WA2POfi3jQQn7Y53oPcQ==", 21 | "bin": { 22 | "lwt": "bin/lwt.js" 23 | } 24 | }, 25 | "node_modules/minimist": { 26 | "version": "0.1.0", 27 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", 28 | "integrity": "sha512-wR5Ipl99t0mTGwLjQJnBjrP/O7zBbLZqvA3aw32DmLx+nXHfWctUjzDjnDx09pX1Po86WFQazF9xUzfMea3Cnw==" 29 | }, 30 | "node_modules/underscore": { 31 | "version": "1.13.6", 32 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", 33 | "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /build/testdata/npm/project6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm_test2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "lightweight": "^0.1.0", 13 | "minimist": "^0.1.0", 14 | "underscore": "^1.13.6", 15 | "cors.js": "0.0.1-security" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /build/testdata/python/pip/expected_pip_buildinfo_with_module_name.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-test-pip", 3 | "number": "1645699899", 4 | "agent": {}, 5 | "buildAgent": { 6 | "name": "GENERIC" 7 | }, 8 | "modules": [ 9 | { 10 | "type": "python", 11 | "id": "testModuleName:1.0.0", 12 | "dependencies": [ 13 | { 14 | "id": "pyyaml:5.1.2", 15 | "type": "tar.gz", 16 | "requestedBy": [ 17 | [ 18 | "testModuleName:1.0.0" 19 | ] 20 | ] 21 | }, 22 | { 23 | "id": "nltk:3.4.5", 24 | "type": "zip", 25 | "requestedBy": [ 26 | [ 27 | "testModuleName:1.0.0" 28 | ] 29 | ] 30 | }, 31 | { 32 | "id": "six:1.17.0", 33 | "type": "metadata", 34 | "requestedBy": [ 35 | [ 36 | "nltk:3.4.5", 37 | "testModuleName:1.0.0" 38 | ] 39 | ] 40 | } 41 | ] 42 | } 43 | ], 44 | "started": "2022-02-24T12:51:39.657+0200" 45 | } -------------------------------------------------------------------------------- /build/testdata/python/pip/expected_pip_buildinfo_without_module_name.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-test-pip", 3 | "number": "1645699899", 4 | "agent": {}, 5 | "buildAgent": { 6 | "name": "GENERIC" 7 | }, 8 | "modules": [ 9 | { 10 | "type": "python", 11 | "id": "jfrog-python-example:1.0", 12 | "dependencies": [ 13 | { 14 | "id": "pyyaml:5.1.2", 15 | "type": "tar.gz", 16 | "requestedBy": [ 17 | [ 18 | "jfrog-python-example:1.0" 19 | ] 20 | ] 21 | }, 22 | { 23 | "id": "nltk:3.4.5", 24 | "type": "zip", 25 | "requestedBy": [ 26 | [ 27 | "jfrog-python-example:1.0" 28 | ] 29 | ] 30 | }, 31 | { 32 | "id": "six:1.17.0", 33 | "type": "metadata", 34 | "requestedBy": [ 35 | [ 36 | "nltk:3.4.5", 37 | "jfrog-python-example:1.0" 38 | ] 39 | ] 40 | } 41 | ] 42 | } 43 | ], 44 | "started": "2022-02-24T12:51:39.657+0200" 45 | } -------------------------------------------------------------------------------- /build/testdata/python/pip/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup 4 | 5 | setup( 6 | name='jfrog-python-example', 7 | version='1.0', 8 | description='Project example for building Python project with JFrog products', 9 | author='JFrog', 10 | author_email='jfrog@jfrog.com', 11 | url='https://github.com/jfrog/project-examples', 12 | packages=[], 13 | install_requires=['PyYAML==5.1.2', 'nltk==3.4.5'], 14 | ) -------------------------------------------------------------------------------- /build/testdata/python/pipenv/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.python.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | toml = "*" 8 | pexpect = "4.8.0" 9 | 10 | [dev-packages] 11 | 12 | [requires] 13 | python_version = "*" 14 | -------------------------------------------------------------------------------- /build/testdata/python/pipenv/expected_pipenv_buildinfo_with_module_name.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-test-pipenv", 3 | "number": "1645714664", 4 | "agent": {}, 5 | "buildAgent": { 6 | "name": "GENERIC" 7 | }, 8 | "modules": [ 9 | { 10 | "type": "python", 11 | "id": "testModuleName:1.0.0", 12 | "dependencies": [ 13 | { 14 | "id": "pexpect:4.8.0", 15 | "type": "whl", 16 | "requestedBy": [ 17 | [ 18 | "testModuleName:1.0.0" 19 | ] 20 | ] 21 | }, 22 | { 23 | "id": "ptyprocess:0.7.0", 24 | "type": "whl", 25 | "requestedBy": [ 26 | [ 27 | "pexpect:4.8.0", 28 | "testModuleName:1.0.0" 29 | ] 30 | ] 31 | }, 32 | { 33 | "id": "toml:0.10.2", 34 | "type": "whl", 35 | "requestedBy": [ 36 | [ 37 | "testModuleName:1.0.0" 38 | ] 39 | ] 40 | } 41 | ] 42 | } 43 | ], 44 | "started": "2022-02-24T16:57:44.021+0200" 45 | } -------------------------------------------------------------------------------- /build/testdata/python/pipenv/expected_pipenv_buildinfo_without_module_name.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-test-pipenv", 3 | "number": "1645714324", 4 | "agent": {}, 5 | "buildAgent": { 6 | "name": "GENERIC" 7 | }, 8 | "modules": [ 9 | { 10 | "type": "python", 11 | "id": "build-info-go-test-pipenv", 12 | "dependencies": [ 13 | { 14 | "id": "pexpect:4.8.0", 15 | "type": "whl", 16 | "requestedBy": [ 17 | [ 18 | "build-info-go-test-pipenv" 19 | ] 20 | ] 21 | }, 22 | { 23 | "id": "ptyprocess:0.7.0", 24 | "type": "whl", 25 | "requestedBy": [ 26 | [ 27 | "pexpect:4.8.0", 28 | "build-info-go-test-pipenv" 29 | ] 30 | ] 31 | }, 32 | { 33 | "id": "toml:0.10.2", 34 | "type": "whl", 35 | "requestedBy": [ 36 | [ 37 | "build-info-go-test-pipenv" 38 | ] 39 | ] 40 | } 41 | ] 42 | } 43 | ], 44 | "started": "2022-02-24T16:52:04.362+0200" 45 | } -------------------------------------------------------------------------------- /build/testdata/yarn/v1/project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "packageManager": "yarn@1.22.19", 4 | "version": "v1.0.0", 5 | "description": "test package for yarn v1", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "react": "18.2.0", 14 | "xml": "1.0.1" 15 | }, 16 | "devDependencies": { 17 | "json": "9.0.6" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /build/testdata/yarn/v1/project/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "js-tokens@^3.0.0 || ^4.0.0": 6 | version "4.0.0" 7 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 8 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 9 | 10 | json@9.0.6: 11 | version "9.0.6" 12 | resolved "https://registry.yarnpkg.com/json/-/json-9.0.6.tgz#7972c2a5a48a42678db2730c7c2c4ee6e4e24585" 13 | integrity sha512-Nx+4WwMM1xadgqjjteOVEyjoIVq7fGH1hAlRDoxoq2tFzYsBYZDIKwYbyxolkTYwxsSOgAZD2ACLkeGjhFW2Jw== 14 | 15 | loose-envify@^1.1.0: 16 | version "1.4.0" 17 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" 18 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== 19 | dependencies: 20 | js-tokens "^3.0.0 || ^4.0.0" 21 | 22 | react@18.2.0: 23 | version "18.2.0" 24 | resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" 25 | integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== 26 | dependencies: 27 | loose-envify "^1.1.0" 28 | 29 | xml@1.0.1: 30 | version "1.0.1" 31 | resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" 32 | integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw== 33 | -------------------------------------------------------------------------------- /build/testdata/yarn/v2/project/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | yarnPath: .yarn/releases/yarn-3.1.1.cjs 2 | -------------------------------------------------------------------------------- /build/testdata/yarn/v2/project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-info-go-tests", 3 | "version": "v1.0.0", 4 | "description": "test package", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "react": "18.2.0", 13 | "xml": "1.0.1" 14 | }, 15 | "devDependencies": { 16 | "json": "9.0.6" 17 | }, 18 | "packageManager": "yarn@3.1.1" 19 | } 20 | -------------------------------------------------------------------------------- /build/testdata/yarn/v2/project/yarn.lock: -------------------------------------------------------------------------------- 1 | # This file is generated by running "yarn install" inside your project. 2 | # Manual changes might be lost - proceed with caution! 3 | 4 | __metadata: 5 | version: 5 6 | cacheKey: 8 7 | 8 | "build-info-go-tests@workspace:.": 9 | version: 0.0.0-use.local 10 | resolution: "build-info-go-tests@workspace:." 11 | dependencies: 12 | json: 9.0.6 13 | react: 18.2.0 14 | xml: 1.0.1 15 | languageName: unknown 16 | linkType: soft 17 | 18 | "js-tokens@npm:^3.0.0 || ^4.0.0": 19 | version: 4.0.0 20 | resolution: "js-tokens@npm:4.0.0" 21 | checksum: 8a95213a5a77deb6cbe94d86340e8d9ace2b93bc367790b260101d2f36a2eaf4e4e22d9fa9cf459b38af3a32fb4190e638024cf82ec95ef708680e405ea7cc78 22 | languageName: node 23 | linkType: hard 24 | 25 | "json@npm:9.0.6": 26 | version: 9.0.6 27 | resolution: "json@npm:9.0.6" 28 | bin: 29 | json: ./lib/json.js 30 | checksum: b9f16874e5bab435ad2e68f5a110549da8e28a4795a24c46e52c97a4f4fc5087f2ceb197eed4f8413fa24a7f7008af3da26caeec7739ca86ec25c2da146af9d5 31 | languageName: node 32 | linkType: hard 33 | 34 | "loose-envify@npm:^1.1.0": 35 | version: 1.4.0 36 | resolution: "loose-envify@npm:1.4.0" 37 | dependencies: 38 | js-tokens: ^3.0.0 || ^4.0.0 39 | bin: 40 | loose-envify: cli.js 41 | checksum: 6517e24e0cad87ec9888f500c5b5947032cdfe6ef65e1c1936a0c48a524b81e65542c9c3edc91c97d5bddc806ee2a985dbc79be89215d613b1de5db6d1cfe6f4 42 | languageName: node 43 | linkType: hard 44 | 45 | "react@npm:18.2.0": 46 | version: 18.2.0 47 | resolution: "react@npm:18.2.0" 48 | dependencies: 49 | loose-envify: ^1.1.0 50 | checksum: 88e38092da8839b830cda6feef2e8505dec8ace60579e46aa5490fc3dc9bba0bd50336507dc166f43e3afc1c42939c09fe33b25fae889d6f402721dcd78fca1b 51 | languageName: node 52 | linkType: hard 53 | 54 | "xml@npm:1.0.1": 55 | version: 1.0.1 56 | resolution: "xml@npm:1.0.1" 57 | checksum: 11b5545ef3f8fec3fa29ce251f50ad7b6c97c103ed4d851306ec23366f5fa4699dd6a942262df52313a0cd1840ab26256da253c023bad3309d8ce46fe6020ca0 58 | languageName: node 59 | linkType: hard 60 | -------------------------------------------------------------------------------- /build/utils/dotnet/configfiletemplate.go: -------------------------------------------------------------------------------- 1 | package dotnet 2 | 3 | const ConfigFileTemplate = ` 4 | 5 | 6 | 7 | 8 | 9 | ` 10 | 11 | const ConfigFileFormat = ` 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ` 23 | -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/dependencies.go: -------------------------------------------------------------------------------- 1 | package dependencies 2 | 3 | import ( 4 | "fmt" 5 | deptree "github.com/jfrog/build-info-go/build/utils/dotnet/dependenciestree" 6 | buildinfo "github.com/jfrog/build-info-go/entities" 7 | "github.com/jfrog/build-info-go/utils" 8 | ) 9 | 10 | const absentNupkgWarnMsg = " Skipping adding this dependency to the build info. This might be because the package already exists in a different NuGet cache," + 11 | " possibly the SDK's NuGetFallbackFolder cache. Removing the package from this cache may resolve the issue." 12 | 13 | var extractors []Extractor 14 | 15 | // Register dependency extractor 16 | func register(dependencyType Extractor) { 17 | extractors = append(extractors, dependencyType) 18 | } 19 | 20 | // The extractor responsible to calculate the project dependencies. 21 | type Extractor interface { 22 | // Check whether the extractor is compatible with the current dependency resolution method 23 | IsCompatible(projectName, dependenciesSource string, log utils.Log) bool 24 | // Get all the dependencies for the project 25 | AllDependencies(log utils.Log) (map[string]*buildinfo.Dependency, error) 26 | // Get all the root dependencies of the project 27 | DirectDependencies() ([]string, error) 28 | // Dependencies relations map 29 | ChildrenMap() (map[string][]string, error) 30 | 31 | new(dependenciesSource string, log utils.Log) (Extractor, error) 32 | } 33 | 34 | func CreateCompatibleExtractor(projectName, dependenciesSource string, log utils.Log) (Extractor, error) { 35 | extractor, err := getCompatibleExtractor(projectName, dependenciesSource, log) 36 | if err != nil { 37 | return nil, err 38 | } 39 | return extractor, nil 40 | } 41 | 42 | func CreateDependencyTree(extractor Extractor, log utils.Log) (deptree.Root, error) { 43 | rootDependencies, err := extractor.DirectDependencies() 44 | if err != nil { 45 | return nil, err 46 | } 47 | allDependencies, err := extractor.AllDependencies(log) 48 | if err != nil { 49 | return nil, err 50 | } 51 | childrenMap, err := extractor.ChildrenMap() 52 | if err != nil { 53 | return nil, err 54 | } 55 | return deptree.CreateDependencyTree(rootDependencies, allDependencies, childrenMap), nil 56 | } 57 | 58 | // Find suitable registered dependencies extractor. 59 | func getCompatibleExtractor(projectName, dependenciesSource string, log utils.Log) (Extractor, error) { 60 | for _, extractor := range extractors { 61 | if extractor.IsCompatible(projectName, dependenciesSource, log) { 62 | return extractor.new(dependenciesSource, log) 63 | } 64 | } 65 | log.Debug(fmt.Sprintf("Unsupported project dependencies for project: %s", projectName)) 66 | return nil, nil 67 | } 68 | -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/assetsproject/dep1.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/utils/dotnet/dependencies/testdata/assetsproject/dep1.nupkg -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/assetsproject/dep2.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/utils/dotnet/dependencies/testdata/assetsproject/dep2.nupkg -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/assetsproject/obj/project.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "targets": { 4 | "t1": { 5 | "dep1/1.0.1": {}, 6 | "dep2/1.0.2": { 7 | "dependencies": { 8 | "dep1": "1.0.1" 9 | } 10 | } 11 | } 12 | }, 13 | "libraries": { 14 | "dep1/1.0.1": { 15 | "path": "", 16 | "files": [ 17 | "file1", 18 | "dep1.nupkg.sha512" 19 | ] 20 | }, 21 | "dep2/1.0.2": { 22 | "path": "", 23 | "files": [ 24 | "file1", 25 | "dep2.nupkg.sha512" 26 | ] 27 | } 28 | }, 29 | "project": { 30 | "version": "1.0.0", 31 | "restore": { 32 | "packagesPath": "testdata/assetsproject" 33 | }, 34 | "frameworks": { 35 | "net461": { 36 | "dependencies": { 37 | "dep1": { 38 | "target": "Package", 39 | "version": "[1.0.1, )" 40 | } 41 | } 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/packagesproject/localcache/id1/1.0.0/id1.1.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/utils/dotnet/dependencies/testdata/packagesproject/localcache/id1/1.0.0/id1.1.0.0.nupkg -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/packagesproject/localcache/id1/1.0.0/id1.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | id1 5 | 6 | 7 | 8 | 9 | 10 | 11 | > -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/packagesproject/localcache/id2/2.0.0/id2.2.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/utils/dotnet/dependencies/testdata/packagesproject/localcache/id2/2.0.0/id2.2.0.0.nupkg -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/packagesproject/localcache/id2/2.0.0/id2.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | id2 5 | 6 | 7 | 8 | 9 | 10 | 11 | > -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/packagesproject/localcache/microsoft.web.infrastructure/1.0.0.0/microsoft.web.infrastructure.1.0.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/utils/dotnet/dependencies/testdata/packagesproject/localcache/microsoft.web.infrastructure/1.0.0.0/microsoft.web.infrastructure.1.0.0.0.nupkg -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/packagesproject/localcache/microsoft.web.infrastructure/1.0.0.0/microsoft.web.infrastructure.nuspec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/build/utils/dotnet/dependencies/testdata/packagesproject/localcache/microsoft.web.infrastructure/1.0.0.0/microsoft.web.infrastructure.nuspec -------------------------------------------------------------------------------- /build/utils/dotnet/dependencies/testdata/packagesproject/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /build/utils/dotnet/dependenciestree/dependencies.go: -------------------------------------------------------------------------------- 1 | package dependenciestree 2 | 3 | import ( 4 | "encoding/json" 5 | buildinfo "github.com/jfrog/build-info-go/entities" 6 | ) 7 | 8 | // Dependency tree 9 | type Tree interface { 10 | MarshalJSON() ([]byte, error) 11 | } 12 | 13 | type Root []*DependenciesTree 14 | 15 | type DependenciesTree struct { 16 | Dependency *buildinfo.Dependency `json:"dependencies,omitempty"` 17 | DirectDependencies []*DependenciesTree 18 | Id string 19 | } 20 | 21 | func (r Root) MarshalJSON() ([]byte, error) { 22 | type Alias Root 23 | return json.Marshal(Alias(r)) 24 | } 25 | 26 | func (t DependenciesTree) MarshalJSON() ([]byte, error) { 27 | type Alias []*DependenciesTree 28 | return json.Marshal(&struct { 29 | *buildinfo.Dependency 30 | Alias `json:"dependencies,omitempty"` 31 | }{ 32 | Dependency: t.Dependency, 33 | Alias: t.DirectDependencies, 34 | }) 35 | } 36 | 37 | // Add children nodes for a dependency 38 | func (t *DependenciesTree) AddChildren(allDependencies map[string]*buildinfo.Dependency, children map[string][]string) { 39 | for _, child := range children[t.Id] { 40 | if _, ok := allDependencies[child]; !ok { 41 | // No such child, skip... 42 | continue 43 | } 44 | childTree := &DependenciesTree{Id: child, Dependency: allDependencies[child]} 45 | childTree.AddChildren(allDependencies, children) 46 | t.DirectDependencies = append(t.DirectDependencies, childTree) 47 | } 48 | } 49 | 50 | // Create dependency tree using the data received from the extractors. 51 | func CreateDependencyTree(rootDependencies []string, allDependencies map[string]*buildinfo.Dependency, childrenMap map[string][]string) Root { 52 | var rootTree Root 53 | for _, root := range rootDependencies { 54 | if _, ok := allDependencies[root]; !ok { 55 | // No such root, skip... 56 | continue 57 | } 58 | subTree := &DependenciesTree{Id: root, Dependency: allDependencies[root]} 59 | subTree.AddChildren(allDependencies, childrenMap) 60 | rootTree = append(rootTree, subTree) 61 | } 62 | return rootTree 63 | } 64 | -------------------------------------------------------------------------------- /build/utils/dotnet/solution/project/project.go: -------------------------------------------------------------------------------- 1 | package project 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/jfrog/build-info-go/build/utils/dotnet/dependencies" 6 | "github.com/jfrog/build-info-go/build/utils/dotnet/dependenciestree" 7 | "github.com/jfrog/build-info-go/utils" 8 | ) 9 | 10 | type Project interface { 11 | Name() string 12 | RootPath() string 13 | MarshalJSON() ([]byte, error) 14 | Extractor() dependencies.Extractor 15 | CreateDependencyTree(log utils.Log) error 16 | Load(dependenciesSource string, log utils.Log) (Project, error) 17 | } 18 | 19 | func CreateProject(name, rootPath string) Project { 20 | return &project{name: name, rootPath: rootPath} 21 | } 22 | 23 | func (project *project) getCompatibleExtractor(log utils.Log) (dependencies.Extractor, error) { 24 | extractor, err := dependencies.CreateCompatibleExtractor(project.name, project.dependenciesSource, log) 25 | return extractor, err 26 | } 27 | 28 | func (project *project) CreateDependencyTree(log utils.Log) error { 29 | var err error 30 | project.dependencyTree, err = dependencies.CreateDependencyTree(project.extractor, log) 31 | return err 32 | } 33 | 34 | type project struct { 35 | name string 36 | rootPath string 37 | dependenciesSource string 38 | dependencyTree dependenciestree.Tree 39 | extractor dependencies.Extractor 40 | } 41 | 42 | func (project *project) Name() string { 43 | return project.name 44 | } 45 | 46 | func (project *project) RootPath() string { 47 | return project.rootPath 48 | } 49 | 50 | func (project *project) Extractor() dependencies.Extractor { 51 | return project.extractor 52 | } 53 | 54 | func (project *project) Load(dependenciesSource string, log utils.Log) (Project, error) { 55 | var err error 56 | project.dependenciesSource = dependenciesSource 57 | project.extractor, err = project.getCompatibleExtractor(log) 58 | return project, err 59 | } 60 | 61 | func (project *project) MarshalJSON() ([]byte, error) { 62 | return json.Marshal(&struct { 63 | Name string `json:"name,omitempty"` 64 | Dependencies dependenciestree.Tree `json:"dependencies,omitempty"` 65 | }{ 66 | Name: project.name, 67 | Dependencies: project.dependencyTree, 68 | }) 69 | } 70 | -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/multilinesproject.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27428.2005 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "packagesconfigmulti", "packagesconfig.csproj", "{D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "packagesconfiganothermulti", "test\packagesconfig.csproj", "{D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}" 8 | ProjectSection(ProjectDependencies) = postProject 9 | {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} = {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10 | EndProjectSection 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.ActiveCfg = Debug|x86 19 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.Build.0 = Debug|x86 20 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.ActiveCfg = Debug|x86 21 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.Build.0 = Debug|x86 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | GlobalSection(ExtensibilityGlobals) = postSolution 27 | SolutionGuid = {D6F2BF93-8FC0-422E-BED5-D352C69B81C0} 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/multiprojects.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27428.2005 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "packagesconfigmulti", "packagesconfig.csproj", "{D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "packagesconfiganothermulti", "test\packagesconfig.csproj", "{D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}" 8 | EndProject 9 | Global 10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 11 | Debug|Any CPU = Debug|Any CPU 12 | Release|Any CPU = Release|Any CPU 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.ActiveCfg = Debug|x86 16 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.Build.0 = Debug|x86 17 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.ActiveCfg = Debug|x86 18 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.Build.0 = Debug|x86 19 | EndGlobalSection 20 | GlobalSection(SolutionProperties) = preSolution 21 | HideSolutionNode = FALSE 22 | EndGlobalSection 23 | GlobalSection(ExtensibilityGlobals) = postSolution 24 | SolutionGuid = {D6F2BF93-8FC0-422E-BED5-D352C69B81C0} 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/nugetproj/proj1/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/nugetproj/proj1/proj1.cs: -------------------------------------------------------------------------------- 1 | class Program 2 | { 3 | static void Main() 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/nugetproj/proj1/proj1.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Debug 10 | 11 | AnyCPU 12 | 13 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF} 14 | 15 | bin\$(Configuration)\ 16 | 17 | v4.5 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 4.0.0 42 | 43 | 44 | 45 | 46 | 47 | 2.14.0 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/nugetproj/proj2/proj2.cs: -------------------------------------------------------------------------------- 1 | class Program 2 | { 3 | static void Main() 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/nugetproj/proj2/proj2.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Debug 10 | 11 | AnyCPU 12 | 13 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF} 14 | 15 | bin\$(Configuration)\ 16 | 17 | v4.5 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 11.0.2 42 | 43 | 44 | 45 | 46 | 47 | 2.14.0 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/nugetproj/solutions/nugetproj.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27428.2005 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proj1", "../proj1/proj1.csproj", "{D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proj2", "../proj2/proj2.csproj", "{D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}" 8 | EndProject 9 | Global 10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 11 | Debug|Any CPU = Debug|Any CPU 12 | Release|Any CPU = Release|Any CPU 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.ActiveCfg = Debug|x86 16 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.Build.0 = Debug|x86 17 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.ActiveCfg = Debug|x86 18 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.Build.0 = Debug|x86 19 | EndGlobalSection 20 | GlobalSection(SolutionProperties) = preSolution 21 | HideSolutionNode = FALSE 22 | EndGlobalSection 23 | GlobalSection(ExtensibilityGlobals) = postSolution 24 | SolutionGuid = {D6F2BF93-8FC0-422E-BED5-D352C69B81C0} 25 | EndGlobalSection 26 | EndGlobal -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/nugetproj/solutions/proj2/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/oneproject.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27428.2005 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "packagesconfig", "packagesconfig.csproj", "{D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.ActiveCfg = Debug|x86 14 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.Build.0 = Debug|x86 15 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.ActiveCfg = Debug|x86 16 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.Build.0 = Debug|x86 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {D6F2BF93-8FC0-422E-BED5-D352C69B81C0} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /build/utils/dotnet/solution/testdata/visualbasic.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27428.2005 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "packagesconfig", "packagesconfig.vbproj", "{D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.ActiveCfg = Debug|x86 14 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Debug|Any CPU.Build.0 = Debug|x86 15 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.ActiveCfg = Debug|x86 16 | {D1FFA0DC-0ACC-4108-ADC1-2A71122C09AF}.Release|Any CPU.Build.0 = Debug|x86 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {D6F2BF93-8FC0-422E-BED5-D352C69B81C0} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /build/utils/npmcacache_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "path/filepath" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestIntegrityToSha(t *testing.T) { 12 | hashAlgorithm, hash, err := integrityToSha("sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==") 13 | assert.NoError(t, err) 14 | assert.Equal(t, "7567b89d63bfaee10e63b1e4509e6016dd4308557dccf46826bf29574fc04907ab98e663b6af233233a9ac2d0a775d062cdfa5ef16943efc732455adc46bbc16", hash) 15 | assert.Equal(t, "sha512", hashAlgorithm) 16 | 17 | hashAlgorithm, hash, err = integrityToSha("sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=") 18 | assert.NoError(t, err) 19 | assert.Equal(t, "676f6eb3c39997c2ee1ac3a924fd6124748f578d", hash) 20 | assert.Equal(t, "sha1", hashAlgorithm) 21 | } 22 | 23 | func TestGetDepTarball(t *testing.T) { 24 | cacache := NewNpmCacache(filepath.Join("..", "testdata", "npm", "_cacache")) 25 | path, err := cacache.GetTarball("sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==") 26 | assert.NoError(t, err) 27 | assert.True(t, strings.HasSuffix(path, filepath.Join("testdata", "npm", "_cacache", "content-v2", "sha512", "75", "67", "b89d63bfaee10e63b1e4509e6016dd4308557dccf46826bf29574fc04907ab98e663b6af233233a9ac2d0a775d062cdfa5ef16943efc732455adc46bbc16"))) 28 | 29 | path, err = cacache.GetTarball("sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=") 30 | assert.NoError(t, err) 31 | assert.True(t, strings.HasSuffix(path, filepath.Join("testdata", "npm", "_cacache", "content-v2", "sha1", "67", "6f", "6eb3c39997c2ee1ac3a924fd6124748f578d"))) 32 | } 33 | 34 | func TestGetDepInfo(t *testing.T) { 35 | cacache := NewNpmCacache(filepath.Join("..", "testdata", "npm", "_cacache")) 36 | info, err := cacache.GetInfo("ansi-regex@5.0.0") 37 | assert.NoError(t, err) 38 | assert.Equal(t, "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", info.Integrity) 39 | } 40 | -------------------------------------------------------------------------------- /build/utils_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/jfrog/build-info-go/entities" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func validateModule(t *testing.T, module entities.Module, expectedDependencies, expectedArtifacts int, moduleName string, moduleType entities.ModuleType, depsContainChecksums bool) { 11 | assert.Equal(t, moduleName, module.Id, "Unexpected module name") 12 | assert.Len(t, module.Dependencies, expectedDependencies, "Incorrect number of dependencies found in the build-info") 13 | assert.Len(t, module.Artifacts, expectedArtifacts, "Incorrect number of artifacts found in the build-info") 14 | if expectedArtifacts > 0 { 15 | assert.Equal(t, "artifactName", module.Artifacts[0].Name, "Unexpected Name field.") 16 | assert.Equal(t, "artifactType", module.Artifacts[0].Type, "Unexpected Type field.") 17 | assert.Equal(t, "artifactPath", module.Artifacts[0].Path, "Unexpected Path field.") 18 | assert.Equal(t, "123", module.Artifacts[0].Checksum.Sha1, "Unexpected Sha1 field.") 19 | assert.Equal(t, "456", module.Artifacts[0].Checksum.Md5, "Unexpected MD5 field.") 20 | assert.Equal(t, "789", module.Artifacts[0].Checksum.Sha256, "Unexpected SHA256 field.") 21 | } 22 | assert.Equal(t, moduleType, module.Type) 23 | assert.Equal(t, depsContainChecksums, !module.Dependencies[0].Checksum.IsEmpty()) 24 | if depsContainChecksums { 25 | assert.NotEmpty(t, module.Dependencies[0].Checksum.Sha1, "Empty Sha1 field.") 26 | assert.NotEmpty(t, module.Dependencies[0].Checksum.Md5, "Empty MD5 field.") 27 | assert.NotEmpty(t, module.Dependencies[0].Checksum.Sha256, "Empty SHA256 field.") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /buildinfoschema_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | 8 | buildutils "github.com/jfrog/build-info-go/build/utils" 9 | "github.com/jfrog/build-info-go/tests" 10 | "github.com/jfrog/build-info-go/utils" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/xeipuuv/gojsonschema" 14 | ) 15 | 16 | func TestGoSchema(t *testing.T) { 17 | validateBuildInfoSchema(t, "go", filepath.Join("golang", "project"), func() {}) 18 | } 19 | 20 | func TestMavenSchema(t *testing.T) { 21 | validateBuildInfoSchema(t, "mvn", filepath.Join("maven", "project"), func() {}) 22 | } 23 | 24 | func TestNpmSchema(t *testing.T) { 25 | validateBuildInfoSchema(t, "npm", filepath.Join("npm", "project1", "npmv8"), func() { 26 | _, _, err := buildutils.RunNpmCmd("npm", "", []string{"install"}, &utils.NullLog{}) 27 | assert.NoError(t, err) 28 | }) 29 | } 30 | 31 | func TestYarnSchema(t *testing.T) { 32 | validateBuildInfoSchema(t, "yarn", filepath.Join("yarn", "v2", "project"), func() {}) 33 | } 34 | 35 | // Validate a build info schema for the input project. 36 | // t - The testing object 37 | // commandName - Command to run such as npm, yarn, mvn, and go 38 | // pathInTestData - The path of the test project in testdata dir 39 | // install - Install the project, if needed 40 | func validateBuildInfoSchema(t *testing.T, commandName, pathInTestData string, install func()) { 41 | // Load build-info schema 42 | schema, err := os.ReadFile("buildinfo-schema.json") 43 | assert.NoError(t, err) 44 | schemaLoader := gojsonschema.NewBytesLoader(schema) 45 | 46 | // Prepare test project 47 | cleanUp := prepareProject(t, pathInTestData, install) 48 | 49 | // Generate build-info 50 | buildInfoContent := generateBuildInfo(t, commandName) 51 | documentLoader := gojsonschema.NewBytesLoader(buildInfoContent) 52 | 53 | // Validate build-info schema 54 | result, err := gojsonschema.Validate(schemaLoader, documentLoader) 55 | assert.NoError(t, err) 56 | assert.True(t, result.Valid(), result.Errors()) 57 | 58 | // Clean up 59 | cleanUp() 60 | } 61 | 62 | // Copy project from testdata to a temp directory and change dir to the temp dir. 63 | // t - The testing object 64 | // pathInTestdata - The path of the test project in to the testdata dir 65 | // install - - Installs the project 66 | // Returns a cleanup callback 67 | func prepareProject(t *testing.T, pathInTestdata string, install func()) func() { 68 | wd, err := os.Getwd() 69 | assert.NoError(t, err) 70 | tempDir, cleanup := tests.CreateTestProject(t, filepath.Join("build", "testdata", pathInTestdata)) 71 | assert.NoError(t, os.Chdir(tempDir)) 72 | install() 73 | 74 | return func() { 75 | assert.NoError(t, os.Chdir(wd)) 76 | cleanup() 77 | } 78 | } 79 | 80 | // Generate build-info by running "bi " in the current working directory 81 | // t - The testing object 82 | // commandName - Command to run such as npm, yarn, mvn, and go 83 | // Returns the buildinfo content 84 | func generateBuildInfo(t *testing.T, commandName string) []byte { 85 | // Save old state 86 | oldArgs := os.Args 87 | oldStdout := os.Stdout 88 | 89 | // Create a commandOutput file 90 | commandOutput, err := os.CreateTemp("", "output") 91 | assert.NoError(t, err) 92 | 93 | defer func() { 94 | os.Stdout = oldStdout 95 | os.Args = oldArgs 96 | assert.NoError(t, commandOutput.Close()) 97 | assert.NoError(t, os.Remove(commandOutput.Name())) 98 | }() 99 | 100 | // Execute command with output redirection to a temp file 101 | os.Stdout = commandOutput 102 | os.Args = []string{"bi", commandName} 103 | main() 104 | 105 | // Read output 106 | content, err := os.ReadFile(commandOutput.Name()) 107 | assert.NoError(t, err) 108 | assert.NotEmpty(t, content) 109 | return content 110 | } 111 | -------------------------------------------------------------------------------- /buildscripts/build.bat: -------------------------------------------------------------------------------- 1 | set CGO_ENABLED=0 2 | go build -o bi.exe -ldflags "-w -extldflags -static" main.go 3 | -------------------------------------------------------------------------------- /buildscripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -eq 0 ] 4 | then 5 | exe_name="bi" 6 | else 7 | exe_name="$1" 8 | fi 9 | 10 | CGO_ENABLED=0 go build -o "$exe_name" -ldflags '-w -extldflags "-static"' main.go -------------------------------------------------------------------------------- /cli/cli_test.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestExtractStringFlag(t *testing.T) { 9 | testCases := []struct { 10 | args []string 11 | flagName string 12 | expectedFlagValue string 13 | expectedFilteredArgs []string 14 | expectedError bool 15 | }{ 16 | {args: []string{"a", "--b", "c", "d"}, flagName: "b", expectedFlagValue: "c", expectedFilteredArgs: []string{"a", "d"}, expectedError: false}, 17 | {args: []string{"--a=b"}, flagName: "a", expectedFlagValue: "b", expectedFilteredArgs: []string{}, expectedError: false}, 18 | {args: []string{"a", "--b=c"}, flagName: "a", expectedFlagValue: "", expectedFilteredArgs: []string{"a", "--b=c"}, expectedError: false}, 19 | {args: []string{"a", "--b"}, flagName: "b", expectedFlagValue: "", expectedFilteredArgs: []string{}, expectedError: true}, 20 | {args: []string{"a", "--b", "--c", "d"}, flagName: "b", expectedFlagValue: "", expectedFilteredArgs: []string{}, expectedError: true}, 21 | } 22 | 23 | for _, testCase := range testCases { 24 | actualFlagValue, actualFilteredArgs, err := extractStringFlag(testCase.args, testCase.flagName) 25 | if testCase.expectedError { 26 | assert.Error(t, err) 27 | continue 28 | } 29 | assert.NoError(t, err) 30 | assert.Equal(t, testCase.expectedFlagValue, actualFlagValue) 31 | assert.Equal(t, testCase.expectedFilteredArgs, actualFilteredArgs) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | buildinfo.io -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/jfrog/build-info-go 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/BurntSushi/toml v1.4.0 7 | github.com/CycloneDX/cyclonedx-go v0.9.0 8 | github.com/buger/jsonparser v1.1.1 9 | github.com/jfrog/gofrog v1.7.6 10 | github.com/stretchr/testify v1.9.0 11 | github.com/urfave/cli/v2 v2.27.4 12 | github.com/xeipuuv/gojsonschema v1.2.0 13 | golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e 14 | golang.org/x/term v0.24.0 15 | ) 16 | 17 | require ( 18 | github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect 19 | github.com/davecgh/go-spew v1.1.1 // indirect 20 | github.com/gookit/color v1.5.4 // indirect 21 | github.com/klauspost/cpuid/v2 v2.2.3 // indirect 22 | github.com/minio/sha256-simd v1.0.1 // indirect 23 | github.com/pmezard/go-difflib v1.0.0 // indirect 24 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 25 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect 26 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect 27 | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect 28 | github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect 29 | golang.org/x/sync v0.8.0 // indirect 30 | golang.org/x/sys v0.25.0 // indirect 31 | gopkg.in/yaml.v3 v3.0.1 // indirect 32 | ) 33 | 34 | // replace github.com/jfrog/gofrog => github.com/jfrog/gofrog v1.7.6-0.20240909061051-2d36ae4bd05a 35 | -------------------------------------------------------------------------------- /images/dark.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/images/dark.gif -------------------------------------------------------------------------------- /images/light.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/images/light.gif -------------------------------------------------------------------------------- /images/linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/images/linux.png -------------------------------------------------------------------------------- /images/mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/images/mac.png -------------------------------------------------------------------------------- /images/windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/images/windows.png -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/jfrog/build-info-go/cli" 7 | "github.com/jfrog/build-info-go/utils" 8 | clitool "github.com/urfave/cli/v2" 9 | ) 10 | 11 | const logLevelEnv = "BUILD_INFO_LOG_LEVEL" 12 | 13 | var log utils.Log 14 | var cliVersion = "dev" 15 | 16 | func main() { 17 | log = utils.NewDefaultLogger(getCliLogLevel()) 18 | app := &clitool.App{ 19 | Name: "Build-Info CLI", 20 | Usage: "Generate build-info for your source code", 21 | Commands: cli.GetCommands(log), 22 | Version: cliVersion, 23 | } 24 | err := app.Run(os.Args) 25 | if err != nil { 26 | log.Error(err) 27 | os.Exit(1) 28 | } 29 | } 30 | 31 | func getCliLogLevel() utils.LevelType { 32 | switch os.Getenv(logLevelEnv) { 33 | case "ERROR": 34 | return utils.ERROR 35 | case "WARN": 36 | return utils.WARN 37 | case "DEBUG": 38 | return utils.DEBUG 39 | default: 40 | return utils.INFO 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /release/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | #function build(pkg, goos, goarch, exeName) 5 | build () { 6 | pkg="$1" 7 | export GOOS="$2" 8 | export GOARCH="$3" 9 | exeName="$4" 10 | echo "Building $exeName for $GOOS-$GOARCH ..." 11 | 12 | CGO_ENABLED=0 jf go build -o "$exeName" -ldflags '-w -extldflags "-static" -X main.cliVersion='"$version" main.go 13 | chmod +x "$exeName" 14 | 15 | # Run verification after building plugin for the correct platform of this image. 16 | if [[ "$pkg" = "linux-386" ]]; then 17 | verifyVersionMatching 18 | fi 19 | } 20 | 21 | #function buildAndUpload(pkg, goos, goarch, fileExtension) 22 | buildAndUpload () { 23 | pkg="$1" 24 | goos="$2" 25 | goarch="$3" 26 | fileExtension="$4" 27 | exeName="bi$fileExtension" 28 | 29 | build "$pkg" "$goos" "$goarch" "$exeName" 30 | 31 | destPath="$pkgPath/$version/$pkg/$exeName" 32 | echo "Uploading $exeName to $destPath ..." 33 | jf rt u "./$exeName" "$destPath" 34 | } 35 | 36 | #function copyToLatestDir() 37 | copyToLatestDir () { 38 | echo "Copy version to latest dir: $pkgPath/$version/" 39 | jf rt cp "$pkgPath/$version/(*)" "$pkgPath/latest/{1}" --flat 40 | } 41 | 42 | # Verify version provided in pipelines UI matches version in build-info-go source code. 43 | verifyVersionMatching () { 44 | echo "Verifying provided version matches built version..." 45 | res=$(eval "./bi -v") 46 | exitCode=$? 47 | if [[ $exitCode -ne 0 ]]; then 48 | echo "Error: Failed verifying version matches" 49 | exit $exitCode 50 | fi 51 | 52 | # Get the version which is after the last space. (expected output to -v for example: "plugin-name version v1.0.0") 53 | echo "Output: $res" 54 | builtVersion="${res##* }" 55 | # Compare versions 56 | if [[ "$builtVersion" != "$version" ]]; then 57 | echo "Versions dont match. Provided: $version, Actual: $builtVersion" 58 | exit 1 59 | fi 60 | echo "Versions match." 61 | } 62 | 63 | version="$1" 64 | pkgPath="ecosys-bi-cli/v1" 65 | 66 | # Build and upload for every architecture. 67 | # Keep 'linux-386' first to prevent unnecessary uploads in case the built version doesn't match the provided one. 68 | buildAndUpload 'linux-386' 'linux' '386' '' 69 | buildAndUpload 'linux-amd64' 'linux' 'amd64' '' 70 | buildAndUpload 'linux-s390x' 'linux' 's390x' '' 71 | buildAndUpload 'linux-arm64' 'linux' 'arm64' '' 72 | buildAndUpload 'linux-arm' 'linux' 'arm' '' 73 | buildAndUpload 'linux-ppc64' 'linux' 'ppc64' '' 74 | buildAndUpload 'linux-ppc64le' 'linux' 'ppc64le' '' 75 | buildAndUpload 'mac-386' 'darwin' 'amd64' '' 76 | buildAndUpload 'mac-arm64' 'darwin' 'arm64' '' 77 | buildAndUpload 'windows-amd64' 'windows' 'amd64' '.exe' 78 | 79 | # Copy the uploaded version to override latest dir 80 | copyToLatestDir -------------------------------------------------------------------------------- /release/pipelines.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: buildinfoGoGit 3 | type: GitRepo 4 | configuration: 5 | path: jfrog/build-info-go 6 | branches: 7 | include: dev 8 | gitProvider: il_automation 9 | 10 | pipelines: 11 | - name: release_build_info_go 12 | configuration: 13 | runtime: 14 | type: image 15 | image: 16 | custom: 17 | name: releases-docker.jfrog.io/jfrog-ecosystem-integration-env 18 | tag: latest 19 | environmentVariables: 20 | readOnly: 21 | NEXT_VERSION: 0.0.0 22 | 23 | steps: 24 | - name: Release 25 | type: Bash 26 | configuration: 27 | inputResources: 28 | - name: buildinfoGoGit 29 | trigger: false 30 | integrations: 31 | - name: il_automation 32 | - name: ecosys_entplus_deployer 33 | execution: 34 | onExecute: 35 | - cd $res_buildinfoGoGit_resourcePath 36 | 37 | # Set env 38 | - export CI=true 39 | - export JFROG_CLI_BUILD_NAME=ecosystem-build-info-go-release 40 | - export JFROG_CLI_BUILD_NUMBER=$run_number 41 | - export JFROG_CLI_BUILD_PROJECT=ecosys 42 | 43 | # Make sure version provided 44 | - echo "Checking variables" 45 | - test -n "$NEXT_VERSION" -a "$NEXT_VERSION" != "0.0.0" 46 | 47 | # Configure Git and merge from the dev 48 | - git checkout main 49 | - git remote set-url origin https://$int_il_automation_token@github.com/jfrog/build-info-go.git 50 | - git merge origin/dev 51 | 52 | # Download JFrog CLI 53 | - curl -fL https://install-cli.jfrog.io | sh 54 | - jf c rm --quiet 55 | - jf c add internal --url=$int_ecosys_entplus_deployer_url --user=$int_ecosys_entplus_deployer_user --password=$int_ecosys_entplus_deployer_apikey 56 | - jf goc --repo-resolve ecosys-go-remote 57 | 58 | # Audit 59 | - jf audit 60 | 61 | # Build and upload 62 | - > 63 | env -i PATH=$PATH HOME=$HOME 64 | JFROG_CLI_BUILD_NAME=$JFROG_CLI_BUILD_NAME 65 | JFROG_CLI_BUILD_NUMBER=$JFROG_CLI_BUILD_NUMBER 66 | JFROG_CLI_BUILD_PROJECT=$JFROG_CLI_BUILD_PROJECT 67 | release/build.sh "$NEXT_VERSION" 68 | - jf rt bag && jf rt bce 69 | - jf rt bp $JFROG_CLI_BUILD_NAME $JFROG_CLI_BUILD_NUMBER 70 | 71 | # Update build-info.json 72 | - ./buildscripts/build.sh 73 | - chmod u+x bi 74 | - ./bi go > build-info.json 75 | - git add build-info.json 76 | - git commit -m "Update build-info.json file" 77 | 78 | # Create a Git tag to the current commit 79 | - git tag v${NEXT_VERSION} 80 | 81 | # Distribute release bundle 82 | - jf ds rbc ecosystem-build-info-go $NEXT_VERSION --spec="release/specs/bi-rbc-spec.json" --spec-vars="VERSION=$NEXT_VERSION" --sign 83 | - jf ds rbd ecosystem-build-info-go $NEXT_VERSION --site="releases.jfrog.io" --sync 84 | 85 | # Push to main 86 | - git clean -fd 87 | - git push 88 | - git push --tags 89 | 90 | onComplete: 91 | - jf c rm --quiet 92 | -------------------------------------------------------------------------------- /release/specs/bi-rbc-spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "pattern": "ecosys-bi-cli/(v1/${VERSION}/*)", 5 | "target": "bi-cli/{1}" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /tests/test_helpers.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | "path/filepath" 7 | "runtime" 8 | "testing" 9 | 10 | "github.com/jfrog/build-info-go/entities" 11 | "github.com/jfrog/build-info-go/utils" 12 | "github.com/jfrog/gofrog/version" 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | // Copy a project from path to temp dir. 17 | // projectPath - Local path to a project 18 | // Return the copied project location and a cleanup function to delete it. 19 | func CreateTestProject(t *testing.T, projectPath string) (tmpProjectPath string, cleanup func()) { 20 | var err error 21 | tmpProjectPath, err = utils.CreateTempDir() 22 | assert.NoError(t, err) 23 | assert.NoError(t, utils.CopyDir(projectPath, tmpProjectPath, true, nil)) 24 | cleanup = func() { 25 | assert.NoError(t, utils.RemoveTempDir(tmpProjectPath)) 26 | } 27 | return 28 | } 29 | 30 | func GetBuildInfo(t *testing.T, filePath string) entities.BuildInfo { 31 | data, err := os.ReadFile(filePath) 32 | assert.NoError(t, err) 33 | var buildinfo entities.BuildInfo 34 | assert.NoError(t, json.Unmarshal(data, &buildinfo)) 35 | return buildinfo 36 | } 37 | 38 | // Return the project path based on 'projectDir'. 39 | // withOsInPath - some tests have individual cases for specific os, if true, return the tests for that belong to the current running os. 40 | // testdataPath - abs path to testdata dir. 41 | // projectDirName - name of the project's directory. 42 | func CreateNpmTest(t *testing.T, testdataPath, projectDirName string, withOsInPath bool, version *version.Version) (tmpProjectPath string, cleanup func()) { 43 | var npmVersionDir string 44 | switch { 45 | case version.AtLeast("8.0.0"): 46 | npmVersionDir = "npmv8" 47 | case version.AtLeast("7.0.0"): 48 | npmVersionDir = "npmv7" 49 | case version.AtLeast("6.0.0"): 50 | npmVersionDir = "npmv6" 51 | } 52 | if withOsInPath { 53 | switch runtime.GOOS { 54 | case "windows": 55 | npmVersionDir = filepath.Join(npmVersionDir, "windows") 56 | case "linux": 57 | npmVersionDir = filepath.Join(npmVersionDir, "linux") 58 | default: 59 | // MacOs 60 | npmVersionDir = filepath.Join(npmVersionDir, "macos") 61 | } 62 | } 63 | path := filepath.Join(testdataPath, "npm", projectDirName, npmVersionDir) 64 | return CreateTestProject(t, path) 65 | } 66 | 67 | func PrintBuildInfoMismatch(t *testing.T, expected, actual []entities.Module) { 68 | excpectedStr, err := json.MarshalIndent(expected, "", " ") 69 | assert.NoError(t, err) 70 | actualStr, err := json.MarshalIndent(actual, "", " ") 71 | assert.NoError(t, err) 72 | t.Errorf("build-info don't match. want: \n%v\ngot:\n%s\n", string(excpectedStr), string(actualStr)) 73 | } 74 | 75 | func CreateTempDirWithCallbackAndAssert(t *testing.T) (string, func()) { 76 | tempDirPath, err := utils.CreateTempDir() 77 | assert.NoError(t, err, "Couldn't create temp dir") 78 | return tempDirPath, func() { 79 | assert.NoError(t, utils.RemoveTempDir(tempDirPath), "Couldn't remove temp dir") 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /utils/buildutils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/hex" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | func GetBuildDir(buildName, buildNumber, projectKey, buildsDirPath string) (string, error) { 11 | hash := sha256.Sum256([]byte(buildName + "_" + buildNumber + "_" + projectKey)) 12 | buildsDir := filepath.Join(buildsDirPath, hex.EncodeToString(hash[:])) 13 | err := os.MkdirAll(buildsDir, 0777) 14 | if err != nil { 15 | return "", err 16 | } 17 | return buildsDir, nil 18 | } 19 | 20 | func GetPartialsBuildDir(buildName, buildNumber, projectKey, buildsDirPath string) (string, error) { 21 | buildDir, err := GetBuildDir(buildName, buildNumber, projectKey, buildsDirPath) 22 | if err != nil { 23 | return "", err 24 | } 25 | buildDir = filepath.Join(buildDir, "partials") 26 | err = os.MkdirAll(buildDir, 0777) 27 | if err != nil { 28 | return "", err 29 | } 30 | return buildDir, nil 31 | } 32 | 33 | // Create a temp file of build-info. 34 | func CreateTempBuildFile(buildName, buildNumber, projectKey, buildsDirPath string, logger Log) (*os.File, error) { 35 | dirPath, err := GetBuildDir(buildName, buildNumber, projectKey, buildsDirPath) 36 | if err != nil { 37 | return nil, err 38 | } 39 | logger.Debug("Creating temp build file at: " + dirPath) 40 | tempFile, err := os.CreateTemp(dirPath, "temp") 41 | if err != nil { 42 | return nil, err 43 | } 44 | return tempFile, nil 45 | } 46 | -------------------------------------------------------------------------------- /utils/cliutils/consts.go: -------------------------------------------------------------------------------- 1 | package cliutils 2 | 3 | const ( 4 | // General CLI constants 5 | ClientAgent = "build-info-go" 6 | ) 7 | -------------------------------------------------------------------------------- /utils/compare_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/jfrog/build-info-go/utils/compareutils" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestIsEqualSlices(t *testing.T) { 11 | data := []struct { 12 | a, b []string 13 | res bool 14 | }{ 15 | {[]string{"1", "2", "3"}, []string{"1", "2", "3"}, true}, 16 | {[]string{"1", "3", "2"}, []string{"1", "2", "3"}, true}, 17 | {[]string{"1", "3", "2"}, []string{"3", "2", "1"}, true}, 18 | {[]string{"1", "3"}, []string{"1", "2", "3"}, false}, 19 | {[]string{"1", "2", "2", "3"}, []string{"1", "2", "3"}, false}, 20 | {[]string{"1", "2", "3"}, []string{"1", "2", "2", "3"}, false}, 21 | {[]string{"1", "(2)", "3"}, []string{"1", "2", "3"}, false}, 22 | {[]string{}, []string{"1", "2", "3"}, false}, 23 | {[]string{}, []string{}, true}, 24 | {nil, []string{}, true}, 25 | {nil, nil, true}, 26 | } 27 | for _, d := range data { 28 | if got := compareutils.IsEqualSlices(d.a, d.b); got != d.res { 29 | t.Errorf("IsEqualSlices(%v, %v) == %v, want %v", d.a, d.b, got, d.res) 30 | } 31 | } 32 | } 33 | 34 | func TestIsEqual2DSlices(t *testing.T) { 35 | data := []struct { 36 | a, b [][]string 37 | res bool 38 | }{ 39 | {[][]string{{"1", "2", "3"}}, [][]string{{"1", "2", "3"}}, true}, 40 | {[][]string{{"1", "2", "3"}}, [][]string{{"4", "5", "6"}}, false}, 41 | {[][]string{{"1", "2"}}, [][]string{{"1", "2", "3"}}, false}, 42 | {[][]string{{"1", "2", "3"}}, [][]string{{"1", "2"}}, false}, 43 | {[][]string{{"1", "2", "3"}, {"1", "2", "3"}}, [][]string{{"1", "2", "3"}}, false}, 44 | {[][]string{{"1", "2", "3"}, {}}, [][]string{{"1", "2", "3"}}, false}, 45 | {[][]string{{}}, [][]string{{"1", "2", "3"}}, false}, 46 | {[][]string{{}}, [][]string{{}}, true}, 47 | } 48 | for _, d := range data { 49 | if got := compareutils.IsEqual2DSlices(d.a, d.b); got != d.res { 50 | t.Errorf("IsEqual2DSlices(%v, %v) == %v, want %v", d.a, d.b, got, d.res) 51 | } 52 | } 53 | } 54 | 55 | func TestTo1DSlice(t *testing.T) { 56 | data := []struct { 57 | a [][]string 58 | res []string 59 | }{ 60 | {[][]string{{"1", "2", "3"}}, []string{"123"}}, 61 | {[][]string{{"1"}}, []string{"1"}}, 62 | {[][]string{{}}, []string{""}}, 63 | } 64 | for _, d := range data { 65 | if got := compareutils.To1DSlice(d.a); !assert.ElementsMatch(t, got, d.res) { 66 | t.Errorf("to1DSlice(%v) == %v, want %v", d.a, got, d.res) 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /utils/compareutils/compare.go: -------------------------------------------------------------------------------- 1 | package compareutils 2 | 3 | import ( 4 | "reflect" 5 | "sort" 6 | ) 7 | 8 | // Compare two slices irrespective of elements order. 9 | func IsEqualSlices(a, b []string) bool { 10 | if len(a) != len(b) { 11 | return false 12 | } 13 | 14 | a_copy := make([]string, len(a)) 15 | b_copy := make([]string, len(b)) 16 | 17 | copy(a_copy, a) 18 | copy(b_copy, b) 19 | 20 | sort.Strings(a_copy) 21 | sort.Strings(b_copy) 22 | 23 | return reflect.DeepEqual(a_copy, b_copy) 24 | } 25 | 26 | // Compare two dimensional slices irrespective of elements order. 27 | func IsEqual2DSlices(a, b [][]string) bool { 28 | return IsEqualSlices(To1DSlice(a), To1DSlice(b)) 29 | } 30 | 31 | // Transform two dimensional slice to one dimensional slice 32 | func To1DSlice(a [][]string) (result []string) { 33 | for _, i := range a { 34 | temp := "" 35 | for _, j := range i { 36 | temp += j 37 | } 38 | result = append(result, temp) 39 | } 40 | return 41 | } 42 | -------------------------------------------------------------------------------- /utils/dependenciesutils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "os" 7 | "path" 8 | "path/filepath" 9 | "time" 10 | ) 11 | 12 | const ( 13 | configPropertiesPathTempPrefix = "extractorProperties" 14 | buildInfoPathKey = "buildInfo.generated.build.info" 15 | buildNameKey = "buildInfo.build.name" 16 | buildTimestampKey = "buildInfo.build.timestamp" 17 | buildNumberKey = "buildInfo.build.number" 18 | projectKey = "buildInfo.build.project" 19 | ) 20 | 21 | // Download the relevant build-info-extractor jar, if it does not already exist locally. 22 | // By default, the jar is downloaded directly from https://releases.jfrog.io/artifactory/oss-release-local. 23 | // 24 | // downloadPath: download path in the remote server. 25 | // filename: The local file name. 26 | // targetPath: The local download path (without the file name). 27 | func downloadExtractorIfNeeded(downloadTo, filename, downloadPath string, downloadExtractorFunc func(downloadTo, downloadPath string) error, logger Log) error { 28 | // If the file exists locally, we're done. 29 | absFileName := filepath.Join(downloadTo, filename) 30 | exists, err := IsFileExists(absFileName, true) 31 | if exists || err != nil { 32 | return err 33 | } 34 | if err := os.MkdirAll(downloadTo, 0777); err != nil { 35 | return err 36 | } 37 | if downloadExtractorFunc != nil { 38 | // Override default download. 39 | return downloadExtractorFunc(absFileName, downloadPath) 40 | } 41 | extractorUrl := "https://releases.jfrog.io/artifactory/oss-release-local/" + downloadPath 42 | logger.Info("Downloading build-info-extractor from", extractorUrl, "to", downloadTo) 43 | return DownloadFile(absFileName, extractorUrl) 44 | } 45 | 46 | // Save all the extractor's properties into a local file. 47 | // extractorConfPath - Path to a file to which all the extractor's properties will be written. 48 | // buildInfoPath - Path to a file to which the build-info data will be written. 49 | // buildName - Build name of the current build. 50 | // buildNumber - Build number of the current build. 51 | // project - JFrog Project key of the current build 52 | // configProperties - Data of the actual extractor's properties. 53 | // Returns the extractor Config file path. 54 | func CreateExtractorPropsFile(extractorConfPath, buildInfoPath, buildName, buildNumber string, buildTimestamp time.Time, project string, configProperties map[string]string) (string, error) { 55 | if err := os.MkdirAll(extractorConfPath, 0777); err != nil { 56 | return "", err 57 | } 58 | propertiesFile, err := os.CreateTemp(extractorConfPath, configPropertiesPathTempPrefix) 59 | if err != nil { 60 | return "", err 61 | } 62 | defer func() { 63 | err = errors.Join(err, propertiesFile.Close()) 64 | }() 65 | var buildProperties = map[string]string{ 66 | buildInfoPathKey: buildInfoPath, 67 | buildNameKey: buildName, 68 | buildTimestampKey: fmt.Sprintf("%d", buildTimestamp.UnixMilli()), 69 | buildNumberKey: buildNumber, 70 | projectKey: project, 71 | } 72 | return propertiesFile.Name(), writeProps(propertiesFile, configProperties, buildProperties) 73 | } 74 | 75 | func DownloadDependencies(downloadTo, filename, relativeFilePath string, downloadExtractorFunc func(downloadTo, downloadPath string) error, logger Log) error { 76 | downloadPath := path.Join(relativeFilePath, filename) 77 | return downloadExtractorIfNeeded(downloadTo, filename, downloadPath, downloadExtractorFunc, logger) 78 | } 79 | 80 | func writeProps(propertiesFile *os.File, maps ...map[string]string) (err error) { 81 | for _, props := range maps { 82 | for key, value := range props { 83 | if value != "" { 84 | if _, err = propertiesFile.WriteString(key + "=" + value + "\n"); err != nil { 85 | return err 86 | } 87 | } 88 | } 89 | } 90 | return nil 91 | } 92 | -------------------------------------------------------------------------------- /utils/error.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type PackageManager string 9 | 10 | const ( 11 | Npm PackageManager = "npm" 12 | Maven PackageManager = "maven" 13 | Pip PackageManager = "pip" 14 | Go PackageManager = "go" 15 | ) 16 | 17 | // ForbiddenError represents a 403 Forbidden error. 18 | type ForbiddenError struct { 19 | Message string 20 | } 21 | 22 | // Error implements the error interface for ForbiddenError. 23 | func (e *ForbiddenError) Error() string { 24 | return "403 Forbidden" 25 | } 26 | 27 | // NewForbiddenError creates a new ForbiddenError with the given message. 28 | func NewForbiddenError() *ForbiddenError { 29 | return &ForbiddenError{} 30 | } 31 | 32 | type ErrProjectNotInstalled struct { 33 | UninstalledDir string 34 | } 35 | 36 | func (err *ErrProjectNotInstalled) Error() string { 37 | return fmt.Sprintf("Directory '%s' is not installed. Skipping SCA scan in this directory...", err.UninstalledDir) 38 | } 39 | 40 | // IsForbiddenOutput checks whether the provided output includes a 403 Forbidden. The various package managers have their own forbidden output formats. 41 | func IsForbiddenOutput(tech PackageManager, cmdOutput string) bool { 42 | switch tech { 43 | case "npm": 44 | return strings.Contains(strings.ToLower(cmdOutput), "403 forbidden") 45 | case "maven": 46 | return strings.Contains(cmdOutput, "status code: 403") || 47 | strings.Contains(strings.ToLower(cmdOutput), "403 forbidden") || 48 | // In some cases mvn returns 500 status code even though it got 403 from artifactory. 49 | strings.Contains(cmdOutput, "status code: 500") 50 | case "pip": 51 | return strings.Contains(strings.ToLower(cmdOutput), "http error 403") 52 | case "go": 53 | return strings.Contains(strings.ToLower(cmdOutput), "403 forbidden") || 54 | strings.Contains(strings.ToLower(cmdOutput), " 403") 55 | } 56 | return false 57 | } 58 | -------------------------------------------------------------------------------- /utils/ioutils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "errors" 5 | "io" 6 | "runtime" 7 | "strings" 8 | "sync" 9 | ) 10 | 11 | var ErrShortWrite = errors.New("short write") 12 | 13 | type asyncMultiWriter struct { 14 | writers []io.Writer 15 | } 16 | 17 | // AsyncMultiWriter creates a writer that duplicates its writes to all the 18 | // provided writers asynchronous 19 | func AsyncMultiWriter(writers ...io.Writer) io.Writer { 20 | w := make([]io.Writer, len(writers)) 21 | copy(w, writers) 22 | return &asyncMultiWriter{w} 23 | } 24 | 25 | // Writes data asynchronously to each writer and waits for all of them to complete. 26 | // In case of an error, the writing will not complete. 27 | func (t *asyncMultiWriter) Write(p []byte) (int, error) { 28 | var wg sync.WaitGroup 29 | wg.Add(len(t.writers)) 30 | errChannel := make(chan error) 31 | finished := make(chan bool, 1) 32 | for _, w := range t.writers { 33 | go writeData(p, w, &wg, errChannel) 34 | } 35 | go func() { 36 | wg.Wait() 37 | close(finished) 38 | }() 39 | // This select will block until one of the two channels returns a value. 40 | select { 41 | case <-finished: 42 | case err := <-errChannel: 43 | if err != nil { 44 | return 0, err 45 | } 46 | } 47 | return len(p), nil 48 | } 49 | 50 | func writeData(p []byte, w io.Writer, wg *sync.WaitGroup, errChan chan error) { 51 | n, err := w.Write(p) 52 | if err != nil { 53 | errChan <- err 54 | } 55 | if n != len(p) { 56 | errChan <- ErrShortWrite 57 | } 58 | wg.Done() 59 | } 60 | 61 | func UnixToWinPathSeparator(filePath string) string { 62 | return strings.ReplaceAll(filePath, "/", "\\\\") 63 | } 64 | 65 | func WinToUnixPathSeparator(filePath string) string { 66 | return strings.ReplaceAll(filePath, "\\", "/") 67 | } 68 | 69 | func IsWindows() bool { 70 | return runtime.GOOS == "windows" 71 | } 72 | 73 | func IsLinux() bool { 74 | return runtime.GOOS == "linux" 75 | } 76 | -------------------------------------------------------------------------------- /utils/logger.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "log" 5 | "os" 6 | ) 7 | 8 | type LevelType int 9 | 10 | const ( 11 | ERROR LevelType = iota 12 | WARN 13 | INFO 14 | DEBUG 15 | ) 16 | 17 | type Log interface { 18 | Debug(a ...interface{}) 19 | Info(a ...interface{}) 20 | Warn(a ...interface{}) 21 | Error(a ...interface{}) 22 | Output(a ...interface{}) 23 | } 24 | 25 | // NullLog is a logger that does nothing 26 | type NullLog struct { 27 | } 28 | 29 | func (nl *NullLog) Debug(...interface{}) { 30 | } 31 | 32 | func (nl *NullLog) Info(...interface{}) { 33 | } 34 | 35 | func (nl *NullLog) Warn(...interface{}) { 36 | } 37 | 38 | func (nl *NullLog) Error(...interface{}) { 39 | } 40 | 41 | func (nl *NullLog) Output(...interface{}) { 42 | } 43 | 44 | type defaultLogger struct { 45 | logLevel LevelType 46 | outputLog *log.Logger 47 | debugLog *log.Logger 48 | infoLog *log.Logger 49 | warnLog *log.Logger 50 | errorLog *log.Logger 51 | } 52 | 53 | // NewDefaultLogger creates a new logger with a given LogLevel. 54 | // All logs are written to Stderr and output is written to Stdout. 55 | func NewDefaultLogger(logLevel LevelType) *defaultLogger { 56 | logger := new(defaultLogger) 57 | logger.logLevel = logLevel 58 | logger.outputLog = log.New(os.Stdout, "", 0) 59 | logger.debugLog = log.New(os.Stderr, "[Debug] ", 0) 60 | logger.infoLog = log.New(os.Stderr, "[Info] ", 0) 61 | logger.warnLog = log.New(os.Stderr, "[Warn] ", 0) 62 | logger.errorLog = log.New(os.Stderr, "[Error] ", 0) 63 | return logger 64 | } 65 | 66 | func (logger defaultLogger) Debug(a ...interface{}) { 67 | if logger.logLevel >= DEBUG { 68 | logger.debugLog.Println(a...) 69 | } 70 | } 71 | 72 | func (logger defaultLogger) Info(a ...interface{}) { 73 | if logger.logLevel >= INFO { 74 | logger.infoLog.Println(a...) 75 | } 76 | } 77 | 78 | func (logger defaultLogger) Warn(a ...interface{}) { 79 | if logger.logLevel >= WARN { 80 | logger.warnLog.Println(a...) 81 | } 82 | } 83 | 84 | func (logger defaultLogger) Error(a ...interface{}) { 85 | if logger.logLevel >= ERROR { 86 | logger.errorLog.Println(a...) 87 | } 88 | } 89 | 90 | func (logger defaultLogger) Output(a ...interface{}) { 91 | logger.outputLog.Println(a...) 92 | } 93 | -------------------------------------------------------------------------------- /utils/masking.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | gofrogcmd "github.com/jfrog/gofrog/io" 5 | "strings" 6 | ) 7 | 8 | // #nosec G101 -- False positive - no hardcoded credentials. 9 | const CredentialsInUrlRegexp = `(?:http|https|git)://.+@` 10 | 11 | // Remove the credentials information from the line. 12 | func RemoveCredentials(pattern *gofrogcmd.CmdOutputPattern) (string, error) { 13 | splitResult := strings.Split(pattern.MatchedResults[0], "//") 14 | return strings.ReplaceAll(pattern.Line, pattern.MatchedResults[0], splitResult[0]+"//***@"), nil 15 | } 16 | -------------------------------------------------------------------------------- /utils/pythonutils/pipdeptree/scriptcreator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/jfrog/build-info-go/utils" 5 | "os" 6 | "path" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | const ( 12 | pipDepTreeContentFileName = "deptreescript.go" 13 | pipDepTreePythonScript = "pipdeptree.py" 14 | pythonPackageName = "pythonutils" 15 | pythonPackageRelativePath = "utils" 16 | // The pip-dep-tree script version. The version should be manually incremented following changes to the pipdeptree.py source file. 17 | pipDepTreeVersion = "6" 18 | ) 19 | 20 | // This main function should be executed manually following changes in pipdeptree.py. Running the function generates new 'pipDepTreeContentFileName' from 'pipDepTreePythonScript. 21 | // Make sure to increment the value of the 'pipDepTreeVersion' constant before running this main function. 22 | func main() { 23 | wd, err := os.Getwd() 24 | if err != nil { 25 | panic(err) 26 | } 27 | 28 | // Check if a pip-dep-tree file of the latest version already exists 29 | pipDepTreeContentPath := filepath.Join(wd, pythonPackageRelativePath, pythonPackageName, pipDepTreeContentFileName) 30 | exists, err := utils.IsFileExists(pipDepTreeContentPath, false) 31 | if err != nil { 32 | panic(err) 33 | } 34 | if exists { 35 | return 36 | } 37 | // Read the script content from the .py file 38 | pyFile, err := os.ReadFile(path.Join(wd, pythonPackageRelativePath, pythonPackageName, "pipdeptree", pipDepTreePythonScript)) 39 | if err != nil { 40 | panic(err) 41 | } 42 | // Replace all backticks ( ` ) with a single quote ( ' ) 43 | pyFileString := strings.ReplaceAll(string(pyFile), "`", "'") 44 | 45 | resourceString := "package " + pythonPackageName + "\n\n" 46 | // Add a const string with the script's version 47 | resourceString += "const pipDepTreeVersion = \"" + pipDepTreeVersion + "\"\n\n" 48 | // Write the script content a byte-slice 49 | resourceString += "var pipDepTreeContent = []byte(`\n" + pyFileString + "`)" 50 | // Create .go file with the script content 51 | err = os.WriteFile(pipDepTreeContentPath, []byte(resourceString), os.ModePerm) 52 | if err != nil { 53 | panic(err) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /utils/pythonutils/pipenvutils.go: -------------------------------------------------------------------------------- 1 | package pythonutils 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | 8 | "github.com/jfrog/build-info-go/utils" 9 | "github.com/jfrog/gofrog/io" 10 | ) 11 | 12 | var ( 13 | windowsReplaceBytes = []byte("\r\n") 14 | unixReplaceBytes = []byte("\n") 15 | replacementBytes = []byte("") 16 | ) 17 | 18 | // Executes pipenv graph. 19 | // Returns a dependency map of all the installed pipenv packages in the current environment and also another list of the top level dependencies 20 | // 'dependenciesGraph' - map between all parent modules and their child dependencies 21 | // 'topLevelPackagesList' - list of all top level dependencies ( root dependencies only) 22 | func getPipenvDependencies(srcPath string, logger utils.Log) (dependenciesGraph map[string][]string, topLevelDependencies []string, err error) { 23 | // Run pipenv graph 24 | pipenvGraphCmd := io.NewCommand("pipenv", "graph", []string{"--json"}) 25 | pipenvGraphCmd.Dir = srcPath 26 | output, err := pipenvGraphCmd.RunWithOutput() 27 | if err != nil { 28 | err = fmt.Errorf("failed to run pipenv graph --json: %s", err.Error()) 29 | return 30 | } 31 | logger.Debug("pipenv graph --json output:\n" + string(output)) 32 | // Parse into array. 33 | packages := make([]pythonDependencyPackage, 0) 34 | err = json.Unmarshal(cleanJsonOutput(output), &packages) 35 | if err != nil { 36 | err = fmt.Errorf("failed to parse pipenv graph --json output: %s", err.Error()) 37 | return 38 | } 39 | dependenciesGraph, topLevelDependencies, err = parseDependenciesToGraph(packages) 40 | return 41 | } 42 | 43 | // Sometimes, `pipenv graph --json` command returns output with new line characters in between (not valid json) So, we need to remove them before unmarshaling. 44 | func cleanJsonOutput(output []byte) []byte { 45 | // For Windows 46 | output = bytes.ReplaceAll(output, windowsReplaceBytes, replacementBytes) 47 | // For Unix 48 | return bytes.ReplaceAll(output, unixReplaceBytes, replacementBytes) 49 | } 50 | -------------------------------------------------------------------------------- /utils/pythonutils/piputils_test.go: -------------------------------------------------------------------------------- 1 | package pythonutils 2 | 3 | import ( 4 | "path/filepath" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/jfrog/build-info-go/tests" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestGetProjectNameAndVersionFromFileContent(t *testing.T) { 13 | testCases := []struct { 14 | fileContent string 15 | expectedProjectName string 16 | expectedProjectVersion string 17 | }{ 18 | {"Metadata-Version: 1.0\nName: jfrog-python-example-1\nVersion: 1.0\nSummary: Project example for building Python project with JFrog products\nHome-page: https://github.com/jfrog/project-examples\nAuthor: JFrog\nAuthor-email: jfrog@jfrog.com\nLicense: UNKNOWN\nDescription: UNKNOWN\nPlatform: UNKNOWN", "jfrog-python-example-1", "1.0"}, 19 | {"Metadata-Version: Name: jfrog-python-example-2\nLicense: UNKNOWN\nDescription: UNKNOWN\nPlatform: UNKNOWN\nName: jfrog-python-example-2\nVersion: 1.0\nSummary: Project example for building Python project with JFrog products\nHome-page: https://github.com/jfrog/project-examples\nAuthor: JFrog\nAuthor-email: jfrog@jfrog.com", "jfrog-python-example-2", "1.0"}, 20 | {"Name:Metadata-Version: 3.0\nName: jfrog-python-example-3\nVersion: 1.0\nSummary: Project example for building Python project with JFrog products\nHome-page: https://github.com/jfrog/project-examples\nAuthor: JFrog\nAuthor-email: jfrog@jfrog.com\nName: jfrog-python-example-4", "jfrog-python-example-3", "1.0"}, 21 | } 22 | 23 | for _, test := range testCases { 24 | projectName, projectVersion, err := getProjectNameAndVersionFromFileContent([]byte(test.fileContent)) 25 | assert.NoError(t, err) 26 | assert.Equal(t, test.expectedProjectName, projectName) 27 | assert.Equal(t, test.expectedProjectVersion, projectVersion) 28 | } 29 | } 30 | 31 | var moduleNameTestProvider = []struct { 32 | projectName string 33 | moduleName string 34 | expectedModuleName string 35 | expectedPackageName string 36 | }{ 37 | {"setuppyproject", "", "jfrog-python-example:1.0", "jfrog-python-example:1.0"}, 38 | {"setuppyproject", "overidden-module", "overidden-module", "jfrog-python-example:1.0"}, 39 | {"requirementsproject", "", "", ""}, 40 | {"requirementsproject", "overidden-module", "overidden-module", ""}, 41 | {"pyproject", "", "jfrog-python-example:1.0", "pip-project-with-pyproject:1.2.3"}, 42 | {"pyproject", "overidden-module", "overidden-module", "pip-project-with-pyproject:1.2.3"}, 43 | } 44 | 45 | func TestGetPipProjectId(t *testing.T) { 46 | for _, test := range moduleNameTestProvider { 47 | t.Run(strings.Join([]string{test.projectName, test.moduleName}, "/"), func(t *testing.T) { 48 | tmpProjectPath, cleanup := tests.CreateTestProject(t, filepath.Join("..", "testdata", "pip", test.projectName)) 49 | defer cleanup() 50 | 51 | // Determine module name 52 | packageName, err := getPipProjectId(tmpProjectPath) 53 | if assert.NoError(t, err) { 54 | assert.Equal(t, test.expectedPackageName, packageName) 55 | } 56 | }) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /utils/pythonutils/poetryutils_test.go: -------------------------------------------------------------------------------- 1 | package pythonutils 2 | 3 | import ( 4 | "path/filepath" 5 | "reflect" 6 | "sort" 7 | "testing" 8 | 9 | "github.com/jfrog/build-info-go/tests" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestGetProjectNameFromPyproject(t *testing.T) { 14 | testCases := []struct { 15 | poetryProject string 16 | expectedProjectName string 17 | }{ 18 | {"project", "my-poetry-project:1.1.0"}, 19 | {"nodevdeps", "my-poetry-project:1.1.17"}, 20 | } 21 | 22 | for _, testCase := range testCases { 23 | t.Run(testCase.poetryProject, func(t *testing.T) { 24 | tmpProjectPath, cleanup := tests.CreateTestProject(t, filepath.Join("..", "testdata", "poetry", testCase.poetryProject)) 25 | defer cleanup() 26 | 27 | actualValue, err := extractPoetryPackageFromPyProjectToml(filepath.Join(tmpProjectPath, "pyproject.toml")) 28 | assert.NoError(t, err) 29 | if actualValue.Name != testCase.expectedProjectName { 30 | t.Errorf("Expected value: %s, got: %s.", testCase.expectedProjectName, actualValue) 31 | } 32 | }) 33 | } 34 | } 35 | 36 | func TestGetProjectDependencies(t *testing.T) { 37 | testCases := []struct { 38 | poetryProject string 39 | expectedDirectDependencies []string 40 | expectedTransitiveDependencies [][]string 41 | }{ 42 | {"project", []string{"numpy:1.23.0", "pytest:5.4.3", "python:"}, [][]string{nil, {"atomicwrites:1.4.0", "attrs:21.4.0", "colorama:0.4.5", "more-itertools:8.13.0", "packaging:21.3", "pluggy:0.13.1", "py:1.11.0", "wcwidth:0.2.5"}, nil}}, 43 | {"nodevdeps", []string{"numpy:1.23.0", "python:"}, [][]string{nil, nil, nil}}, 44 | } 45 | 46 | for _, testCase := range testCases { 47 | t.Run(testCase.poetryProject, func(t *testing.T) { 48 | tmpProjectPath, cleanup := tests.CreateTestProject(t, filepath.Join("..", "testdata", "poetry", testCase.poetryProject)) 49 | defer cleanup() 50 | 51 | graph, directDependencies, err := getPoetryDependencies(tmpProjectPath) 52 | assert.NoError(t, err) 53 | sort.Strings(directDependencies) 54 | if !reflect.DeepEqual(directDependencies, testCase.expectedDirectDependencies) { 55 | t.Errorf("Expected value: %s, got: %s.", testCase.expectedDirectDependencies, directDependencies) 56 | } 57 | for i, directDependency := range directDependencies { 58 | transitiveDependencies := graph[directDependency] 59 | sort.Strings(transitiveDependencies) 60 | if !reflect.DeepEqual(transitiveDependencies, testCase.expectedTransitiveDependencies[i]) { 61 | t.Errorf("Expected value: %s, got: %s.", testCase.expectedTransitiveDependencies[i], graph[directDependency]) 62 | } 63 | } 64 | }) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /utils/pythonutils/pyprojectutils.go: -------------------------------------------------------------------------------- 1 | package pythonutils 2 | 3 | import ( 4 | "github.com/BurntSushi/toml" 5 | "os" 6 | ) 7 | 8 | type PyProjectToml struct { 9 | // Represents the [tool.poetry] section in pyproject.toml. 10 | Tool map[string]PoetryPackage 11 | // Represents the [project] section in pyproject.toml, for pypi package managers other than poetry. 12 | Project Project 13 | } 14 | 15 | // Pypi project defined for package managers other than poetry (pip, pipenv, etc...) 16 | type Project struct { 17 | Name string 18 | Version string 19 | Description string 20 | } 21 | 22 | // Get project name and version by parsing the pyproject.toml file. 23 | // Try to extract the project name and version from the [project] section, or if requested also try from [tool.poetry] section. 24 | func extractPipProjectDetailsFromPyProjectToml(pyProjectFilePath string) (projectName, projectVersion string, err error) { 25 | pyProjectFile, err := decodePyProjectToml(pyProjectFilePath) 26 | if err != nil { 27 | return 28 | } 29 | return pyProjectFile.Project.Name, pyProjectFile.Project.Version, nil 30 | } 31 | 32 | func decodePyProjectToml(pyProjectFilePath string) (pyProjectFile PyProjectToml, err error) { 33 | content, err := os.ReadFile(pyProjectFilePath) 34 | if err != nil { 35 | return 36 | } 37 | _, err = toml.Decode(string(content), &pyProjectFile) 38 | return 39 | } 40 | 41 | // Look for 'pyproject.toml' file in current work dir. 42 | // If found, return its absolute path. 43 | func getPyProjectFilePath(srcPath string) (string, error) { 44 | return getFilePath(srcPath, "pyproject.toml") 45 | } 46 | -------------------------------------------------------------------------------- /utils/pythonutils/pyprojectutils_test.go: -------------------------------------------------------------------------------- 1 | package pythonutils 2 | 3 | import ( 4 | "path/filepath" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestGetPyProject(t *testing.T) { 11 | testCases := []struct { 12 | testName string 13 | pyProjectFilePath string 14 | expectedName string 15 | expectedVersion string 16 | errExpected bool 17 | }{ 18 | {"successful", filepath.Join("..", "testdata", "pip", "pyproject"), "pip-project-with-pyproject", "1.2.3", false}, 19 | {"does not contain project section", filepath.Join("..", "testdata", "poetry", "project"), "", "", false}, 20 | {"invalid", filepath.Join("..", "testdata", "pip", "setuppyproject", "setup.py"), "", "", true}, 21 | } 22 | 23 | for _, testCase := range testCases { 24 | t.Run(testCase.testName, func(t *testing.T) { 25 | name, version, err := extractPipProjectDetailsFromPyProjectToml(filepath.Join(testCase.pyProjectFilePath, "pyproject.toml")) 26 | if testCase.errExpected { 27 | assert.Error(t, err) 28 | return 29 | } 30 | assert.Equal(t, testCase.expectedName, name) 31 | assert.Equal(t, testCase.expectedVersion, version) 32 | assert.NoError(t, err) 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /utils/pythonutils/twineutils.go: -------------------------------------------------------------------------------- 1 | package pythonutils 2 | 3 | import ( 4 | "fmt" 5 | "github.com/jfrog/build-info-go/entities" 6 | "github.com/jfrog/gofrog/crypto" 7 | gofrogcmd "github.com/jfrog/gofrog/io" 8 | "github.com/jfrog/gofrog/log" 9 | "path" 10 | "path/filepath" 11 | "regexp" 12 | "slices" 13 | "strings" 14 | ) 15 | 16 | const ( 17 | _twineExeName = "twine" 18 | _twineUploadCmdName = "upload" 19 | _verboseFlag = "--verbose" 20 | _disableProgressFlag = "--disable-progress-bar" 21 | ) 22 | 23 | // Run a twine upload and parse artifacts paths from logs. 24 | func TwineUploadWithLogParsing(commandArgs []string, srcPath string) (artifactsPaths []string, err error) { 25 | commandArgs = addRequiredFlags(commandArgs) 26 | uploadCmd := gofrogcmd.NewCommand(_twineExeName, _twineUploadCmdName, commandArgs) 27 | uploadCmd.Dir = srcPath 28 | log.Debug("Running twine command: '", _twineExeName, _twineUploadCmdName, strings.Join(commandArgs, " "), "'with build info collection") 29 | _, errorOut, _, err := gofrogcmd.RunCmdWithOutputParser(uploadCmd, true, getArtifactsParser(&artifactsPaths)) 30 | if err != nil { 31 | return nil, fmt.Errorf("failed running '%s %s %s' command with error: '%s - %s'", _twineExeName, _twineUploadCmdName, strings.Join(commandArgs, " "), err.Error(), errorOut) 32 | } 33 | return 34 | } 35 | 36 | // Enabling verbose and disabling progress bar are required for log parsing. 37 | func addRequiredFlags(commandArgs []string) []string { 38 | for _, flag := range []string{_verboseFlag, _disableProgressFlag} { 39 | if !slices.Contains(commandArgs, flag) { 40 | commandArgs = append(commandArgs, flag) 41 | } 42 | } 43 | return commandArgs 44 | } 45 | 46 | func getArtifactsParser(artifactsPaths *[]string) (parser *gofrogcmd.CmdOutputPattern) { 47 | return &gofrogcmd.CmdOutputPattern{ 48 | // Regexp to catch the paths in lines such as "INFO dist/jfrog_python_example-1.0-py3-none-any.whl (1.6 KB)" 49 | // First part ".+\s" is the line prefix. 50 | // Second part "([^ \t]+)" is the artifact path as a group. 51 | // Third part "\s+\([\d.]+\s+[A-Za-z]{2}\)" is the size and unit, surrounded by parentheses. 52 | RegExp: regexp.MustCompile(`^.+\s([^ \t]+)\s+\([\d.]+\s+[A-Za-z]{2}\)`), 53 | ExecFunc: func(pattern *gofrogcmd.CmdOutputPattern) (string, error) { 54 | // Check for out of bound results. 55 | if len(pattern.MatchedResults)-1 <= 0 { 56 | log.Debug(fmt.Sprintf("Failed extracting artifact name from line: %s", pattern.Line)) 57 | return pattern.Line, nil 58 | } 59 | *artifactsPaths = append(*artifactsPaths, pattern.MatchedResults[1]) 60 | return pattern.Line, nil 61 | }, 62 | } 63 | } 64 | 65 | // Create artifacts entities from the artifacts paths that were found during the upload. 66 | func CreateArtifactsFromPaths(artifactsPaths []string) (artifacts []entities.Artifact, err error) { 67 | projectName, projectVersion, err := getPipProjectNameAndVersion("") 68 | if err != nil { 69 | return 70 | } 71 | var absPath string 72 | var fileDetails *crypto.FileDetails 73 | for _, artifactPath := range artifactsPaths { 74 | absPath, err = filepath.Abs(artifactPath) 75 | if err != nil { 76 | return nil, err 77 | } 78 | fileDetails, err = crypto.GetFileDetails(absPath, true) 79 | if err != nil { 80 | return nil, err 81 | } 82 | 83 | artifact := entities.Artifact{Name: filepath.Base(absPath), Path: path.Join(projectName, projectVersion, filepath.Base(absPath)), 84 | Type: strings.TrimPrefix(filepath.Ext(absPath), ".")} 85 | artifact.Checksum = entities.Checksum{Sha1: fileDetails.Checksum.Sha1, Md5: fileDetails.Checksum.Md5} 86 | artifacts = append(artifacts, artifact) 87 | } 88 | return 89 | } 90 | -------------------------------------------------------------------------------- /utils/pythonutils/twineutils_test.go: -------------------------------------------------------------------------------- 1 | package pythonutils 2 | 3 | import ( 4 | gofrogcmd "github.com/jfrog/gofrog/io" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func TestTwineUploadCapture(t *testing.T) { 10 | tests := []struct { 11 | name string 12 | text string 13 | expectedCaptures []string 14 | }{ 15 | { 16 | name: "verbose true", 17 | text: ` 18 | Uploading distributions to https://myplatform.jfrog.io/artifactory/api/pypi/twine-local/ 19 | INFO dist/jfrog_python_example-1.0-py3-none-any.whl (1.6 KB) 20 | INFO dist/jfrog_python_example-1.0.tar.gz (2.4 KB) 21 | INFO username set by command options 22 | INFO password set by command options 23 | INFO username: user 24 | INFO password: 25 | Uploading jfrog_python_example-1.0-py3-none-any.whl 26 | 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.5/4.5 kB • 00:00 • ? 27 | INFO Response from https://myplatform.jfrog.io/artifactory/api/pypi/twine-local/: 28 | 200 29 | Uploading jfrog_python_example-1.0.tar.gz 30 | 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.3/5.3 kB • 00:00 • ? 31 | INFO Response from https://myplatform.jfrog.io/artifactory/api/pypi/twine-local/: 32 | 200`, 33 | expectedCaptures: []string{"dist/jfrog_python_example-1.0-py3-none-any.whl", 34 | "dist/jfrog_python_example-1.0.tar.gz"}, 35 | }, 36 | } 37 | 38 | for _, testCase := range tests { 39 | t.Run(testCase.name, func(t *testing.T) { 40 | var artifacts []string 41 | runDummyTextStream(t, testCase.text, []*gofrogcmd.CmdOutputPattern{getArtifactsParser(&artifacts)}) 42 | assert.ElementsMatch(t, artifacts, testCase.expectedCaptures) 43 | }) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /utils/testdata/mods/testBadGoList/go.mod.txt: -------------------------------------------------------------------------------- 1 | module testBadGoList 2 | 3 | go 1.16 4 | 5 | require rsc.io/quote v1.5.2 6 | 7 | require golang.org/x/text v0.3.3 // indirect 8 | -------------------------------------------------------------------------------- /utils/testdata/mods/testBadGoList/go.sum.txt: -------------------------------------------------------------------------------- 1 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 2 | golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= 3 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 4 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 5 | rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= 6 | rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= 7 | rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= 8 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 9 | -------------------------------------------------------------------------------- /utils/testdata/mods/testBadGoList/test.go.txt: -------------------------------------------------------------------------------- 1 | package testBadGoList 2 | 3 | import ( 4 | "fmt" 5 | "rsc.io/quote" 6 | "rscxxxx.ioxxxx/quotexxxx" 7 | ) 8 | 9 | func PrintHello() { 10 | fmt.Println(quote.Hello()) 11 | } 12 | -------------------------------------------------------------------------------- /utils/testdata/mods/testGoList/go.mod.txt: -------------------------------------------------------------------------------- 1 | module testGoList 2 | 3 | go 1.16 4 | 5 | require rsc.io/quote v1.5.2 6 | 7 | require golang.org/x/text v0.3.3 // indirect 8 | -------------------------------------------------------------------------------- /utils/testdata/mods/testGoList/go.sum.txt: -------------------------------------------------------------------------------- 1 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 2 | golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= 3 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 4 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 5 | rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= 6 | rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= 7 | rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= 8 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 9 | -------------------------------------------------------------------------------- /utils/testdata/mods/testGoList/test.go.txt: -------------------------------------------------------------------------------- 1 | package testGoList 2 | 3 | import ( 4 | "fmt" 5 | "rsc.io/quote" 6 | ) 7 | 8 | func PrintHello() { 9 | fmt.Println(quote.Hello()) 10 | } 11 | -------------------------------------------------------------------------------- /utils/testdata/noproject/f: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/utils/testdata/noproject/f -------------------------------------------------------------------------------- /utils/testdata/oneline: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/utils/testdata/oneline -------------------------------------------------------------------------------- /utils/testdata/pip/pyproject/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "pip-project-with-pyproject" 7 | version = "1.2.3" 8 | description = "Project example for building Python project with JFrog products" 9 | authors = [ 10 | { name="JFrog", email="jfrog@jfrog.com" } 11 | ] 12 | dependencies = [ 13 | "PyYAML>3.11", 14 | "nltk" 15 | ] -------------------------------------------------------------------------------- /utils/testdata/pip/requirementsproject/requirements.txt: -------------------------------------------------------------------------------- 1 | PyYAML==5.1.2 2 | macholib==1.11 3 | nltk==3.4.5 -------------------------------------------------------------------------------- /utils/testdata/pip/setuppyproject/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup 4 | 5 | setup( 6 | name='jfrog-python-example', 7 | version='1.0', 8 | description='Project example for building Python project with JFrog products', 9 | author='JFrog', 10 | author_email='jfrog@jfrog.com', 11 | url='https://github.com/jfrog/project-examples', 12 | packages=[], 13 | install_requires=['PyYAML==5.1.2', 'nltk==3.4.5'], 14 | ) -------------------------------------------------------------------------------- /utils/testdata/poetry/nodevdeps/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "my-poetry-project" 3 | version = "1.1.17" 4 | description = "" 5 | authors = ["Severus Snape "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.10" 9 | numpy = "^1.23.0" 10 | 11 | [build-system] 12 | requires = ["poetry-core>=1.0.0"] 13 | build-backend = "poetry.core.masonry.api" 14 | -------------------------------------------------------------------------------- /utils/testdata/poetry/project/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "my-poetry-project" 3 | version = "1.1.0" 4 | description = "" 5 | authors = ["Severus Snape "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.10" 9 | numpy = "^1.23.0" 10 | 11 | [tool.poetry.dev-dependencies] 12 | pytest = "^5.2" 13 | 14 | [build-system] 15 | requires = ["poetry-core>=1.0.0"] 16 | build-backend = "poetry.core.masonry.api" 17 | -------------------------------------------------------------------------------- /utils/testdata/project/dir/f: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/utils/testdata/project/dir/f -------------------------------------------------------------------------------- /utils/testdata/project/go.mod: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrog/build-info-go/5d96a5e3b54f743ae6648f672e7e06950180bd9a/utils/testdata/project/go.mod -------------------------------------------------------------------------------- /utils/testdata/threelines: -------------------------------------------------------------------------------- 1 | 2 | 781d76ae5f48ddd1674161acd90024758fd6e14c {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644222657888,"size":2821,"metadata":{"time":1644222657863,"url":"https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Mon, 07 Feb 2022 08:30:58 GMT","etag":"\"69fd1c7bc68c850139d20aefed955a71\"","last-modified":"Fri, 04 Oct 2019 11:29:17 GMT","vary":"Accept-Encoding"},"options":{"compress":true}}} 3 | -------------------------------------------------------------------------------- /utils/testdata/twolines: -------------------------------------------------------------------------------- 1 | 2 | 781d76ae5f48ddd1674161acd90024758fd6e14c {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz","integrity":"sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==","time":1644222657888,"size":2821,"metadata":{"time":1644222657863,"url":"https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Mon, 07 Feb 2022 08:30:58 GMT","etag":"\"69fd1c7bc68c850139d20aefed955a71\"","last-modified":"Fri, 04 Oct 2019 11:29:17 GMT","vary":"Accept-Encoding"},"options":{"compress":true}}} -------------------------------------------------------------------------------- /utils/utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "regexp" 5 | ) 6 | 7 | func GetRegExp(regex string) (*regexp.Regexp, error) { 8 | regExp, err := regexp.Compile(regex) 9 | if err != nil { 10 | return nil, err 11 | } 12 | return regExp, nil 13 | } 14 | --------------------------------------------------------------------------------