diff --git a/.codacy.yml b/.codacy.yml index 103bc8752..afe83d0e7 100644 --- a/.codacy.yml +++ b/.codacy.yml @@ -1,3 +1,7 @@ --- exclude_paths: - "test/**/*" + - "ci/**/*" + - "contrib/**/*" + - "docs/**/*" + - "types/**/*" diff --git a/.github/workflows/build-base-images.yml b/.github/workflows/build-base-images.yml index b7c8cd45d..aeec370d2 100644 --- a/.github/workflows/build-base-images.yml +++ b/.github/workflows/build-base-images.yml @@ -222,6 +222,160 @@ jobs: tags: ghcr.io/cyclonedx/cdxgen-debian-dotnet6:v11 labels: ${{ steps.meta-cdxgen-debian-dotnet6.outputs.labels }} + debian-ruby33-image: + if: github.repository == 'CycloneDX/cdxgen' + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta-debian-ruby33 + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/cyclonedx/debian-ruby33 + + - name: Build and push Docker images + uses: docker/build-push-action@v5 + with: + context: . + file: ci/base-images/debian/Dockerfile.ruby33 + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta-debian-ruby33.outputs.tags }} + labels: ${{ steps.meta-debian-ruby33.outputs.labels }} + + cdxgen-debian-ruby33-image: + if: github.repository == 'CycloneDX/cdxgen' + runs-on: ubuntu-latest + needs: debian-ruby33-image + permissions: + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta-cdxgen-debian-ruby33 + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/cyclonedx/cdxgen-debian-ruby33 + + - name: Build and push Docker images + uses: docker/build-push-action@v5 + if: github.ref == 'refs/heads/master' + with: + context: . + file: ci/base-images/cdxgen/debian/Dockerfile.ruby33 + platforms: linux/amd64,linux/arm64 + push: true + tags: ghcr.io/cyclonedx/cdxgen-debian-ruby33:v11 + labels: ${{ steps.meta-cdxgen-debian-ruby33.outputs.labels }} + + debian-ruby34-image: + if: github.repository == 'CycloneDX/cdxgen' + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta-debian-ruby34 + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/cyclonedx/debian-ruby34 + + - name: Build and push Docker images + uses: docker/build-push-action@v5 + with: + context: . + file: ci/base-images/debian/Dockerfile.ruby34 + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta-debian-ruby34.outputs.tags }} + labels: ${{ steps.meta-debian-ruby34.outputs.labels }} + + cdxgen-debian-ruby34-image: + if: github.repository == 'CycloneDX/cdxgen' + runs-on: ubuntu-latest + needs: debian-ruby34-image + permissions: + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta-cdxgen-debian-ruby34 + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/cyclonedx/cdxgen-debian-ruby34 + + - name: Build and push Docker images + uses: docker/build-push-action@v5 + if: github.ref == 'refs/heads/master' + with: + context: . + file: ci/base-images/cdxgen/debian/Dockerfile.ruby34 + platforms: linux/amd64,linux/arm64 + push: true + tags: ghcr.io/cyclonedx/cdxgen-debian-ruby34:v11 + labels: ${{ steps.meta-cdxgen-debian-ruby34.outputs.labels }} + sle-dotnet7-image: if: github.repository == 'CycloneDX/cdxgen' runs-on: ubuntu-latest diff --git a/bin/cdxgen.js b/bin/cdxgen.js index be77dabb0..b4d563061 100755 --- a/bin/cdxgen.js +++ b/bin/cdxgen.js @@ -296,7 +296,7 @@ const args = yargs(hideBin(process.argv)) .option("feature-flags", { description: "Experimental feature flags to enable. Advanced users only.", hidden: true, - choices: ["safe-pip-install", "suggest-build-tools"], + choices: ["safe-pip-install", "suggest-build-tools", "ruby-docker-install"], }) .option("min-confidence", { description: diff --git a/ci/Dockerfile b/ci/Dockerfile index a8758430a..f3c207194 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -21,7 +21,7 @@ ARG SBT_VERSION=1.10.7 ARG MAVEN_VERSION=3.9.9 ARG GRADLE_VERSION=8.11 ARG GO_VERSION=1.23.3 -ARG NODE_VERSION=23.5.0 +ARG NODE_VERSION=23.6.0 ARG PYTHON_VERSION=3.12 ARG RUBY_VERSION=3.4.0 diff --git a/ci/base-images/README.md b/ci/base-images/README.md index 22634c071..8b64bb67c 100644 --- a/ci/base-images/README.md +++ b/ci/base-images/README.md @@ -142,6 +142,30 @@ Node.js 20 docker run --rm -e CDXGEN_DEBUG_MODE=debug -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-node20:v11 -r /app -o /app/bom.json -t js ``` +### Ruby applications + +Use the custom image `ghcr.io/cyclonedx/cdxgen-ruby34:v11`. + +Ruby 3.3.6 + +```shell +docker run --rm -e CDXGEN_DEBUG_MODE=debug -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-ruby33:v11 -r /app -o /app/bom.json -t ruby +``` + +Ruby 3.4.1 + +```shell +docker run --rm -e CDXGEN_DEBUG_MODE=debug -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-ruby34:v11 -r /app -o /app/bom.json -t ruby +``` + +Pass any Ruby version with the type argument to make cdxgen automatically install the appropriate version using `rbenv` prior to BOM generation. + +Example: Pass `-t ruby2.5.0` to install Ruby 2.5.0 + +```shell +docker run --rm -e CDXGEN_DEBUG_MODE=debug -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-ruby34:v11 -r /app -o /app/bom.json -t ruby2.5.0 +``` + ## Troubleshooting ### .Net restore crashes diff --git a/ci/base-images/cdxgen/Dockerfile.python b/ci/base-images/cdxgen/Dockerfile.python index f3b53db0b..db47eed6d 100644 --- a/ci/base-images/cdxgen/Dockerfile.python +++ b/ci/base-images/cdxgen/Dockerfile.python @@ -11,7 +11,7 @@ LABEL maintainer="CycloneDX" \ org.opencontainers.image.description="Rolling image with cdxgen SBOM generator for Python 3.12 apps" \ org.opencontainers.docker.cmd="docker run --rm -v /tmp:/tmp -p 9090:9090 -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-python:v11 -r /app --server" -ARG NODE_VERSION=23.5.0 +ARG NODE_VERSION=23.6.0 ENV NVM_DIR="/root/.nvm" \ PYTHON_CMD=python3 \ diff --git a/ci/base-images/cdxgen/debian/Dockerfile.ruby33 b/ci/base-images/cdxgen/debian/Dockerfile.ruby33 new file mode 100644 index 000000000..880581ba5 --- /dev/null +++ b/ci/base-images/cdxgen/debian/Dockerfile.ruby33 @@ -0,0 +1,27 @@ +FROM ghcr.io/cyclonedx/debian-ruby33:master + +LABEL maintainer="CycloneDX" \ + org.opencontainers.image.authors="Team AppThreat " \ + org.opencontainers.image.source="https://github.com/CycloneDX/cdxgen" \ + org.opencontainers.image.url="https://github.com/CycloneDX/cdxgen" \ + org.opencontainers.image.version="rolling" \ + org.opencontainers.image.vendor="AppThreat" \ + org.opencontainers.image.licenses="Apache-2.0" \ + org.opencontainers.image.title="cdxgen" \ + org.opencontainers.image.description="Rolling image with cdxgen SBOM generator for Ruby 3.3 apps" \ + org.opencontainers.docker.cmd="docker run --rm -v /tmp:/tmp -p 9090:9090 -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-debian-ruby33:v11 -r /app --server" + +ENV CDXGEN_IN_CONTAINER=true \ + NODE_COMPILE_CACHE="/opt/cdxgen-node-cache" \ + CDXGEN_GEM_HOME="/tmp/gems" \ + PYTHONPATH=/opt/pypi +ENV PATH=${PATH}:/usr/local/bin:/opt/pypi/bin: + +COPY . /opt/cdxgen + +RUN cd /opt/cdxgen && corepack enable && corepack pnpm install --prod --package-import-method copy && corepack pnpm cache delete \ + && mkdir -p /opt/cdxgen-node-cache \ + && node /opt/cdxgen/bin/cdxgen.js --help \ + && chmod a-w -R /opt + +ENTRYPOINT ["node", "/opt/cdxgen/bin/cdxgen.js"] diff --git a/ci/base-images/cdxgen/debian/Dockerfile.ruby34 b/ci/base-images/cdxgen/debian/Dockerfile.ruby34 new file mode 100644 index 000000000..3d5367c25 --- /dev/null +++ b/ci/base-images/cdxgen/debian/Dockerfile.ruby34 @@ -0,0 +1,27 @@ +FROM ghcr.io/cyclonedx/debian-ruby34:master + +LABEL maintainer="CycloneDX" \ + org.opencontainers.image.authors="Team AppThreat " \ + org.opencontainers.image.source="https://github.com/CycloneDX/cdxgen" \ + org.opencontainers.image.url="https://github.com/CycloneDX/cdxgen" \ + org.opencontainers.image.version="rolling" \ + org.opencontainers.image.vendor="AppThreat" \ + org.opencontainers.image.licenses="Apache-2.0" \ + org.opencontainers.image.title="cdxgen" \ + org.opencontainers.image.description="Rolling image with cdxgen SBOM generator for Ruby apps" \ + org.opencontainers.docker.cmd="docker run --rm -v /tmp:/tmp -p 9090:9090 -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-debian-ruby34:v11 -r /app --server" + +ENV CDXGEN_IN_CONTAINER=true \ + NODE_COMPILE_CACHE="/opt/cdxgen-node-cache" \ + CDXGEN_GEM_HOME="/tmp/gems" \ + PYTHONPATH=/opt/pypi +ENV PATH=${PATH}:/usr/local/bin:/opt/pypi/bin: + +COPY . /opt/cdxgen + +RUN cd /opt/cdxgen && corepack enable && corepack pnpm install --prod --package-import-method copy && corepack pnpm cache delete \ + && mkdir -p /opt/cdxgen-node-cache \ + && node /opt/cdxgen/bin/cdxgen.js --help \ + && chmod a-w -R /opt + +ENTRYPOINT ["node", "/opt/cdxgen/bin/cdxgen.js"] diff --git a/ci/base-images/debian/Dockerfile.dotnet6 b/ci/base-images/debian/Dockerfile.dotnet6 index 2a273d493..c24440f27 100644 --- a/ci/base-images/debian/Dockerfile.dotnet6 +++ b/ci/base-images/debian/Dockerfile.dotnet6 @@ -1,7 +1,7 @@ FROM mcr.microsoft.com/dotnet/sdk:6.0-bookworm-slim ARG JAVA_VERSION=23.0.1-tem -ARG NODE_VERSION=22.12.0 +ARG NODE_VERSION=22.13.0 ENV JAVA_VERSION=$JAVA_VERSION \ JAVA_HOME="/opt/java/${JAVA_VERSION}" \ @@ -14,8 +14,7 @@ ENV JAVA_VERSION=$JAVA_VERSION \ LC_ALL=en_US.UTF-8 \ LANG=en_US.UTF-8 \ LANGUAGE=en_US.UTF-8 \ - NVM_DIR="/root/.nvm" \ - npm_config_python=/usr/bin/python3.11 + NVM_DIR="/root/.nvm" ENV PATH=${PATH}:/root/.nvm/versions/node/v${NODE_VERSION}/bin:${JAVA_HOME}/bin:${MAVEN_HOME}/bin:/usr/local/bin:/root/.local/bin: COPY ci/base-images/debian/install.sh /tmp/ diff --git a/ci/base-images/debian/Dockerfile.dotnet8 b/ci/base-images/debian/Dockerfile.dotnet8 index a4caef51e..0d1a36c6e 100644 --- a/ci/base-images/debian/Dockerfile.dotnet8 +++ b/ci/base-images/debian/Dockerfile.dotnet8 @@ -1,7 +1,7 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0 ARG JAVA_VERSION=23.0.1-tem -ARG NODE_VERSION=23.5.0 +ARG NODE_VERSION=23.6.0 ENV JAVA_VERSION=$JAVA_VERSION \ JAVA_HOME="/opt/java/${JAVA_VERSION}" \ @@ -14,8 +14,7 @@ ENV JAVA_VERSION=$JAVA_VERSION \ LC_ALL=en_US.UTF-8 \ LANG=en_US.UTF-8 \ LANGUAGE=en_US.UTF-8 \ - NVM_DIR="/root/.nvm" \ - npm_config_python=/usr/bin/python3.11 + NVM_DIR="/root/.nvm" ENV PATH=${PATH}:/root/.nvm/versions/node/v${NODE_VERSION}/bin:${JAVA_HOME}/bin:${MAVEN_HOME}/bin:/usr/local/bin:/root/.local/bin: COPY ci/base-images/debian/install.sh /tmp/ diff --git a/ci/base-images/debian/Dockerfile.dotnet9 b/ci/base-images/debian/Dockerfile.dotnet9 index a21686805..6f285841b 100644 --- a/ci/base-images/debian/Dockerfile.dotnet9 +++ b/ci/base-images/debian/Dockerfile.dotnet9 @@ -1,7 +1,7 @@ FROM mcr.microsoft.com/dotnet/sdk:9.0 ARG JAVA_VERSION=23.0.1-tem -ARG NODE_VERSION=23.5.0 +ARG NODE_VERSION=23.6.0 ENV JAVA_VERSION=$JAVA_VERSION \ JAVA_HOME="/opt/java/${JAVA_VERSION}" \ @@ -14,8 +14,7 @@ ENV JAVA_VERSION=$JAVA_VERSION \ LC_ALL=en_US.UTF-8 \ LANG=en_US.UTF-8 \ LANGUAGE=en_US.UTF-8 \ - NVM_DIR="/root/.nvm" \ - npm_config_python=/usr/bin/python3.11 + NVM_DIR="/root/.nvm" ENV PATH=${PATH}:/root/.nvm/versions/node/v${NODE_VERSION}/bin:${JAVA_HOME}/bin:${MAVEN_HOME}/bin:/usr/local/bin:/root/.local/bin: COPY ci/base-images/debian/install.sh /tmp/ diff --git a/ci/base-images/debian/Dockerfile.ruby33 b/ci/base-images/debian/Dockerfile.ruby33 new file mode 100644 index 000000000..94bb53211 --- /dev/null +++ b/ci/base-images/debian/Dockerfile.ruby33 @@ -0,0 +1,26 @@ +FROM ruby:3.3.6 + +ARG JAVA_VERSION=23.0.1-tem +ARG NODE_VERSION=23.6.0 + +ENV JAVA_VERSION=$JAVA_VERSION \ + JAVA_HOME="/opt/java/${JAVA_VERSION}" \ + LC_ALL=en_US.UTF-8 \ + LANG=en_US.UTF-8 \ + LANGUAGE=en_US.UTF-8 \ + NVM_DIR="/root/.nvm" +ENV PATH=${PATH}:/root/.nvm/versions/node/v${NODE_VERSION}/bin:/usr/local/bin:/root/.local/bin:/root/.rbenv/bin: + +COPY ci/base-images/debian/install.sh /tmp/ + +RUN apt-get update && apt-get install -y --no-install-recommends curl bash bzip2 git-core zip unzip make gawk \ + && apt-get install -y build-essential python3 python3-pip python3-dev libmagic-dev \ + && chmod +x /tmp/install.sh \ + && ./tmp/install.sh && rm /tmp/install.sh \ + && node -v \ + && npm -v \ + && gem install bundler \ + && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ + && rm -rf /var/lib/apt/lists/* + +CMD /bin/bash diff --git a/ci/base-images/debian/Dockerfile.ruby34 b/ci/base-images/debian/Dockerfile.ruby34 new file mode 100644 index 000000000..62a0de1b1 --- /dev/null +++ b/ci/base-images/debian/Dockerfile.ruby34 @@ -0,0 +1,26 @@ +FROM ruby:3.4 + +ARG JAVA_VERSION=23.0.1-tem +ARG NODE_VERSION=23.6.0 + +ENV JAVA_VERSION=$JAVA_VERSION \ + JAVA_HOME="/opt/java/${JAVA_VERSION}" \ + LC_ALL=en_US.UTF-8 \ + LANG=en_US.UTF-8 \ + LANGUAGE=en_US.UTF-8 \ + NVM_DIR="/root/.nvm" +ENV PATH=${PATH}:/root/.nvm/versions/node/v${NODE_VERSION}/bin:/usr/local/bin:/root/.local/bin:/root/.rbenv/bin: + +COPY ci/base-images/debian/install.sh /tmp/ + +RUN apt-get update && apt-get install -y --no-install-recommends curl bash bzip2 git-core zip unzip make gawk \ + && apt-get install -y build-essential python3 python3-pip python3-dev libmagic-dev \ + && chmod +x /tmp/install.sh \ + && ./tmp/install.sh && rm /tmp/install.sh \ + && node -v \ + && npm -v \ + && gem install bundler \ + && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ + && rm -rf /var/lib/apt/lists/* + +CMD /bin/bash diff --git a/ci/base-images/debian/install.sh b/ci/base-images/debian/install.sh index 0ea32bfe9..dcc266414 100644 --- a/ci/base-images/debian/install.sh +++ b/ci/base-images/debian/install.sh @@ -1,5 +1,12 @@ #! /usr/bin/env bash +git clone https://github.com/rbenv/rbenv.git --depth=1 ~/.rbenv +echo 'export PATH="/root/.rbenv/bin:$PATH"' >> ~/.bashrc +echo 'eval "$(/root/.rbenv/bin/rbenv init - bash)"' >> ~/.bashrc +source ~/.bashrc +mkdir -p "$(rbenv root)/plugins" +git clone https://github.com/rbenv/ruby-build.git --depth=1 "$(rbenv root)/plugins/ruby-build" + curl -s "https://get.sdkman.io" | bash chmod +x /root/.sdkman/bin/sdkman-init.sh source $HOME/.sdkman/bin/sdkman-init.sh @@ -13,6 +20,7 @@ fi sdk offline enable mv /root/.sdkman/candidates/* /opt/ rm -rf /root/.sdkman + python3 -m pip install --no-cache-dir --upgrade pip virtualenv python3 -m pip install --no-cache-dir --upgrade --user pipenv poetry uv curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash diff --git a/ci/base-images/sle/Dockerfile.lang b/ci/base-images/sle/Dockerfile.lang index 8c8dfe070..e9a2d3ae7 100644 --- a/ci/base-images/sle/Dockerfile.lang +++ b/ci/base-images/sle/Dockerfile.lang @@ -3,7 +3,7 @@ FROM registry.suse.com/bci/python:3.12 ARG JAVA_VERSION=23.0.1-tem ARG MAVEN_VERSION=3.9.9 ARG GCC_VERSION=13 -ARG NODE_VERSION=23.5.0 +ARG NODE_VERSION=23.6.0 ENV JAVA_VERSION=$JAVA_VERSION \ MAVEN_VERSION=$MAVEN_VERSION \ diff --git a/data/frameworks-list.json b/data/frameworks-list.json index ef7dffdf9..fb3c6e062 100644 --- a/data/frameworks-list.json +++ b/data/frameworks-list.json @@ -191,6 +191,16 @@ "pkg:composer/roducks", "pkg:composer/queryphp", "pkg:composer/silex", - "pkg:composer/psr" + "pkg:composer/psr", + "pkg:gem/rails", + "pkg:gem/sinatra", + "pkg:gem/hanami", + "pkg:gem/padrino", + "pkg:gem/cuba", + "pkg:gem/grape", + "pkg:gem/volt", + "pkg:gem/trailblazer", + "pkg:gem/ramaze", + "pkg:gem/scorched" ] } diff --git a/docs/PROJECT_TYPES.md b/docs/PROJECT_TYPES.md index f95622ebc..99ad22bfd 100644 --- a/docs/PROJECT_TYPES.md +++ b/docs/PROJECT_TYPES.md @@ -26,7 +26,8 @@ _Note: there are multiple project types / aliases that will produce the same out | Python (Specific version) | `python36`, `python38`, `python39`, `python310`, `python311`, `python312` | `pyproject.toml`, `setup.py`, `requirements.txt` [2], `Pipfile.lock`, `poetry.lock`, `pdm.lock`, `bdist_wheel`, `.whl`, `.egg-info` | Yes using the automatic pip install/freeze. When disabled, only with `Pipfile.lock`, `pdm.lock`, `uv.lock`, and `poetry.lock` | - | | Golang | `go`, `golang` | `binary`, `go.mod`, `go.sum`, `Gopkg.lock` | Yes except binary | ✅ | | Rust | `rust`, `rust-lang`, `cargo` | `binary`, `Cargo.toml`, `Cargo.lock` | Only for `Cargo.lock` | - | -| Ruby | `ruby`, `gems` | `Gemfile.lock`, `gemspec` | Only for `Gemfile.lock` | - | +| Ruby | `ruby`, `gems`, `rubygems`, `bundler`, `rb`, `gemspec` | `Gemfile.lock`, `gemspec` | Only for `Gemfile.lock` | - | +| Ruby (Specific version) | `ruby*`. Example: ruby2.5.4, ruby3.4.0 | `Gemfile.lock`, `gemspec` | Only for `Gemfile.lock` | - | | PHP | `php`, `composer` | Composer.lock | Yes | ✅ | | .NET (#C) | `csharp`, `netcore`, `dotnet`, `vb`, `dotnet-framework` | `.csproj`, `.vbproj`, `.fsproj`, `packages.config`, `project.assets.json` [3], `packages.lock.json`, `.nupkg`, `paket.lock`, `binary` | Only for `project.assets.json`, `packages.lock.json`, `paket.lock` | - | | Dart | `dart`, `flutter`, `pub` | `pubspec.lock`, `pubspec.yaml` | Only for `pubspec.lock` | - | @@ -55,6 +56,7 @@ _*NOTE:*_ > - Alternatively, create a lock file using sbt-dependency-lock [plugin](https://github.com/stringbean/sbt-dependency-lock) > - sdkman must be installed and setup to use the new Java with version types such as java8, java11. > - While python3.6 is supported (-t python36), dependency tree construction requires python >= 3.9 +> - rbenv must be installed and setup to use the new Ruby with version types such as ruby2.5.4, ruby3.4.0 Use of the container image is recommended in all these cases, since it has the build tools pre-installed. diff --git a/lib/cli/index.js b/lib/cli/index.js index 7c10b32f2..d0279fbaa 100644 --- a/lib/cli/index.js +++ b/lib/cli/index.js @@ -49,6 +49,7 @@ import { buildObjectForGradleModule, checksumFile, cleanupPlugin, + collectGemModuleNames, collectGradleDependencies, collectJarNS, collectMvnDependencies, @@ -105,6 +106,7 @@ import { parseCsProjData, parseEdnData, parseGemfileLockData, + parseGemspecData, parseGitHubWorkflowData, parseGoListDep, parseGoModData, @@ -2419,7 +2421,7 @@ export async function createNodejsBom(path, options) { if (DEBUG_MODE && result.stdout) { if (result.stdout.includes("EBADENGINE Unsupported engine")) { console.log( - "Try using the custom `ghcr.io/cyclonedx/cdxgen-node20:v11` container image, which bundles node.js 20. The current version of node.js is incompatible for this project.", + "TIP: Try using the custom `ghcr.io/cyclonedx/cdxgen-node20:v11` container image, which bundles node.js 20. The current version of node.js is incompatible for this project.", ); console.log( "Alternatively, run cdxgen with the custom node with version types. Eg: `-t node20`", @@ -2449,12 +2451,12 @@ export async function createNodejsBom(path, options) { ); } else { console.log( - "Try using the custom `ghcr.io/cyclonedx/cdxgen-node20:v11` container image, which bundles node.js 20. The default image bundles node >= 23, which might be incompatible.", + "TIP: Try using the custom `ghcr.io/cyclonedx/cdxgen-node20:v11` container image, which bundles node.js 20. The default image bundles node >= 23, which might be incompatible.", ); } } else { console.log( - "Try using the custom `ghcr.io/cyclonedx/cdxgen-node20:v11` container image with --platform=linux/amd64, which bundles node.js 20.", + "TIP: Try using the custom `ghcr.io/cyclonedx/cdxgen-node20:v11` container image with --platform=linux/amd64, which bundles node.js 20.", ); } } @@ -5154,6 +5156,26 @@ export async function createRubyBom(path, options) { `${options.multiProject ? "**/" : ""}Gemfile*.lock`, options, ); + let gemspecFiles = getAllFiles( + path, + `${options.multiProject ? "**/" : ""}*.gemspec`, + options, + ); + const gemHome = process.env.CDXGEN_GEM_HOME || process.env.GEM_HOME; + let isGemHomeEmpty = true; + // In deep mode, let's collect all gems that got installed in our custom GEM_HOME directory. + // This would improve the accuracy of any security analysis downstream at cost of a slight increase in time. + if (options.deep && process.env.CDXGEN_GEM_HOME) { + const gemHomeSpecFiles = getAllFiles( + process.env.CDXGEN_GEM_HOME, + "**/specifications/**/*.gemspec", + options, + ); + if (gemHomeSpecFiles?.length) { + isGemHomeEmpty = false; + gemspecFiles = gemspecFiles.concat(gemHomeSpecFiles); + } + } let pkgList = []; let dependencies = []; let rootList = []; @@ -5205,6 +5227,23 @@ export async function createRubyBom(path, options) { } } } + // Parsing .gemspec files would help us get more metadata such as description, authors, licenses etc + if (gemspecFiles.length) { + if (!gemLockFiles.length && !hasAnyProjectType(["oci"], options, false)) { + console.log( + "SBOM generation using only gemspec files is imprecise and results in an inaccurate dependency tree.", + ); + options.failOnError && process.exit(1); + } + for (const f of gemspecFiles) { + const gemspecData = readFileSync(f, { encoding: "utf-8" }); + const gpkgList = await parseGemspecData(gemspecData, f); + if (gpkgList.length) { + pkgList = pkgList.concat(gpkgList); + pkgList = trimComponents(pkgList); + } + } + } if (rootList.length) { dependencies = mergeDependencies( dependencies, @@ -5217,6 +5256,59 @@ export async function createRubyBom(path, options) { parentComponent, ); } + // Should we collect the module names for the gems + if (options.resolveClass || options.deep) { + if (gemHome && !isGemHomeEmpty) { + const rubyCommand = + process.env.CDXGEN_RUBY_CMD || process.env.RUBY_CMD || "ruby"; + const bundleCommand = process.env.CDXGEN_BUNDLE_CMD || "bundle"; + let emptyCount = 0; + let atleastOneHit = false; + console.log( + `About the collect the module names for ${pkgList.length} gems. This would take a while ...`, + ); + for (const apkg of pkgList) { + if (!apkg.name || !apkg.version || apkg.name.startsWith("/")) { + continue; + } + const moduleNames = collectGemModuleNames( + rubyCommand, + bundleCommand, + gemHome, + apkg.name, + path, + ); + if (moduleNames.length) { + emptyCount = 0; + atleastOneHit = true; + if (!apkg.properties) { + apkg.properties = []; + } + apkg.properties.push({ + name: "Namespaces", + value: moduleNames.join(", "), + }); + } else { + emptyCount++; + } + // Circuit breaker + if (!atleastOneHit && emptyCount >= 5) { + console.log( + "Unable to collect the module names for all the gems. Resolve the errors reported and re-run cdxgen.", + ); + break; + } + } + // Clean up + if (process.env?.CDXGEN_GEM_HOME?.startsWith(tmpdir())) { + rmSync(process.env.CDXGEN_GEM_HOME, { recursive: true, force: true }); + } + } else { + console.log( + "Set the environment variable CDXGEN_GEM_HOME or GEM_HOME to collect the module names for installed gems.", + ); + } + } return buildBomNSData(options, pkgList, "gem", { src: path, dependencies, @@ -5348,7 +5440,7 @@ export async function createCsharpBom(path, options) { "This project requires a specific version of dotnet sdk to be installed. The cdxgen container image bundles dotnet SDK 8.0, which might be incompatible.", ); console.log( - "Try using the custom `ghcr.io/cyclonedx/cdxgen-dotnet6:v11` or `ghcr.io/cyclonedx/cdxgen-dotnet7:v11` container images.", + "TIP: Try using the custom `ghcr.io/cyclonedx/cdxgen-dotnet6:v11` or `ghcr.io/cyclonedx/cdxgen-dotnet7:v11` container images.", ); } else { console.error( @@ -6783,16 +6875,25 @@ export async function createBom(path, options) { return await createMultiXBom(path, options); } // Use the project type alias to return any singular BOM - if (PROJECT_TYPE_ALIASES["java"].includes(projectType[0])) { + if ( + PROJECT_TYPE_ALIASES["java"].includes(projectType[0]) || + projectType?.[0]?.startsWith("java") + ) { return await createJavaBom(path, options); } if (PROJECT_TYPE_ALIASES["android"].includes(projectType[0])) { return createAndroidBom(path, options); } - if (PROJECT_TYPE_ALIASES["js"].includes(projectType[0])) { + if ( + PROJECT_TYPE_ALIASES["js"].includes(projectType[0]) || + projectType?.[0]?.startsWith("node") + ) { return await createNodejsBom(path, options); } - if (PROJECT_TYPE_ALIASES["py"].includes(projectType[0])) { + if ( + PROJECT_TYPE_ALIASES["py"].includes(projectType[0]) || + projectType?.[0]?.startsWith("python") + ) { return await createPythonBom(path, options); } if (PROJECT_TYPE_ALIASES["go"].includes(projectType[0])) { @@ -6804,7 +6905,10 @@ export async function createBom(path, options) { if (PROJECT_TYPE_ALIASES["php"].includes(projectType[0])) { return createPHPBom(path, options); } - if (PROJECT_TYPE_ALIASES["ruby"].includes(projectType[0])) { + if ( + PROJECT_TYPE_ALIASES["ruby"].includes(projectType[0]) || + projectType?.[0]?.startsWith("ruby") + ) { return await createRubyBom(path, options); } if (PROJECT_TYPE_ALIASES["csharp"].includes(projectType[0])) { diff --git a/lib/evinser/swiftsem.js b/lib/evinser/swiftsem.js index 068f52e22..206a6c7b2 100644 --- a/lib/evinser/swiftsem.js +++ b/lib/evinser/swiftsem.js @@ -583,7 +583,7 @@ export function createSemanticsSlices(basePath, options) { } if (!sdkArgs) { console.log( - "Unable to detect the swift sdk needed to build this project. Try running the swift build command to check if this project builds successfully.", + "TIP: Unable to detect the swift sdk needed to build this project. Try running the swift build command to check if this project builds successfully.", ); return; } diff --git a/lib/helpers/envcontext.js b/lib/helpers/envcontext.js index e03574312..2d22a2f86 100644 --- a/lib/helpers/envcontext.js +++ b/lib/helpers/envcontext.js @@ -1,9 +1,10 @@ import { Buffer } from "node:buffer"; import { spawnSync } from "node:child_process"; import { existsSync } from "node:fs"; -import { homedir } from "node:os"; +import { arch, homedir, tmpdir } from "node:os"; import { delimiter, dirname, join } from "node:path"; import process from "node:process"; +import { compareLoose } from "semver"; import { CARGO_CMD, DEBUG_MODE, @@ -13,11 +14,13 @@ import { MAX_BUFFER, NODE_CMD, NPM_CMD, + RUBY_CMD, RUSTC_CMD, SWIFT_CMD, TIMEOUT_MS, getJavaCommand, getPythonCommand, + isMac, isWin, } from "./utils.js"; @@ -307,6 +310,24 @@ export function collectSwiftInfo(dir) { return undefined; } +/** + * Collect Ruby version + * + * @param {string} dir Working directory + * @returns Object containing Ruby details + */ +export function collectRubyInfo(dir) { + const versionDesc = getCommandOutput(RUBY_CMD, dir, ["--version"]); + if (versionDesc) { + return { + type: "platform", + name: "ruby", + version: versionDesc.trim(), + }; + } + return undefined; +} + /** * Method to run a swift command * @@ -348,6 +369,10 @@ export function collectEnvInfo(dir) { if (cmp) { infoComponents.push(cmp); } + cmp = collectRubyInfo(dir); + if (cmp) { + infoComponents.push(cmp); + } return infoComponents; } @@ -413,15 +438,15 @@ export function isSdkmanAvailable() { * Method to check if nvm is available. */ export function isNvmAvailable() { - let isNvmSetup = false; - const result = spawnSync(process.env.SHELL || "bash", ["-i", "-c", "nvm"], { - encoding: "utf-8", - shell: process.env.SHELL || true, - }); - if (result.status === 0) { - isNvmSetup = true; - } - return isNvmSetup; + const result = spawnSync( + process.env.SHELL || "bash", + ["-i", "-c", process.env.NVM_CMD || "nvm"], + { + encoding: "utf-8", + shell: process.env.SHELL || true, + }, + ); + return result.status === 0; } /** @@ -636,3 +661,357 @@ export function getOrInstallNvmTool(toolVersion) { function getSdkmanToolFullname(toolName) { return SDKMAN_JAVA_TOOL_ALIASES[toolName] || toolName; } + +/** + * Method to check if rbenv is available. + * + * @returns {Boolean} true if rbenv is available. false otherwise. + */ +export function isRbenvAvailable() { + let result = spawnSync( + process.env.SHELL || "bash", + ["-i", "-c", process.env.RBENV_CMD || "rbenv", "--version"], + { + encoding: "utf-8", + shell: process.env.SHELL || true, + timeout: TIMEOUT_MS, + }, + ); + if (result.status !== 0) { + result = spawnSync(process.env.RBENV_CMD || "rbenv", ["--version"], { + shell: isWin, + encoding: "utf-8", + }); + return result.status === 0; + } +} + +export function rubyVersionDir(rubyVersion) { + return process.env.RBENV_ROOT + ? join(process.env.RBENV_ROOT, "versions", rubyVersion, "bin") + : join(homedir(), ".rbenv", "versions", rubyVersion, "bin"); +} + +/** + * Perform bundle install using Ruby container images. Not working cleanly yet. + * + * @param rubyVersion Ruby version + * @param cdxgenGemHome Gem Home + * @param filePath Path + */ +export function bundleInstallWithDocker(rubyVersion, cdxgenGemHome, filePath) { + const ociCmd = process.env.DOCKER_CMD || "docker"; + const ociArgs = [ + "run", + "--rm", + "-e", + "GEM_HOME=/gems", + "-v", + `/tmp:${tmpdir()}:rw`, + "-v", + `${filePath}:/app:rw`, + "-v", + `${cdxgenGemHome}:/gems:rw`, + "-w", + "/app", + "-it", + `docker.io/ruby:${rubyVersion}`, + "bash", + "-c", + "bundle", + "install", + ]; + console.log(`Performing bundle install with: ${ociCmd} ${ociArgs.join(" ")}`); + const result = spawnSync(ociCmd, ociArgs, { + encoding: "utf-8", + shell: isWin, + timeout: TIMEOUT_MS, + stdio: "inherit", + }); + if (result.error || result.status !== 0) { + return false; + } + if (existsSync(join(filePath, "Gemfile.lock"))) { + console.log( + "Gemfile.lock was generated successfully. Thank you for trying this feature!", + ); + } + return result.status === 0; +} + +/** + * Install a particular ruby version using rbenv. + * + * @param rubyVersion Ruby version to install + * @param filePath File path + */ +export function installRubyVersion(rubyVersion, filePath) { + const existingRuby = collectRubyInfo(filePath); + if (existingRuby?.version?.startsWith(`ruby ${rubyVersion} `)) { + return { fullToolBinDir: undefined, status: true }; + } + const fullToolBinDir = rubyVersionDir(rubyVersion); + if (existsSync(fullToolBinDir)) { + const result = spawnSync( + process.env.RBENV_CMD || "rbenv", + ["local", rubyVersion], + { + encoding: "utf-8", + shell: isWin, + timeout: TIMEOUT_MS, + }, + ); + if (result.error || result.status !== 0) { + if (result.stdout) { + console.log(result.stdout); + } + if (result.stderr) { + console.log(result.stderr); + } + } + if (result.status === 0) { + return { fullToolBinDir, status: true }; + } + } + console.log( + `Attempting to install Ruby ${rubyVersion} using rbenv. This might take a while ...`, + ); + const result = spawnSync( + process.env.RBENV_CMD || "rbenv", + ["install", rubyVersion], + { + encoding: "utf-8", + shell: isWin, + timeout: TIMEOUT_MS, + }, + ); + if (result.error || result.status !== 0) { + if (result.stdout) { + console.log(result.stdout); + } + if (result.stderr) { + console.log(result.stderr); + } + if (isMac) { + console.log( + "Try running the commands `sudo xcode-select --install` followed by `xcodebuild -runFirstLaunch`.", + ); + } + if (process.env?.CDXGEN_IN_CONTAINER === "true") { + console.log( + "Are there any devel packages that could be included in the cdxgen container image to avoid these errors? Start a discussion thread here: https://github.com/CycloneDX/cdxgen/discussions", + ); + } else { + console.log( + `TIP: Try using the custom container image "ghcr.io/cyclonedx/cdxgen-debian-ruby34" with the argument "-t ruby${rubyVersion}"`, + ); + } + } + return { fullToolBinDir, status: result.status === 0 }; +} + +/** + * Method to install bundler using gem. + * + * @param rubyVersion Ruby version + * @param bundlerVersion Bundler version + */ +export function installRubyBundler(rubyVersion, bundlerVersion) { + const minRubyVersion = "3.1.0"; + let bundlerWarningShown = false; + if (!bundlerVersion && compareLoose(rubyVersion, minRubyVersion) === -1) { + console.log( + `Default installation for bundler requires Ruby >= ${minRubyVersion}. Attempting to detect and install an older version of bundler for Ruby ${rubyVersion}.`, + ); + bundlerWarningShown = true; + } + const fullToolBinDir = rubyVersionDir(rubyVersion); + if (existsSync(fullToolBinDir)) { + const gemInstallArgs = ["install", "bundler"]; + if (bundlerVersion) { + gemInstallArgs.push("-v"); + gemInstallArgs.push(bundlerVersion); + } + if (!bundlerWarningShown) { + if (bundlerVersion) { + console.log( + `Installing bundler ${bundlerVersion} using ${join(fullToolBinDir, "gem")}`, + ); + } else { + console.log( + `Installing bundler using ${join(fullToolBinDir, "gem")} ${gemInstallArgs.join(" ")}`, + ); + } + } + const result = spawnSync(join(fullToolBinDir, "gem"), gemInstallArgs, { + encoding: "utf-8", + shell: isWin, + timeout: TIMEOUT_MS, + }); + if (bundlerWarningShown) { + if (result.stderr?.includes("Try installing it with")) { + const oldBundlerVersion = result.stderr + .split("`\n")[0] + .split("Try installing it with `") + .pop() + .split(" ") + .pop() + .replaceAll("`", ""); + if (/^\d+/.test(oldBundlerVersion)) { + console.log( + `The last version of bundler to support your Ruby & RubyGems was ${oldBundlerVersion}. cdxgen will now attempt to install this version.`, + ); + return installRubyBundler(rubyVersion, oldBundlerVersion); + } + } + } else { + if (result.error || result.status !== 0) { + if (result.stdout) { + console.log(result.stdout); + } + if (result.stderr) { + console.log(result.stderr); + } + } + return result.status === 0; + } + } + return false; +} + +/** + * Method to perform bundle install + * + * @param cdxgenGemHome cdxgen Gem home + * @param rubyVersion Ruby version + * @param bundleCommand Bundle command to use + * @param basePath working directory + * + * @returns {boolean} true if the install was successful. false otherwise. + */ +export function performBundleInstall( + cdxgenGemHome, + rubyVersion, + bundleCommand, + basePath, +) { + if (arch() !== "x64") { + console.log( + `INFO: Many Ruby packages have limited support for ${arch()} architecture.\nRun the cdxgen container image with --platform=linux/amd64 for best experience.`, + ); + } + let installArgs = ["install"]; + if (process.env.BUNDLE_INSTALL_ARGS) { + installArgs = installArgs.concat( + process.env.BUNDLE_INSTALL_ARGS.split(" "), + ); + } + console.log( + `Invoking ${bundleCommand} ${installArgs.join(" ")} from ${basePath} with GEM_HOME ${cdxgenGemHome}. Please wait ...`, + ); + let result = spawnSync(bundleCommand, installArgs, { + encoding: "utf-8", + shell: isWin, + timeout: TIMEOUT_MS, + cwd: basePath, + env: { + ...process.env, + GEM_HOME: cdxgenGemHome, + }, + }); + if (result.error || result.status !== 0) { + let pythonWarningShown = false; + if (result?.stderr?.includes("requires python 2 to be installed")) { + pythonWarningShown = true; + console.log( + "A native module requires python 2 to be installed. Please install python 2.7.18 from https://www.python.org/downloads/release/python-2718/.", + ); + console.log( + "NOTE: Python 2.7.x has now reached end-of-life. Python 2.7.18, is the FINAL RELEASE of Python 2.7.x. It will no longer be supported or updated. You should stop using this project in production and decommission immediately.", + ); + console.log( + "Further, the project might need older versions of gcc and other build tools which might not be readily available in this environment.", + ); + if (process.env?.CDXGEN_IN_CONTAINER === "true") { + console.log( + "cdxgen container images do not bundle Python 2. Run cdxgen in cli mode to proceed with the SBOM generation.", + ); + } + console.log( + "Alternatively, ensure Gemfile.lock is present locally and invoke cdxgen with the argument `--lifecycle pre-build`.", + ); + } + if (result?.stderr?.includes("Running `bundle update ")) { + console.log( + "Gemfile.lock appears to be outdated. Attempting automated update.", + ); + const packageToUpdate = result.stderr + .split("Running `bundle update ") + .pop() + .split("`")[0]; + let updateArgs = ["update"]; + if (packageToUpdate?.length && !packageToUpdate.includes(" ")) { + updateArgs.push(packageToUpdate); + } + if (process.env.BUNDLE_UPDATE_ARGS) { + updateArgs = updateArgs.concat( + process.env.BUNDLE_UPDATE_ARGS.split(" "), + ); + } + console.log(`${bundleCommand} ${updateArgs.join(" ")}`); + result = spawnSync(bundleCommand, updateArgs, { + encoding: "utf-8", + shell: isWin, + timeout: TIMEOUT_MS, + cwd: basePath, + env: { + ...process.env, + GEM_HOME: cdxgenGemHome, + }, + }); + if (result.error || result.status !== 0) { + console.log("------------"); + if (result.stdout) { + console.log(result.stdout); + } + if (result.stderr) { + console.log(result.stderr); + } + console.log("------------"); + } + return result.status === 0; + } + if ( + !pythonWarningShown && + (result?.stderr?.includes("Failed to build gem native extension") || + result?.stderr?.includes("Gem::Ext::BuildError")) + ) { + console.log( + "Bundler failed to build some gem native extension(s). Carefully review the below error to install any required development libraries.", + ); + } + console.log("------------"); + if (result.stdout) { + console.log(result.stdout); + } + if (result.stderr) { + console.log(result.stderr); + } + console.log("------------"); + if (process.env?.CDXGEN_IN_CONTAINER === "true") { + console.log( + "Are there any devel packages that could be included in the cdxgen container image to avoid these errors? Start a discussion thread here: https://github.com/CycloneDX/cdxgen/discussions", + ); + console.log("------------"); + } else if (rubyVersion) { + console.log( + `TIP: Try using the custom container image "ghcr.io/cyclonedx/cdxgen-debian-ruby34" with the argument "-t ruby${rubyVersion}".`, + ); + } else { + console.log( + `TIP: Try invoking cdxgen with a Ruby version type. With the custom container image "ghcr.io/cyclonedx/cdxgen-debian-ruby34", you can pass the argument "-t ruby". Example: "-t ruby3.3.6"`, + ); + } + } + return result.status === 0; +} diff --git a/lib/helpers/utils.js b/lib/helpers/utils.js index 6bdb5049b..ca346bd43 100644 --- a/lib/helpers/utils.js +++ b/lib/helpers/utils.js @@ -239,6 +239,8 @@ if (process.env.LEIN_CMD) { export const SWIFT_CMD = process.env.SWIFT_CMD || isMac ? "xcrun swift" : "swift"; +export const RUBY_CMD = process.env.RUBY_CMD || "ruby"; + // Python components that can be excluded export const PYTHON_EXCLUDED_COMPONENTS = [ "pip", @@ -333,7 +335,7 @@ export const PROJECT_TYPE_ALIASES = { go: ["go", "golang", "gomod", "gopkg"], rust: ["rust", "rust-lang", "cargo"], php: ["php", "composer", "wordpress"], - ruby: ["ruby", "gems", "rubygems"], + ruby: ["ruby", "gems", "rubygems", "bundler", "rb", "gemspec"], csharp: [ "csharp", "netcore", @@ -460,6 +462,10 @@ export function hasAnyProjectType(projectTypes, options, defaultStatus = true) { const allProjectTypes = [...projectTypes]; // Convert the project types into base types const baseProjectTypes = []; + // Support for arbitray versioned ruby type + if (projectTypes.filter((p) => p.startsWith("ruby")).length) { + baseProjectTypes.push("ruby"); + } const baseExcludeTypes = []; for (const abt of Object.keys(PROJECT_TYPE_ALIASES)) { if ( @@ -6154,37 +6160,291 @@ export async function getRubyGemsMetadata(pkgList) { return rdepList; } +function _upperFirst(string) { + return string.slice(0, 1).toUpperCase() + string.slice(1, string.length); +} + +/** + * Utility method to convert a gem package name to a CamelCased module name. Low accuracy. + * + * @param name Package name + */ +export function toGemModuleNames(name) { + const modList = name.split("-").map((s) => { + return s + .split("_") + .map((str) => { + return _upperFirst(str.split("/").map(_upperFirst).join("/")); + }) + .join(""); + }); + const moduleNames = []; + let prefix = ""; + for (const amod of modList) { + if (amod !== "Ruby") { + moduleNames.push(`${prefix}${amod}`); + } + prefix = prefix?.length ? `${prefix}${amod}::` : `${amod}::`; + // ruby-prof is RubyProf + if (prefix === "Ruby::") { + prefix = "Ruby"; + } + } + return moduleNames; +} + /** - * Method to parse Gemspec + * Collect all namespaces for a given gem present at the given gemHome + * + * @param {String} rubyCommand Ruby command to use if bundle is not available + * @param {String} bundleCommand Bundle command to use + * @param {String} gemHome Value to use as GEM_HOME env variable + * @param {String} gemName Name of the gem + * @param {String} filePath File path + * + * @returns {Array} List of module names + */ +export function collectGemModuleNames( + rubyCommand, + bundleCommand, + gemHome, + gemName, + filePath, +) { + gemHome = gemHome || process.env.CDXGEN_GEM_HOME || process.env.GEM_HOME; + if (!gemHome) { + console.log( + "Set the environment variable CDXGEN_GEM_HOME or GEM_HOME to collect the gem module names.", + ); + return []; + } + if (!gemName || gemName.startsWith("/")) { + return []; + } + const moduleNames = new Set(); + const commandToUse = bundleCommand || rubyCommand; + let args = bundleCommand ? ["exec", "ruby"] : []; + args = args.concat([ + "-e", + `initial = ObjectSpace.each_object(Module).map { |m| m.respond_to?(:name) ? m.name : nil }.compact; + require '${gemName}'; + begin + afterwards = ObjectSpace.each_object(Module).map { |m| m.respond_to?(:name) ? m.name : nil }.compact; + added = afterwards - initial; + puts added.sort + rescue NoMethodError => e + puts "" + end + `, + ]); + const result = spawnSync(commandToUse, args, { + encoding: "utf-8", + shell: isWin, + timeout: 5000, + cwd: filePath, + env: { + ...process.env, + GEM_HOME: gemHome, + }, + }); + if (result.error || result.status !== 0) { + // Let's retry for simple mismatches + if (gemName?.includes("-")) { + return collectGemModuleNames( + bundleCommand, + gemHome, + gemName.replaceAll("-", "/"), + filePath, + ); + } + // bundle can sometimes offer suggestions for simple mismatches. Let's try that. + if (result?.stderr?.includes("Did you mean?")) { + const altGemName = result.stderr + .split("Did you mean? ")[1] + .split("\n")[0] + .trim(); + if (altGemName?.length && !altGemName.startsWith("/")) { + return collectGemModuleNames( + bundleCommand, + gemHome, + altGemName, + filePath, + ); + } + } + if (DEBUG_MODE) { + console.log( + `Unable to collect the module names exported by the gem ${gemName}.`, + ); + } + if (result?.stderr?.includes("Bundler::GemNotFound")) { + return []; + } + // Let's guess the module name based on common naming convention. + return toGemModuleNames(gemName); + } + const simpleModuleNames = new Set(); + for (const aline of result.stdout.split("\n")) { + if ( + !aline?.length || + aline.startsWith("Ignoring ") || + aline.includes("cannot load such file") || + aline.startsWith("#<") + ) { + continue; + } + if (!aline.includes("::")) { + simpleModuleNames.add(aline.trim()); + continue; + } + moduleNames.add(aline.trim()); + } + return moduleNames.size + ? Array.from(moduleNames).sort() + : Array.from(simpleModuleNames).sort(); +} + +/** + * Method to parse Gemspec file contents * * @param {string} gemspecData Gemspec data + * @param {string} gemspecFile File name for evidence. */ -export async function parseGemspecData(gemspecData) { +export async function parseGemspecData(gemspecData, gemspecFile) { let pkgList = []; - const pkg = {}; + const pkg = { properties: [] }; + if (gemspecFile) { + pkg.name = basename(gemspecFile).replace(".gemspec", ""); + } if (!gemspecData) { return pkgList; } + let versionHackMatch = false; gemspecData.split("\n").forEach((l) => { - l = l.trim(); - if (l.includes(".name = ")) { - pkg.name = l - .split(".name = ")[1] - .replace(".freeze", "") - .replace(/"/g, ""); - } else if (l.includes(".version = ")) { - pkg.version = l - .split(".version = ")[1] - .replace(".freeze", "") - .replace(/"/g, ""); - } else if (l.includes(".description = ")) { - pkg.description = l - .split(".description = ")[1] - .replace(".freeze", "") - .replace(/"/g, ""); + l = l.replace("\r", ""); + l = l.replace(/\s+/g, " ").replaceAll("%q{", "").trim().replace(/}$/, ""); + if (l.startsWith("#")) { + return; + } + for (const aprop of ["name", "version", "description", "homepage"]) { + if (l.includes(`.${aprop} = `)) { + pkg[aprop] = l + .split(`.${aprop} = `)[1] + .replace(".freeze", "") + .replaceAll("''', ", "") + .replace(/"/g, ""); + return; + } + } + // Cleanup bad version strings + if (pkg?.version?.includes("::")) { + pkg.version = undefined; + // Can we find the version from the directory name? + if (gemspecFile) { + const versionFromDir = dirname(gemspecFile).split("-").pop(); + if (/\d/.test(versionFromDir)) { + pkg.version = versionFromDir; + versionHackMatch = true; + } + } + } + for (const aprop of ["authors", "licenses"]) { + if (l.includes(`.${aprop} = `)) { + try { + const pline = l + .split(`.${aprop} = `) + .pop() + .replaceAll(".freeze", "") + .replaceAll("%w", "") + .replaceAll("'", '"') + .replaceAll(']"', ""); + const apropList = JSON.parse(pline); + if (apropList) { + if (Array.isArray(apropList)) { + pkg[aprop] = apropList; + } else if ( + typeof apropList === "string" || + apropList instanceof String + ) { + pkg[aprop] = apropList.split(","); + } + } + } catch (err) { + const alist = l + .replace(/[[\]'"]/g, "") + .replaceAll("%w", "") + .split(", "); + if (alist?.length) { + pkg[aprop] = alist; + } + } + } + } + if (l.includes(".executables = ")) { + try { + const exeList = JSON.parse( + l + .split(".executables = ") + .pop() + .replaceAll(".freeze", "") + .replaceAll("'", '"') + .replaceAll(']"', ""), + ); + if (exeList && Array.isArray(exeList)) { + pkg.properties.push({ + name: "cdx:gem:executables", + value: exeList.join(", "), + }); + } + } catch (err) { + // pass + } } }); - pkgList = [pkg]; + if (pkg.name) { + const purlString = new PackageURL( + "gem", + "", + pkg.name, + pkg.version, + null, + null, + ).toString(); + pkg.purl = purlString; + pkg["bom-ref"] = decodeURIComponent(purlString); + } + if (gemspecFile) { + pkg.properties.push({ name: "SrcFile", value: gemspecFile }); + // Did we find the version number from the directory name? Let's reduce the confidence and set the correct technique + pkg.evidence = { + identity: { + field: "purl", + confidence: !pkg.version || versionHackMatch ? 0.2 : 0.5, + methods: [ + { + technique: versionHackMatch ? "filename" : "manifest-analysis", + confidence: !pkg.version || versionHackMatch ? 0.2 : 0.5, + value: gemspecFile, + }, + ], + }, + }; + } + if (pkg.authors) { + pkg.authors = pkg.authors.map((a) => { + return { name: a }; + }); + } + if (pkg.licenses) { + pkg.licenses = pkg.licenses.map((l) => { + return { license: { name: l } }; + }); + } + if (pkg.name) { + pkgList = [pkg]; + } else { + console.log("Unable to parse", gemspecData, gemspecFile); + } if (shouldFetchLicense()) { return await getRubyGemsMetadata(pkgList); } diff --git a/lib/helpers/utils.test.js b/lib/helpers/utils.test.js index cbcf6f6fb..e309d2757 100644 --- a/lib/helpers/utils.test.js +++ b/lib/helpers/utils.test.js @@ -92,6 +92,7 @@ import { parseYarnLock, readZipEntry, splitOutputByGradleProjects, + toGemModuleNames, yarnLockToIdentMap, } from "./utils.js"; @@ -4461,16 +4462,228 @@ test("parseGemfileLockData", async () => { expect(retMap.dependenciesList.length).toEqual(139); }); +test("toGemModuleName", () => { + expect(toGemModuleNames("ruby_parser")).toEqual(["RubyParser"]); + expect(toGemModuleNames("public_suffix")).toEqual(["PublicSuffix"]); + expect(toGemModuleNames("unicode-display_width")).toEqual([ + "Unicode", + "Unicode::DisplayWidth", + ]); + expect(toGemModuleNames("net-http-persistent")).toEqual([ + "Net", + "Net::Http", + "Net::Http::Persistent", + ]); + expect(toGemModuleNames("ruby-prof")).toEqual(["RubyProf"]); + expect(toGemModuleNames("thread_safe")).toEqual(["ThreadSafe"]); + expect(toGemModuleNames("pluck_to_hash")).toEqual(["PluckToHash"]); + expect(toGemModuleNames("sinatra")).toEqual(["Sinatra"]); + expect(toGemModuleNames("passenger")).toEqual(["Passenger"]); + expect(toGemModuleNames("simplecov-html")).toEqual([ + "Simplecov", + "Simplecov::Html", + ]); +}); + test("parseGemspecData", async () => { - const deps = await parseGemspecData( + let deps = await parseGemspecData( readFileSync("./test/data/xmlrpc.gemspec", { encoding: "utf-8" }), + "./test/data/xmlrpc.gemspec", ); expect(deps.length).toEqual(1); expect(deps[0]).toEqual({ + authors: [ + { + name: "SHIBATA Hiroshi", + }, + ], + "bom-ref": "pkg:gem/xmlrpc@0.3.0", + licenses: [ + { + license: { + name: "Ruby", + }, + }, + ], + description: + "XMLRPC is a lightweight protocol that enables remote procedure calls over HTTP.", + evidence: { + identity: { + confidence: 0.5, + field: "purl", + methods: [ + { + confidence: 0.5, + technique: "manifest-analysis", + value: "./test/data/xmlrpc.gemspec", + }, + ], + }, + }, + homepage: "https://github.com/ruby/xmlrpc", name: "xmlrpc", + properties: [ + { + name: "SrcFile", + value: "./test/data/xmlrpc.gemspec", + }, + ], + purl: "pkg:gem/xmlrpc@0.3.0", version: "0.3.0", + }); + deps = await parseGemspecData( + readFileSync("./test/data/loofah-2.3.1.gemspec", { encoding: "utf-8" }), + "./test/data/loofah-2.3.1.gemspec", + ); + expect(deps.length).toEqual(1); + expect(deps[0]).toEqual({ + authors: [ + { + name: "Mike Dalessio", + }, + { + name: "Bryan Helmkamp", + }, + ], + "bom-ref": "pkg:gem/loofah@2.3.1", + licenses: [ + { + license: { + name: "MIT", + }, + }, + ], description: - "XMLRPC is a lightweight protocol that enables remote procedure calls over HTTP.", + "Loofah is a general library for manipulating and transforming HTML/XML documents and fragments, built on top of Nokogiri.\\n\\nLoofah excels at HTML sanitization (XSS prevention). It includes some nice HTML sanitizers, which are based on HTML5lib's safelist, so it most likely won't make your codes less secure. (These statements have not been evaluated by Netexperts.)\\n\\nActiveRecord extensions for sanitization are available in the [`loofah-activerecord` gem](https://github.com/flavorjones/loofah-activerecord).", + evidence: { + identity: { + confidence: 0.5, + field: "purl", + methods: [ + { + confidence: 0.5, + technique: "manifest-analysis", + value: "./test/data/loofah-2.3.1.gemspec", + }, + ], + }, + }, + homepage: "https://github.com/flavorjones/loofah", + name: "loofah", + properties: [ + { + name: "SrcFile", + value: "./test/data/loofah-2.3.1.gemspec", + }, + ], + purl: "pkg:gem/loofah@2.3.1", + version: "2.3.1", + }); + deps = await parseGemspecData( + readFileSync("./test/data/nokogiri-1.10.10.gemspec", { encoding: "utf-8" }), + "./test/data/nokogiri-1.10.10.gemspec", + ); + expect(deps.length).toEqual(1); + expect(deps[0]).toEqual({ + authors: [ + { + name: "Aaron Patterson", + }, + { + name: "Mike Dalessio", + }, + { + name: "Yoko Harada", + }, + { + name: "Tim Elliott", + }, + { + name: "Akinori MUSHA", + }, + { + name: "John Shahid", + }, + { + name: "Lars Kanis", + }, + ], + "bom-ref": "pkg:gem/nokogiri@1.10.10", + licenses: [ + { + license: { + name: "MIT", + }, + }, + ], + description: + "Nokogiri (\\u92F8) is an HTML, XML, SAX, and Reader parser. Among\\nNokogiri's many features is the ability to search documents via XPath\\nor CSS3 selectors.", + evidence: { + identity: { + confidence: 0.5, + field: "purl", + methods: [ + { + confidence: 0.5, + technique: "manifest-analysis", + value: "./test/data/nokogiri-1.10.10.gemspec", + }, + ], + }, + }, + homepage: "https://nokogiri.org", + name: "nokogiri", + properties: [ + { + name: "cdx:gem:executables", + value: "nokogiri", + }, + { + name: "SrcFile", + value: "./test/data/nokogiri-1.10.10.gemspec", + }, + ], + purl: "pkg:gem/nokogiri@1.10.10", + version: "1.10.10", + }); + deps = await parseGemspecData( + readFileSync("./test/data/activerecord-import.gemspec", { + encoding: "utf-8", + }), + "./test/data/activerecord-import.gemspec", + ); + expect(deps.length).toEqual(1); + expect(deps[0]).toEqual({ + authors: [ + { + name: "Zach Dennis", + }, + ], + "bom-ref": "pkg:gem/activerecord-import", + version: undefined, + description: "A library for bulk inserting data using ActiveRecord.", + evidence: { + identity: { + confidence: 0.2, + field: "purl", + methods: [ + { + confidence: 0.2, + technique: "manifest-analysis", + value: "./test/data/activerecord-import.gemspec", + }, + ], + }, + }, + homepage: "https://github.com/zdennis/activerecord-import", + name: "activerecord-import", + properties: [ + { + name: "SrcFile", + value: "./test/data/activerecord-import.gemspec", + }, + ], + purl: "pkg:gem/activerecord-import", }); }); @@ -5732,6 +5945,36 @@ test("hasAnyProjectType tests", () => { false, ), ).toBeFalsy(); + expect( + hasAnyProjectType( + ["ruby"], + { + projectType: ["ruby2.5.4"], + excludeType: undefined, + }, + false, + ), + ).toBeTruthy(); + expect( + hasAnyProjectType( + ["ruby"], + { + projectType: ["rb"], + excludeType: undefined, + }, + false, + ), + ).toBeTruthy(); + expect( + hasAnyProjectType( + ["ruby"], + { + projectType: ["ruby3.4.1", "ruby2.5.4"], + excludeType: undefined, + }, + false, + ), + ).toBeTruthy(); }); test("isPackageManagerAllowed tests", () => { diff --git a/lib/stages/postgen/postgen.js b/lib/stages/postgen/postgen.js index a23c6a1e6..8ecee37cb 100644 --- a/lib/stages/postgen/postgen.js +++ b/lib/stages/postgen/postgen.js @@ -328,7 +328,7 @@ export function filterBom(bomJson, options) { hasAnyProjectType(["python"], options, false) ) { console.log( - "Try running cdxgen with --deep argument to identify component usages with atom.", + "TIP: Try running cdxgen with --deep argument to identify component usages with atom.", ); } else if ( options.requiredOnly && diff --git a/lib/stages/pregen/pregen.js b/lib/stages/pregen/pregen.js index 0f1456898..e59dae9dd 100644 --- a/lib/stages/pregen/pregen.js +++ b/lib/stages/pregen/pregen.js @@ -1,14 +1,19 @@ import { spawnSync } from "node:child_process"; -import { existsSync, mkdtempSync, readdirSync } from "node:fs"; +import { existsSync, mkdtempSync, readFileSync, readdirSync } from "node:fs"; import { arch, platform, tmpdir } from "node:os"; import { delimiter, dirname, join, resolve } from "node:path"; import process from "node:process"; import { SDKMAN_JAVA_TOOL_ALIASES, + bundleInstallWithDocker, getOrInstallNvmTool, + installRubyBundler, + installRubyVersion, installSdkmanTool, isNvmAvailable, + isRbenvAvailable, isSdkmanAvailable, + performBundleInstall, runSwiftCommand, } from "../../helpers/envcontext.js"; import { @@ -16,6 +21,9 @@ import { TIMEOUT_MS, getAllFiles, hasAnyProjectType, + isFeatureEnabled, + isMac, + isWin, } from "../../helpers/utils.js"; /** @@ -41,6 +49,7 @@ export function prepareEnv(filePath, options) { preparePythonEnv(filePath, options); prepareNodeEnv(filePath, options); prepareSwiftEnv(filePath, options); + prepareRubyEnv(filePath, options); } /** @@ -251,79 +260,290 @@ export function doNpmInstall(filePath, nvmNodePath) { * @param {Object} options CLI Options */ export function prepareSwiftEnv(filePath, options) { - if (hasAnyProjectType(["swift"], options, false)) { - if (platform() === "win32") { - console.log( - "Ensure Swift for Windows is installed by following the instructions at https://www.swift.org/install/windows/", - ); + if (!hasAnyProjectType(["swift"], options, false)) { + return; + } + if (platform() === "win32") { + console.log( + "Ensure Swift for Windows is installed by following the instructions at https://www.swift.org/install/windows/", + ); + } + if ( + process.env?.CDXGEN_IN_CONTAINER !== "true" && + platform() === "linux" && + arch() !== "x64" + ) { + console.log( + "INFO: Swift for Linux has known issues on non x64 machines.\nRun the cdxgen container image with --platform=linux/amd64 for best experience.", + ); + } + if (options.deep || options?.lifecycle?.includes("post-build")) { + const swiftFiles = getAllFiles( + filePath, + `${options.multiProject ? "**/" : ""}Package*.swift`, + options, + ); + const pkgResolvedFiles = getAllFiles( + filePath, + `${options.multiProject ? "**/" : ""}Package.resolved`, + options, + ); + const outputFileMaps = getAllFiles( + filePath, + ".build/**/debug/**/output-file-map.json", + options, + ); + const fastlaneFiles = getAllFiles( + filePath, + `${options.multiProject ? "**/" : ""}Fastfile`, + options, + ); + if ( + (!pkgResolvedFiles.length || !outputFileMaps.length) && + swiftFiles.length + ) { + if (fastlaneFiles.length) { + console.log( + "For best results, build the project using the 'bundle exec fastlane' command prior to invoking cdxgen.", + ); + console.log( + "Look for any Makefile or CI workflow files to identify the full command along with the arguments to build this project.\nYou may also need access to keychain and private dependencies used.", + ); + return; + } + for (const f of swiftFiles) { + const basePath = dirname(f); + console.log( + "Attempting to generate the Package.resolved file", + basePath, + ); + const cmdOutput = runSwiftCommand(basePath, [ + "package", + "-v", + "resolve", + ]); + const resolvedFile = join(basePath, "Package.resolved"); + if (!cmdOutput) { + console.log( + "Swift build was not successful. Build this project manually before invoking cdxgen.", + ); + } + if (!existsSync(resolvedFile)) { + console.log( + "Package.resolved file did not get generated successfully. Check the Package.swift file for declared dependencies.\nCheck if any private registry needs to be configured for the build to succeed.", + ); + } + } } + } +} + +/** + * Method to check and prepare the environment for Ruby projects + * + * @param {String} filePath Path + * @param {Object} options CLI Options + */ +export function prepareRubyEnv(filePath, options) { + // Skip preparation early + if ( + !hasAnyProjectType(["ruby"], options, false) || + !options.installDeps || + options?.lifecycle?.includes("pre-build") + ) { + return; + } + const gemFiles = getAllFiles( + filePath, + `${options.multiProject ? "**/" : ""}Gemfile`, + options, + ); + if (!gemFiles.length) { + return; + } + const gemLockFiles = getAllFiles( + filePath, + `${options.multiProject ? "**/" : ""}Gemfile*.lock`, + options, + ); + if (gemLockFiles.length && !options.deep) { + return; + } + let rubyVersionNeeded; + const rbenvPresent = isRbenvAvailable(); + const cdxgenGemHome = + process.env.CDXGEN_GEM_HOME || + process.env.GEM_HOME || + mkdtempSync(join(tmpdir(), "cdxgen-gem-home-")); + process.env.CDXGEN_GEM_HOME = cdxgenGemHome; + // Is there a .ruby-version file in the project? + if (existsSync(join(filePath, ".ruby-version"))) { + rubyVersionNeeded = readFileSync(join(filePath, ".ruby-version"), { + encoding: "utf-8", + }).trim(); + } else if (existsSync(join(filePath, "Gemfile.lock"))) { + // Is there a lock file that can be used to identify the needed Ruby version? + const gemlockData = readFileSync(join(filePath, "Gemfile.lock"), { + encoding: "utf-8", + }); + let rubyVersionMarker = false; + for (let l of gemlockData.split("\n")) { + l = l.replace("\r", "").trim(); + if (l.includes("RUBY VERSION")) { + rubyVersionMarker = true; + } + if (rubyVersionMarker && l.includes("ruby ")) { + const possibleVersion = l + .split("ruby ") + .pop() + .split("p")[0] + .split("d")[0]; + if (/^\d+/.test(possibleVersion)) { + rubyVersionNeeded = possibleVersion; + break; + } + } + } + } else { + // Is the user invoking with a ruby with custom version type. Eg: -t ruby2.5.4 + let projectTypes = options.projectType; if ( - process.env?.CDXGEN_IN_CONTAINER !== "true" && - platform() === "linux" && - arch() !== "x64" + options.projectType && + (typeof options.projectType === "string" || + options.projectType instanceof String) ) { + projectTypes = options.projectType.split(","); + } + for (const apt of projectTypes) { + if (!apt.startsWith("ruby")) { + continue; + } + const possibleVersion = apt.replace("ruby", ""); + if (/^\d+/.test(possibleVersion)) { + rubyVersionNeeded = possibleVersion; + break; + } + } + } + if (!rbenvPresent) { + console.log( + `This project requires Ruby ${rubyVersionNeeded}. cdxgen can automatically install the required version of Ruby with rbenv command.`, + ); + if (process.env?.CDXGEN_IN_CONTAINER !== "true") { console.log( - "INFO: Swift for Linux has known issues on non x64 machines.\nRun the cdxgen container image with --platform=linux/amd64 for best experience.", + "Try using the container image ghcr.io/cyclonedx/cdxgen, which includes the rbenv command along with the dependencies such as ruby-build, rust, etc for successful compilation.", ); + if (isMac) { + console.log( + "Alternatively, install rbenv with homebrew `brew install rbenv`, followed by `rbenv init`", + ); + } } - if (options.deep || options?.lifecycle?.includes("post-build")) { - const swiftFiles = getAllFiles( - filePath, - `${options.multiProject ? "**/" : ""}Package*.swift`, - options, - ); - const pkgResolvedFiles = getAllFiles( - filePath, - `${options.multiProject ? "**/" : ""}Package.resolved`, - options, - ); - const outputFileMaps = getAllFiles( - filePath, - ".build/**/debug/**/output-file-map.json", - options, - ); - const fastlaneFiles = getAllFiles( - filePath, - `${options.multiProject ? "**/" : ""}Fastfile`, - options, - ); - if ( - (!pkgResolvedFiles.length || !outputFileMaps.length) && - swiftFiles.length - ) { - if (fastlaneFiles.length) { - console.log( - "For best results, build the project using the 'bundle exec fastlane' command prior to invoking cdxgen.", - ); + } else if (rubyVersionNeeded) { + // Should we use docker + if (isFeatureEnabled(options, "ruby-docker-install") || isWin) { + for (const agemf of gemFiles) { + bundleInstallWithDocker( + rubyVersionNeeded, + cdxgenGemHome, + dirname(agemf), + ); + } + if (DEBUG_MODE) { + const gemspecFiles = getAllFiles( + cdxgenGemHome, + `${options.multiProject ? "**/" : ""}*.gemspec`, + options, + ); + if (gemspecFiles.length > 3) { console.log( - "Look for any Makefile or CI workflow files to identify the full command along with the arguments to build this project.\nYou may also need access to keychain and private dependencies used.", + `GEM_HOME ${cdxgenGemHome} includes ${gemspecFiles.length} .gemspec files. Bundle install with docker was successful.`, ); - return; } - for (const f of swiftFiles) { - const basePath = dirname(f); - console.log( - "Attempting to generate the Package.resolved file", - basePath, + } + return; + } + if (isMac) { + console.log( + "Installing Ruby with rbenv on macOS could fail for a variety of reasons.", + ); + console.log( + `TIP: Use the custom container image "ghcr.io/cyclonedx/cdxgen-debian-ruby34" with the argument "-t ruby${rubyVersionNeeded}".`, + ); + } + // Try rbenv install + const { fullToolBinDir, status } = installRubyVersion( + rubyVersionNeeded, + filePath, + ); + let bundleTool; + if (status) { + if (fullToolBinDir) { + if (!process.env?.PATH?.includes(`versions/${rubyVersionNeeded}`)) { + process.env.PATH = `${fullToolBinDir}${delimiter}${process.env.PATH}`; + } + process.env.CDXGEN_RUBY_CMD = join(fullToolBinDir, "ruby"); + process.env.CDXGEN_GEM_CMD = join(fullToolBinDir, "gem"); + bundleTool = join(fullToolBinDir, "bundle"); + process.env.CDXGEN_BUNDLE_CMD = bundleTool; + if (!existsSync(bundleTool)) { + const bundlerStatus = installRubyBundler( + rubyVersionNeeded, + undefined, ); - const cmdOutput = runSwiftCommand(basePath, [ - "package", - "-v", - "resolve", - ]); - const resolvedFile = join(basePath, "Package.resolved"); - if (!cmdOutput) { + if (!bundlerStatus && !process.env.CDXGEN_DEBUG_MODE) { console.log( - "Swift build was not successful. Build this project manually before invoking cdxgen.", + "bundler didn't get installed successfully. Set the environment variable CDXGEN_DEBUG_MODE=debug to troubleshoot.", ); } - if (!existsSync(resolvedFile)) { + } + } + // Do we have a proper GEM_HOME already? + if (cdxgenGemHome && existsSync(cdxgenGemHome)) { + const gemspecFiles = getAllFiles( + cdxgenGemHome, + "**/specifications/**/*.gemspec", + options, + ); + if (gemspecFiles.length > 3) { + if (DEBUG_MODE) { console.log( - "Package.resolved file did not get generated successfully. Check the Package.swift file for declared dependencies.\nCheck if any private registry needs to be configured for the build to succeed.", + `GEM_HOME ${cdxgenGemHome} includes ${gemspecFiles.length} .gemspec files. Skipping bundle install.`, ); } + return; + } + } + if (bundleTool && existsSync(bundleTool)) { + if (DEBUG_MODE) { + console.log(`bundle command is now available at ${bundleTool}`); + } + // Invoke bundle install + for (const agemf of gemFiles) { + performBundleInstall( + cdxgenGemHome, + rubyVersionNeeded, + bundleTool, + dirname(agemf), + ); } } + } else { + console.log(`Ruby install has failed for version ${rubyVersionNeeded}.`); + options.deep && options.failOnError && process.exit(1); + } + } else { + // Just attempt bundle install + console.log( + "Attempting bundle install with the default Ruby installation. This is more likely to fail ...", + ); + for (const agemf of gemFiles) { + performBundleInstall( + cdxgenGemHome, + rubyVersionNeeded, + "bundle", + dirname(agemf), + ); } } } diff --git a/test/data/activerecord-import.gemspec b/test/data/activerecord-import.gemspec new file mode 100644 index 000000000..d667e376b --- /dev/null +++ b/test/data/activerecord-import.gemspec @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require File.expand_path('../lib/activerecord-import/version', __FILE__) + +Gem::Specification.new do |gem| + gem.authors = ["Zach Dennis"] + gem.email = ["zach.dennis@gmail.com"] + gem.summary = "Bulk insert extension for ActiveRecord" + gem.description = "A library for bulk inserting data using ActiveRecord." + gem.homepage = "https://github.com/zdennis/activerecord-import" + gem.license = "MIT" + + gem.metadata = { + "changelog_uri" => "https://github.com/zdennis/activerecord-import/blob/master/CHANGELOG.md" + } + + gem.files = `git ls-files`.split($\) + gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.name = "activerecord-import" + gem.require_paths = ["lib"] + gem.version = ActiveRecord::Import::VERSION + + gem.required_ruby_version = ">= 2.4.0" + + gem.add_runtime_dependency "activerecord", ">= 4.2" + gem.add_development_dependency "rake" +end diff --git a/test/data/loofah-2.3.1.gemspec b/test/data/loofah-2.3.1.gemspec new file mode 100644 index 000000000..961c926e3 --- /dev/null +++ b/test/data/loofah-2.3.1.gemspec @@ -0,0 +1,71 @@ +# -*- encoding: utf-8 -*- +# stub: loofah 2.3.1 ruby lib + +Gem::Specification.new do |s| + s.name = "loofah".freeze + s.version = "2.3.1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Mike Dalessio".freeze, "Bryan Helmkamp".freeze] + s.date = "2019-10-22" + s.description = "Loofah is a general library for manipulating and transforming HTML/XML documents and fragments, built on top of Nokogiri.\n\nLoofah excels at HTML sanitization (XSS prevention). It includes some nice HTML sanitizers, which are based on HTML5lib's safelist, so it most likely won't make your codes less secure. (These statements have not been evaluated by Netexperts.)\n\nActiveRecord extensions for sanitization are available in the [`loofah-activerecord` gem](https://github.com/flavorjones/loofah-activerecord).".freeze + s.email = ["mike.dalessio@gmail.com".freeze, "bryan@brynary.com".freeze] + s.extra_rdoc_files = ["CHANGELOG.md".freeze, "MIT-LICENSE.txt".freeze, "Manifest.txt".freeze, "README.md".freeze, "SECURITY.md".freeze] + s.files = ["CHANGELOG.md".freeze, "MIT-LICENSE.txt".freeze, "Manifest.txt".freeze, "README.md".freeze, "SECURITY.md".freeze] + s.homepage = "https://github.com/flavorjones/loofah".freeze + s.licenses = ["MIT".freeze] + s.rdoc_options = ["--main".freeze, "README.md".freeze] + s.rubygems_version = "3.0.3".freeze + s.summary = "Loofah is a general library for manipulating and transforming HTML/XML documents and fragments, built on top of Nokogiri".freeze + + s.installed_by_version = "3.0.3" if s.respond_to? :installed_by_version + + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q.freeze, [">= 1.5.9"]) + s.add_runtime_dependency(%q.freeze, ["~> 1.0.2"]) + s.add_development_dependency(%q.freeze, ["~> 12.3"]) + s.add_development_dependency(%q.freeze, ["~> 2.2"]) + s.add_development_dependency(%q.freeze, ["~> 1.2.0"]) + s.add_development_dependency(%q.freeze, ["~> 2.2.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.0"]) + s.add_development_dependency(%q.freeze, ["~> 2.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.5"]) + s.add_development_dependency(%q.freeze, ["~> 1.6"]) + s.add_development_dependency(%q.freeze, [">= 0.26.0"]) + s.add_development_dependency(%q.freeze, [">= 4.0", "< 7"]) + s.add_development_dependency(%q.freeze, ["~> 3.18"]) + else + s.add_dependency(%q.freeze, [">= 1.5.9"]) + s.add_dependency(%q.freeze, ["~> 1.0.2"]) + s.add_dependency(%q.freeze, ["~> 12.3"]) + s.add_dependency(%q.freeze, ["~> 2.2"]) + s.add_dependency(%q.freeze, ["~> 1.2.0"]) + s.add_dependency(%q.freeze, ["~> 2.2.0"]) + s.add_dependency(%q.freeze, ["~> 1.0"]) + s.add_dependency(%q.freeze, ["~> 2.0"]) + s.add_dependency(%q.freeze, ["~> 1.5"]) + s.add_dependency(%q.freeze, ["~> 1.6"]) + s.add_dependency(%q.freeze, [">= 0.26.0"]) + s.add_dependency(%q.freeze, [">= 4.0", "< 7"]) + s.add_dependency(%q.freeze, ["~> 3.18"]) + end + else + s.add_dependency(%q.freeze, [">= 1.5.9"]) + s.add_dependency(%q.freeze, ["~> 1.0.2"]) + s.add_dependency(%q.freeze, ["~> 12.3"]) + s.add_dependency(%q.freeze, ["~> 2.2"]) + s.add_dependency(%q.freeze, ["~> 1.2.0"]) + s.add_dependency(%q.freeze, ["~> 2.2.0"]) + s.add_dependency(%q.freeze, ["~> 1.0"]) + s.add_dependency(%q.freeze, ["~> 2.0"]) + s.add_dependency(%q.freeze, ["~> 1.5"]) + s.add_dependency(%q.freeze, ["~> 1.6"]) + s.add_dependency(%q.freeze, [">= 0.26.0"]) + s.add_dependency(%q.freeze, [">= 4.0", "< 7"]) + s.add_dependency(%q.freeze, ["~> 3.18"]) + end +end diff --git a/test/data/nokogiri-1.10.10.gemspec b/test/data/nokogiri-1.10.10.gemspec new file mode 100644 index 000000000..752e85047 --- /dev/null +++ b/test/data/nokogiri-1.10.10.gemspec @@ -0,0 +1,85 @@ +# -*- encoding: utf-8 -*- +# stub: nokogiri 1.10.10 ruby lib +# stub: ext/nokogiri/extconf.rb + +Gem::Specification.new do |s| + s.name = "nokogiri".freeze + s.version = "1.10.10" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "bug_tracker_uri" => "https://github.com/sparklemotion/nokogiri/issues", "changelog_uri" => "https://nokogiri.org/CHANGELOG.html", "documentation_uri" => "https://nokogiri.org/rdoc/index.html", "homepage_uri" => "https://nokogiri.org", "source_code_uri" => "https://github.com/sparklemotion/nokogiri" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["Aaron Patterson".freeze, "Mike Dalessio".freeze, "Yoko Harada".freeze, "Tim Elliott".freeze, "Akinori MUSHA".freeze, "John Shahid".freeze, "Lars Kanis".freeze] + s.date = "2020-07-06" + s.description = "Nokogiri (\u92F8) is an HTML, XML, SAX, and Reader parser. Among\nNokogiri's many features is the ability to search documents via XPath\nor CSS3 selectors.".freeze + s.email = ["aaronp@rubyforge.org".freeze, "mike.dalessio@gmail.com".freeze, "yokolet@gmail.com".freeze, "tle@holymonkey.com".freeze, "knu@idaemons.org".freeze, "jvshahid@gmail.com".freeze, "lars@greiz-reinsdorf.de".freeze] + s.executables = ["nokogiri".freeze] + s.extensions = ["ext/nokogiri/extconf.rb".freeze] + s.extra_rdoc_files = ["LICENSE-DEPENDENCIES.md".freeze, "LICENSE.md".freeze, "README.md".freeze, "ext/nokogiri/html_document.c".freeze, "ext/nokogiri/html_element_description.c".freeze, "ext/nokogiri/html_entity_lookup.c".freeze, "ext/nokogiri/html_sax_parser_context.c".freeze, "ext/nokogiri/html_sax_push_parser.c".freeze, "ext/nokogiri/nokogiri.c".freeze, "ext/nokogiri/xml_attr.c".freeze, "ext/nokogiri/xml_attribute_decl.c".freeze, "ext/nokogiri/xml_cdata.c".freeze, "ext/nokogiri/xml_comment.c".freeze, "ext/nokogiri/xml_document.c".freeze, "ext/nokogiri/xml_document_fragment.c".freeze, "ext/nokogiri/xml_dtd.c".freeze, "ext/nokogiri/xml_element_content.c".freeze, "ext/nokogiri/xml_element_decl.c".freeze, "ext/nokogiri/xml_encoding_handler.c".freeze, "ext/nokogiri/xml_entity_decl.c".freeze, "ext/nokogiri/xml_entity_reference.c".freeze, "ext/nokogiri/xml_io.c".freeze, "ext/nokogiri/xml_libxml2_hacks.c".freeze, "ext/nokogiri/xml_namespace.c".freeze, "ext/nokogiri/xml_node.c".freeze, "ext/nokogiri/xml_node_set.c".freeze, "ext/nokogiri/xml_processing_instruction.c".freeze, "ext/nokogiri/xml_reader.c".freeze, "ext/nokogiri/xml_relax_ng.c".freeze, "ext/nokogiri/xml_sax_parser.c".freeze, "ext/nokogiri/xml_sax_parser_context.c".freeze, "ext/nokogiri/xml_sax_push_parser.c".freeze, "ext/nokogiri/xml_schema.c".freeze, "ext/nokogiri/xml_syntax_error.c".freeze, "ext/nokogiri/xml_text.c".freeze, "ext/nokogiri/xml_xpath_context.c".freeze, "ext/nokogiri/xslt_stylesheet.c".freeze] + s.files = ["LICENSE-DEPENDENCIES.md".freeze, "LICENSE.md".freeze, "README.md".freeze, "bin/nokogiri".freeze, "ext/nokogiri/extconf.rb".freeze, "ext/nokogiri/html_document.c".freeze, "ext/nokogiri/html_element_description.c".freeze, "ext/nokogiri/html_entity_lookup.c".freeze, "ext/nokogiri/html_sax_parser_context.c".freeze, "ext/nokogiri/html_sax_push_parser.c".freeze, "ext/nokogiri/nokogiri.c".freeze, "ext/nokogiri/xml_attr.c".freeze, "ext/nokogiri/xml_attribute_decl.c".freeze, "ext/nokogiri/xml_cdata.c".freeze, "ext/nokogiri/xml_comment.c".freeze, "ext/nokogiri/xml_document.c".freeze, "ext/nokogiri/xml_document_fragment.c".freeze, "ext/nokogiri/xml_dtd.c".freeze, "ext/nokogiri/xml_element_content.c".freeze, "ext/nokogiri/xml_element_decl.c".freeze, "ext/nokogiri/xml_encoding_handler.c".freeze, "ext/nokogiri/xml_entity_decl.c".freeze, "ext/nokogiri/xml_entity_reference.c".freeze, "ext/nokogiri/xml_io.c".freeze, "ext/nokogiri/xml_libxml2_hacks.c".freeze, "ext/nokogiri/xml_namespace.c".freeze, "ext/nokogiri/xml_node.c".freeze, "ext/nokogiri/xml_node_set.c".freeze, "ext/nokogiri/xml_processing_instruction.c".freeze, "ext/nokogiri/xml_reader.c".freeze, "ext/nokogiri/xml_relax_ng.c".freeze, "ext/nokogiri/xml_sax_parser.c".freeze, "ext/nokogiri/xml_sax_parser_context.c".freeze, "ext/nokogiri/xml_sax_push_parser.c".freeze, "ext/nokogiri/xml_schema.c".freeze, "ext/nokogiri/xml_syntax_error.c".freeze, "ext/nokogiri/xml_text.c".freeze, "ext/nokogiri/xml_xpath_context.c".freeze, "ext/nokogiri/xslt_stylesheet.c".freeze] + s.homepage = "https://nokogiri.org".freeze + s.licenses = ["MIT".freeze] + s.rdoc_options = ["--main".freeze, "README.md".freeze] + s.required_ruby_version = Gem::Requirement.new(">= 2.3.0".freeze) + s.rubygems_version = "3.0.3".freeze + s.summary = "Nokogiri (\u92F8) is an HTML, XML, SAX, and Reader parser".freeze + + s.installed_by_version = "3.0.3" if s.respond_to? :installed_by_version + + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q.freeze, ["~> 2.4.0"]) + s.add_development_dependency(%q.freeze, ["~> 0.24"]) + s.add_development_dependency(%q.freeze, ["~> 1.2"]) + s.add_development_dependency(%q.freeze, ["~> 2.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.6"]) + s.add_development_dependency(%q.freeze, ["~> 5.8"]) + s.add_development_dependency(%q.freeze, ["~> 1.4.14"]) + s.add_development_dependency(%q.freeze, ["~> 12.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.1.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.0.5"]) + s.add_development_dependency(%q.freeze, ["~> 0.73"]) + s.add_development_dependency(%q.freeze, ["~> 0.16"]) + s.add_development_dependency(%q.freeze, [">= 4.0", "< 7"]) + s.add_development_dependency(%q.freeze, ["~> 3.22"]) + else + s.add_dependency(%q.freeze, ["~> 2.4.0"]) + s.add_dependency(%q.freeze, ["~> 0.24"]) + s.add_dependency(%q.freeze, ["~> 1.2"]) + s.add_dependency(%q.freeze, ["~> 2.0"]) + s.add_dependency(%q.freeze, ["~> 1.0"]) + s.add_dependency(%q.freeze, ["~> 1.6"]) + s.add_dependency(%q.freeze, ["~> 5.8"]) + s.add_dependency(%q.freeze, ["~> 1.4.14"]) + s.add_dependency(%q.freeze, ["~> 12.0"]) + s.add_dependency(%q.freeze, ["~> 1.1.0"]) + s.add_dependency(%q.freeze, ["~> 1.0"]) + s.add_dependency(%q.freeze, ["~> 1.0.5"]) + s.add_dependency(%q.freeze, ["~> 0.73"]) + s.add_dependency(%q.freeze, ["~> 0.16"]) + s.add_dependency(%q.freeze, [">= 4.0", "< 7"]) + s.add_dependency(%q.freeze, ["~> 3.22"]) + end + else + s.add_dependency(%q.freeze, ["~> 2.4.0"]) + s.add_dependency(%q.freeze, ["~> 0.24"]) + s.add_dependency(%q.freeze, ["~> 1.2"]) + s.add_dependency(%q.freeze, ["~> 2.0"]) + s.add_dependency(%q.freeze, ["~> 1.0"]) + s.add_dependency(%q.freeze, ["~> 1.6"]) + s.add_dependency(%q.freeze, ["~> 5.8"]) + s.add_dependency(%q.freeze, ["~> 1.4.14"]) + s.add_dependency(%q.freeze, ["~> 12.0"]) + s.add_dependency(%q.freeze, ["~> 1.1.0"]) + s.add_dependency(%q.freeze, ["~> 1.0"]) + s.add_dependency(%q.freeze, ["~> 1.0.5"]) + s.add_dependency(%q.freeze, ["~> 0.73"]) + s.add_dependency(%q.freeze, ["~> 0.16"]) + s.add_dependency(%q.freeze, [">= 4.0", "< 7"]) + s.add_dependency(%q.freeze, ["~> 3.22"]) + end +end diff --git a/types/lib/cli/index.d.ts.map b/types/lib/cli/index.d.ts.map index ae7e5ef8b..b3fe2e839 100644 --- a/types/lib/cli/index.d.ts.map +++ b/types/lib/cli/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/cli/index.js"],"names":[],"mappings":"AA0xBA;;;;;;;;GAQG;AACH,gFAFW,MAAM,SAchB;AAuXD;;;;;;;GAOG;AACH,mCALW,MAAM,qBAiEhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;EAKhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM;;;;EAkBhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAs7BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BAukBhB;AAED;;;;;;;;;;GAUG;AACH,+DAsEC;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA+dhB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BA+YhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAqIhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAiDhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBA+KhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBAsHhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,0CAHW,MAAM,qBAuBhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,8BAqDhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,8BA4ChB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM,8BA6FhB;AAED;;;;;GAKG;AACH,iDAHW,MAAM,qBAiUhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBAiJhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAmFhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA4XhB;AAED;;;;;GAKG;AACH,2CAHW,MAAM;;;;;;;;;;;;;;;;;;;;GAoChB;AAED;;;;;;;;KA+DC;AAED;;;;;;GAMG;AACH,yDAqFC;AAED;;;;;;;;;GASG;AACH,2GA6BC;AAED;;;;;GAKG;AACH,0CAHW,MAAM,EAAE,8BAqdlB;AAED;;;;;GAKG;AACH,iCAHW,MAAM,8BAgUhB;AAED;;;;;GAKG;AACH,gCAHW,MAAM,qBAqOhB;AAED;;;;;;GAMG;AACH,wDAFY,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CAwHxE"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/cli/index.js"],"names":[],"mappings":"AA4xBA;;;;;;;;GAQG;AACH,gFAFW,MAAM,SAchB;AAuXD;;;;;;;GAOG;AACH,mCALW,MAAM,qBAiEhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;EAKhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM;;;;EAkBhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAs7BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BAukBhB;AAED;;;;;;;;;;GAUG;AACH,+DAsEC;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA+dhB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BA+YhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAqIhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAiDhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBA+KhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBAsHhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,0CAHW,MAAM,qBAuBhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,8BAqDhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,8BA4ChB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM,8BA6FhB;AAED;;;;;GAKG;AACH,iDAHW,MAAM,qBAiUhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBAiJhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BA6KhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA4XhB;AAED;;;;;GAKG;AACH,2CAHW,MAAM;;;;;;;;;;;;;;;;;;;;GAoChB;AAED;;;;;;;;KA+DC;AAED;;;;;;GAMG;AACH,yDAqFC;AAED;;;;;;;;;GASG;AACH,2GA6BC;AAED;;;;;GAKG;AACH,0CAHW,MAAM,EAAE,8BAqdlB;AAED;;;;;GAKG;AACH,iCAHW,MAAM,8BAgUhB;AAED;;;;;GAKG;AACH,gCAHW,MAAM,qBAiPhB;AAED;;;;;;GAMG;AACH,wDAFY,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CAwHxE"} \ No newline at end of file diff --git a/types/lib/helpers/envcontext.d.ts b/types/lib/helpers/envcontext.d.ts index ff5fb4db6..0aa98f346 100644 --- a/types/lib/helpers/envcontext.d.ts +++ b/types/lib/helpers/envcontext.d.ts @@ -142,6 +142,17 @@ export function collectSwiftInfo(dir: string): { name: string; version: any; }; +/** + * Collect Ruby version + * + * @param {string} dir Working directory + * @returns Object containing Ruby details + */ +export function collectRubyInfo(dir: string): { + type: string; + name: string; + version: any; +}; /** * Method to run a swift command * @@ -202,6 +213,49 @@ export function getNvmToolDirectory(toolName: string): string; * @returns {String} path of the tool if not found installs and then returns paths. false if encounters an error. */ export function getOrInstallNvmTool(toolVersion: string): string; +/** + * Method to check if rbenv is available. + * + * @returns {Boolean} true if rbenv is available. false otherwise. + */ +export function isRbenvAvailable(): boolean; +export function rubyVersionDir(rubyVersion: any): string; +/** + * Perform bundle install using Ruby container images. Not working cleanly yet. + * + * @param rubyVersion Ruby version + * @param cdxgenGemHome Gem Home + * @param filePath Path + */ +export function bundleInstallWithDocker(rubyVersion: any, cdxgenGemHome: any, filePath: any): boolean; +/** + * Install a particular ruby version using rbenv. + * + * @param rubyVersion Ruby version to install + * @param filePath File path + */ +export function installRubyVersion(rubyVersion: any, filePath: any): { + fullToolBinDir: string; + status: boolean; +}; +/** + * Method to install bundler using gem. + * + * @param rubyVersion Ruby version + * @param bundlerVersion Bundler version + */ +export function installRubyBundler(rubyVersion: any, bundlerVersion: any): boolean; +/** + * Method to perform bundle install + * + * @param cdxgenGemHome cdxgen Gem home + * @param rubyVersion Ruby version + * @param bundleCommand Bundle command to use + * @param basePath working directory + * + * @returns {boolean} true if the install was successful. false otherwise. + */ +export function performBundleInstall(cdxgenGemHome: any, rubyVersion: any, bundleCommand: any, basePath: any): boolean; export const GIT_COMMAND: any; export namespace SDKMAN_JAVA_TOOL_ALIASES { let java8: any; diff --git a/types/lib/helpers/envcontext.d.ts.map b/types/lib/helpers/envcontext.d.ts.map index 25f241717..87539f0fc 100644 --- a/types/lib/helpers/envcontext.d.ts.map +++ b/types/lib/helpers/envcontext.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"envcontext.d.ts","sourceRoot":"","sources":["../../../lib/helpers/envcontext.js"],"names":[],"mappings":"AAmCA;;;;;;GAMG;AACH,wCALW,MAAM,OACN,MAAM,OAMhB;AAED;;;;;GAKG;AACH,kCAJW,MAAM,OAMhB;AAED;;;;;;GAMG;AACH,gDAJW,MAAM,OAMhB;AAED;;;;;GAKG;AACH,mCAJW,MAAM,MAsBhB;AAED;;;;;GAKG;AACH,+BAJW,MAAM,SAgChB;AAED;;;;;;;GAOG;AACH,oCALW,MAAM,oBAOhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM;;;;;;;;;EAsBhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;;EAgBhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;;EAgBhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM;;;;;EAkBhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM;;;;;EAehB;AAED;;;;;GAKG;AACH,qCAHW,MAAM;;;;;EAehB;AAED;;;;;GAKG;AACH,mCAHW,MAAM;;;;EAahB;AAED;;;;;GAKG;AACH,sCAHW,MAAM;;;;EAahB;AAED;;;;;;GAMG;AACH,+DAEC;AAED;;;;;;;;;IA+BC;AAwCD;;GAEG;AACH,6CAeC;AAED;;GAEG;AACH,0CAUC;AAED;;;;;;;GAOG;AACH,mFAqBC;AAED;;;;;;;GAOG;AACH,+EAyFC;AAED;;;;;;GAMG;AACH,8DAuBC;AAED;;;;;;GAMG;AACH,iEAmCC;AA/lBD,8BAAwD"} \ No newline at end of file +{"version":3,"file":"envcontext.d.ts","sourceRoot":"","sources":["../../../lib/helpers/envcontext.js"],"names":[],"mappings":"AAsCA;;;;;;GAMG;AACH,wCALW,MAAM,OACN,MAAM,OAMhB;AAED;;;;;GAKG;AACH,kCAJW,MAAM,OAMhB;AAED;;;;;;GAMG;AACH,gDAJW,MAAM,OAMhB;AAED;;;;;GAKG;AACH,mCAJW,MAAM,MAsBhB;AAED;;;;;GAKG;AACH,+BAJW,MAAM,SAgChB;AAED;;;;;;;GAOG;AACH,oCALW,MAAM,oBAOhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM;;;;;;;;;EAsBhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;;EAgBhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;;EAgBhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM;;;;;EAkBhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM;;;;;EAehB;AAED;;;;;GAKG;AACH,qCAHW,MAAM;;;;;EAehB;AAED;;;;;GAKG;AACH,mCAHW,MAAM;;;;EAahB;AAED;;;;;GAKG;AACH,sCAHW,MAAM;;;;EAahB;AAED;;;;;GAKG;AACH,qCAHW,MAAM;;;;EAahB;AAED;;;;;;GAMG;AACH,+DAEC;AAED;;;;;;;;;IAmCC;AAwCD;;GAEG;AACH,6CAeC;AAED;;GAEG;AACH,0CAUC;AAED;;;;;;;GAOG;AACH,mFAqBC;AAED;;;;;;;GAOG;AACH,+EAyFC;AAED;;;;;;GAMG;AACH,8DAuBC;AAED;;;;;;GAMG;AACH,iEAmCC;AASD;;;;GAIG;AACH,4CAiBC;AAED,yDAIC;AAED;;;;;;GAMG;AACH,sGAsCC;AAED;;;;;GAKG;AACH;;;EA+DC;AAED;;;;;GAKG;AACH,mFA6DC;AAED;;;;;;;;;GASG;AACH,+GAFa,OAAO,CA+HnB;AA99BD,8BAAwD"} \ No newline at end of file diff --git a/types/lib/helpers/utils.d.ts b/types/lib/helpers/utils.d.ts index 0ce9d7ba0..f9b6c6412 100644 --- a/types/lib/helpers/utils.d.ts +++ b/types/lib/helpers/utils.d.ts @@ -595,11 +595,30 @@ export function parseGoVersionData(buildInfoData: any): Promise; */ export function getRubyGemsMetadata(pkgList: any[]): Promise; /** - * Method to parse Gemspec + * Utility method to convert a gem package name to a CamelCased module name. Low accuracy. + * + * @param name Package name + */ +export function toGemModuleNames(name: any): string[]; +/** + * Collect all namespaces for a given gem present at the given gemHome + * + * @param {String} rubyCommand Ruby command to use if bundle is not available + * @param {String} bundleCommand Bundle command to use + * @param {String} gemHome Value to use as GEM_HOME env variable + * @param {String} gemName Name of the gem + * @param {String} filePath File path + * + * @returns {Array} List of module names + */ +export function collectGemModuleNames(rubyCommand: string, bundleCommand: string, gemHome: string, gemName: string, filePath: string): Array; +/** + * Method to parse Gemspec file contents * * @param {string} gemspecData Gemspec data + * @param {string} gemspecFile File name for evidence. */ -export function parseGemspecData(gemspecData: string): Promise; +export function parseGemspecData(gemspecData: string, gemspecFile: string): Promise; /** * Method to parse Gemfile.lock * @@ -1350,6 +1369,7 @@ export let CARGO_CMD: string; export let CLJ_CMD: string; export let LEIN_CMD: string; export const SWIFT_CMD: "xcrun swift" | "swift"; +export const RUBY_CMD: any; export const PYTHON_EXCLUDED_COMPONENTS: string[]; export const PROJECT_TYPE_ALIASES: { java: string[]; diff --git a/types/lib/helpers/utils.d.ts.map b/types/lib/helpers/utils.d.ts.map index 1bce8a807..21f28d36d 100644 --- a/types/lib/helpers/utils.d.ts.map +++ b/types/lib/helpers/utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/helpers/utils.js"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/helpers/utils.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/types/lib/stages/pregen/pregen.d.ts b/types/lib/stages/pregen/pregen.d.ts index 6e64d4692..7b5c04813 100644 --- a/types/lib/stages/pregen/pregen.d.ts +++ b/types/lib/stages/pregen/pregen.d.ts @@ -49,4 +49,11 @@ export function doNpmInstall(filePath: string, nvmNodePath: string): void; * @param {Object} options CLI Options */ export function prepareSwiftEnv(filePath: string, options: any): void; +/** + * Method to check and prepare the environment for Ruby projects + * + * @param {String} filePath Path + * @param {Object} options CLI Options + */ +export function prepareRubyEnv(filePath: string, options: any): void; //# sourceMappingURL=pregen.d.ts.map \ No newline at end of file diff --git a/types/lib/stages/pregen/pregen.d.ts.map b/types/lib/stages/pregen/pregen.d.ts.map index 441b2b423..47e3c9c00 100644 --- a/types/lib/stages/pregen/pregen.d.ts.map +++ b/types/lib/stages/pregen/pregen.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"pregen.d.ts","sourceRoot":"","sources":["../../../../lib/stages/pregen/pregen.js"],"names":[],"mappings":"AAoBA;;;;;GAKG;AACH,iEAiBC;AAED;;;;GAIG;AACH,iEASC;AAED;;;;;GAKG;AACH,wEAqCC;AAED;;;;;GAKG;AACH,qEAyDC;AAED;;;;;;;;GAQG;AACH,uEAmBC;AAED;;;;;GAKG;AACH,0EAqCC;AAED;;;;;GAKG;AACH,sEA4EC"} \ No newline at end of file +{"version":3,"file":"pregen.d.ts","sourceRoot":"","sources":["../../../../lib/stages/pregen/pregen.js"],"names":[],"mappings":"AA4BA;;;;;GAKG;AACH,iEAkBC;AAED;;;;GAIG;AACH,iEASC;AAED;;;;;GAKG;AACH,wEAqCC;AAED;;;;;GAKG;AACH,qEAyDC;AAED;;;;;;;;GAQG;AACH,uEAmBC;AAED;;;;;GAKG;AACH,0EAqCC;AAED;;;;;GAKG;AACH,sEA6EC;AAED;;;;;GAKG;AACH,qEA0MC"} \ No newline at end of file